출장등록 진행중 -> 화면 등록 완료
리스트 진행
This commit is contained in:
parent
b4b54de6d2
commit
e572834961
@ -37,6 +37,11 @@ public class RestResponse {
|
|||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
@Builder
|
||||||
|
public RestResponse(HttpStatus status, String msg) {
|
||||||
|
this.status = status;
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ public class ItnCommuteVO implements Serializable {
|
|||||||
private Integer commuteGroupId; // 그룹 아이디
|
private Integer commuteGroupId; // 그룹 아이디
|
||||||
private String uniqId;
|
private String uniqId;
|
||||||
private String userName; // 이름
|
private String userName; // 이름
|
||||||
private String userRank; // 직위
|
private String rankCd; // 직위
|
||||||
private String category; // 구분
|
private String category; // 구분
|
||||||
private String workDt; // 근무일자
|
private String workDt; // 근무일자
|
||||||
private String startTime; // 출근시간
|
private String startTime; // 출근시간
|
||||||
|
|||||||
@ -109,7 +109,7 @@ public class CommuteServiceImpl implements CommuteService {
|
|||||||
|
|
||||||
if( matchedUser != null ){
|
if( matchedUser != null ){
|
||||||
t.setUsrid(matchedUser.getUserName());
|
t.setUsrid(matchedUser.getUserName());
|
||||||
t.setPstn(matchedUser.getUserRank());
|
t.setPstn(matchedUser.getRankCd());
|
||||||
t.setUniqId(matchedUser.getUniqId());
|
t.setUniqId(matchedUser.getUniqId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.itn.admin.itn.bizTrip.mapper;
|
||||||
|
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripApprovalVO;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripMemberVO;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripVO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface BizTripMapper {
|
||||||
|
void insertBizTrip(BizTripVO trip);
|
||||||
|
|
||||||
|
void insertTripMember(BizTripMemberVO member);
|
||||||
|
|
||||||
|
void insertApprovalLine(BizTripApprovalVO approval);
|
||||||
|
|
||||||
|
List<BizTripVO> selectTripList();
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.itn.admin.itn.bizTrip.mapper.domain;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.vo.CmnVO;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class BizTripApprovalVO extends CmnVO {
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
private Integer tripId; // 출장 ID (FK)
|
||||||
|
private String approverId; // 결재자 uniq_id
|
||||||
|
private Integer orderNo; // 결재 순서
|
||||||
|
private String approveStatus; // 결재 상태 (WAIT, APPROVED, REJECTED)
|
||||||
|
private LocalDateTime approveDt; // 결재 일시
|
||||||
|
private String comment; // 결재 의견
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.itn.admin.itn.bizTrip.mapper.domain;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.vo.CmnVO;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class BizTripMemberVO extends CmnVO {
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
private Integer tripId; // 출장 ID (FK)
|
||||||
|
private String uniqId; // 유저 고유 ID (FK)
|
||||||
|
private String role; // 역할 (기안자: 0, 동행자: 1 등)
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.itn.admin.itn.bizTrip.mapper.domain;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class BizTripRequestDTO {
|
||||||
|
private BizTripVO tripInfo;
|
||||||
|
private List<BizTripMemberVO> tripMembers;
|
||||||
|
private List<BizTripApprovalVO> approvalLines;
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package com.itn.admin.itn.bizTrip.mapper.domain;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.vo.CmnVO;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class BizTripVO extends CmnVO {
|
||||||
|
|
||||||
|
private Integer tripId; // 출장 고유 ID
|
||||||
|
private String tripTypeCd; // 출장 구분 (TRIP_TYPE 공통코드)
|
||||||
|
private String locationCd; // 출장지 (TRIP_LOCATION 공통코드)
|
||||||
|
private String locationTxt; // 출장지 (TRIP_LOCATION 공통코드)
|
||||||
|
private String purpose; // 출장 목적
|
||||||
|
private String moveCd; // 이동 수단 (TRIP_MOVE 공통코드)
|
||||||
|
private LocalDate tripDt; // 출장일자
|
||||||
|
private LocalTime startTime; // 출장 시작시간
|
||||||
|
private LocalTime endTime; // 출장 종료시간
|
||||||
|
private String status; // 결재 상태 (ING, DONE 등)
|
||||||
|
|
||||||
|
|
||||||
|
private String latestApproveStatus; // 최신 결재 상태
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.itn.admin.itn.bizTrip.service;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.msg.RestResponse;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripRequestDTO;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface BizTripService {
|
||||||
|
RestResponse register(BizTripRequestDTO dto);
|
||||||
|
|
||||||
|
List<BizTripVO> selectTripList();
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package com.itn.admin.itn.bizTrip.service.impl;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.msg.RestResponse;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.BizTripMapper;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripApprovalVO;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripMemberVO;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripRequestDTO;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripVO;
|
||||||
|
import com.itn.admin.itn.bizTrip.service.BizTripService;
|
||||||
|
import com.itn.admin.itn.code.mapper.CodeMapper;
|
||||||
|
import com.itn.admin.itn.code.mapper.domain.CodeVO;
|
||||||
|
import com.itn.admin.itn.code.server.CodeService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class BizTripServiceImpl implements BizTripService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BizTripMapper bizTripMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse register(BizTripRequestDTO dto) {
|
||||||
|
// 1. BizTripVO insert (자동 생성된 tripId 얻기)
|
||||||
|
BizTripVO trip = dto.getTripInfo();
|
||||||
|
bizTripMapper.insertBizTrip(trip); // insert 후 trip.tripId에 PK 자동 세팅됨
|
||||||
|
|
||||||
|
Integer tripId = trip.getTripId();
|
||||||
|
|
||||||
|
// 2. 출장 참여 인원 등록
|
||||||
|
List<BizTripMemberVO> memberList = dto.getTripMembers();
|
||||||
|
if (memberList != null && !memberList.isEmpty()) {
|
||||||
|
for (BizTripMemberVO member : memberList) {
|
||||||
|
member.setTripId(tripId);
|
||||||
|
bizTripMapper.insertTripMember(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 결재 라인 등록
|
||||||
|
List<BizTripApprovalVO> approvalList = dto.getApprovalLines();
|
||||||
|
if (approvalList != null && !approvalList.isEmpty()) {
|
||||||
|
for (BizTripApprovalVO approval : approvalList) {
|
||||||
|
approval.setTripId(tripId);
|
||||||
|
bizTripMapper.insertApprovalLine(approval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new RestResponse(HttpStatus.OK, "등록되었습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BizTripVO> selectTripList() {
|
||||||
|
return bizTripMapper.selectTripList();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,42 +1,42 @@
|
|||||||
package com.itn.admin.itn.trip.web;
|
package com.itn.admin.itn.bizTrip.web;
|
||||||
|
|
||||||
import com.itn.admin.cmn.config.CustomUserDetails;
|
import com.itn.admin.cmn.config.CustomUserDetails;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripVO;
|
||||||
|
import com.itn.admin.itn.bizTrip.service.BizTripService;
|
||||||
import com.itn.admin.itn.user.mapper.domain.UserVO;
|
import com.itn.admin.itn.user.mapper.domain.UserVO;
|
||||||
import com.itn.admin.itn.user.service.UserService;
|
import com.itn.admin.itn.user.service.UserService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Controller
|
@Controller
|
||||||
public class TripController {
|
public class BizTripController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserService userService;
|
private BizTripService bizTripService;
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/itn/trip/reg")
|
@GetMapping("/itn/bizTrip/reg")
|
||||||
public String list(@ModelAttribute("userVO") UserVO userVO
|
public String list(@AuthenticationPrincipal CustomUserDetails loginUser
|
||||||
,@AuthenticationPrincipal CustomUserDetails loginUser
|
|
||||||
,Model model
|
,Model model
|
||||||
) {
|
) {
|
||||||
log.info(" + loginUser :: [{}]", loginUser.getUser());
|
log.info(" + loginUser :: [{}]", loginUser.getUser());
|
||||||
|
|
||||||
/*
|
|
||||||
Map<String, Object> resultMap = userService.getList(userVO);
|
|
||||||
|
|
||||||
model.addAttribute("list", resultMap.get("resultList"));
|
|
||||||
*/
|
|
||||||
model.addAttribute("loginUser", loginUser.getUser());
|
model.addAttribute("loginUser", loginUser.getUser());
|
||||||
|
|
||||||
return "itn/trip/reg";
|
return "itn/bizTrip/reg";
|
||||||
|
}
|
||||||
|
@GetMapping("/itn/bizTrip/list")
|
||||||
|
public String bizTripList(Model model) {
|
||||||
|
List<BizTripVO> list = bizTripService.selectTripList();
|
||||||
|
model.addAttribute("list", list);
|
||||||
|
return "itn/bizTrip/list"; // Thymeleaf HTML 파일 경로
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.itn.admin.itn.bizTrip.web;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.config.CustomUserDetails;
|
||||||
|
import com.itn.admin.cmn.msg.RestResponse;
|
||||||
|
import com.itn.admin.itn.bizTrip.mapper.domain.BizTripRequestDTO;
|
||||||
|
import com.itn.admin.itn.bizTrip.service.BizTripService;
|
||||||
|
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||||
|
import com.itn.admin.itn.user.mapper.domain.UserVO;
|
||||||
|
import com.itn.admin.itn.user.service.UserService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
public class BizTripRestController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BizTripService bizTripService;
|
||||||
|
|
||||||
|
@PostMapping("/api/bizTrip/register")
|
||||||
|
public ResponseEntity<RestResponse> registerBizTrip(@RequestBody BizTripRequestDTO dto
|
||||||
|
, @AuthenticationPrincipal CustomUserDetails loginUser) {
|
||||||
|
dto.getTripInfo().setFrstRegisterId(loginUser.getUser().getUniqId());
|
||||||
|
log.info("dto: [{}]", dto);
|
||||||
|
// bizTripService.register(dto);
|
||||||
|
return ResponseEntity.ok().body(bizTripService.register(dto));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -41,6 +41,10 @@ public interface UserMapper {
|
|||||||
|
|
||||||
void changepassword(UserVO userVO);
|
void changepassword(UserVO userVO);
|
||||||
|
|
||||||
|
List<UserVO> selectUsersByNameAndRank(String userName);
|
||||||
|
|
||||||
|
|
||||||
@Select("SELECT * FROM users WHERE user_name LIKE CONCAT('%', #{userName}, '%')")
|
@Select("SELECT * FROM users WHERE user_name LIKE CONCAT('%', #{userName}, '%')")
|
||||||
List<UserVO> findByUniqUserName(String userName);
|
List<UserVO> findByUniqUserName(String userName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ public class UserVO extends CmnVO {
|
|||||||
private String userId;
|
private String userId;
|
||||||
private String password;
|
private String password;
|
||||||
private String userName;
|
private String userName;
|
||||||
private String userRank;
|
private String rankCd;
|
||||||
private String mobilePhone;
|
private String mobilePhone;
|
||||||
private String gwId;
|
private String gwId;
|
||||||
private String biostarId;
|
private String biostarId;
|
||||||
|
|||||||
@ -26,4 +26,5 @@ public interface UserService {
|
|||||||
RestResponse changepassword(UserVO userVO);
|
RestResponse changepassword(UserVO userVO);
|
||||||
|
|
||||||
RestResponse findByUniqUserName(String userName);
|
RestResponse findByUniqUserName(String userName);
|
||||||
|
RestResponse findByUniqApprovalUser(String userName);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,6 +107,27 @@ public class UserServiceImpl implements UserService {
|
|||||||
users.forEach(user -> {
|
users.forEach(user -> {
|
||||||
String deptNm = tCodeUtils.getCodeName("DEPT", user.getDeptCd());
|
String deptNm = tCodeUtils.getCodeName("DEPT", user.getDeptCd());
|
||||||
user.setDeptNm(deptNm); // UserVO에 deptCdName 필드 있어야 함
|
user.setDeptNm(deptNm); // UserVO에 deptCdName 필드 있어야 함
|
||||||
|
String rankNm = tCodeUtils.getCodeName("RANK", user.getRankCd());
|
||||||
|
user.setDeptNm(rankNm); // UserVO에 deptCdName 필드 있어야 함
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return RestResponse.builder()
|
||||||
|
.status(HttpStatus.OK) // 200 성공
|
||||||
|
.data(users)
|
||||||
|
// .msg("수정되었습니다.")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
} @Override
|
||||||
|
public RestResponse findByUniqApprovalUser(String userName) {
|
||||||
|
|
||||||
|
List<UserVO> users = userMapper.selectUsersByNameAndRank(userName);
|
||||||
|
// 코드 이름을 붙여주는 처리 (가공)
|
||||||
|
users.forEach(user -> {
|
||||||
|
String deptNm = tCodeUtils.getCodeName("DEPT", user.getDeptCd());
|
||||||
|
user.setDeptNm(deptNm); // UserVO에 deptCdName 필드 있어야 함
|
||||||
|
String rankNm = tCodeUtils.getCodeName("RANK", user.getRankCd());
|
||||||
|
user.setDeptNm(rankNm); // UserVO에 deptCdName 필드 있어야 함
|
||||||
});
|
});
|
||||||
|
|
||||||
return RestResponse.builder()
|
return RestResponse.builder()
|
||||||
|
|||||||
@ -49,6 +49,11 @@ public class UserRestController {
|
|||||||
log.info("userName: {}", userName);
|
log.info("userName: {}", userName);
|
||||||
return ResponseEntity.ok(userService.findByUniqUserName(userName));
|
return ResponseEntity.ok(userService.findByUniqUserName(userName));
|
||||||
}
|
}
|
||||||
|
@GetMapping("/api/admin/approval/search/name")
|
||||||
|
public ResponseEntity<?> findByUniqApprovalUser(@RequestParam String userName) {
|
||||||
|
log.info("userName: {}", userName);
|
||||||
|
return ResponseEntity.ok(userService.findByUniqApprovalUser(userName));
|
||||||
|
}
|
||||||
|
|
||||||
// 코드 그룹 수정 메서드
|
// 코드 그룹 수정 메서드
|
||||||
@PutMapping("/api/admin/user/{uniqId}")
|
@PutMapping("/api/admin/user/{uniqId}")
|
||||||
|
|||||||
104
src/main/resources/mapper/itn/bizTrip/BizTripMapper.xml
Normal file
104
src/main/resources/mapper/itn/bizTrip/BizTripMapper.xml
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?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.itn.admin.itn.bizTrip.mapper.BizTripMapper">
|
||||||
|
|
||||||
|
<insert id="insertBizTrip" useGeneratedKeys="true" keyProperty="tripId">
|
||||||
|
INSERT INTO biz_trip (
|
||||||
|
trip_type_cd, location_cd, location_txt, purpose,
|
||||||
|
move_cd, trip_dt, start_time, end_time, status,
|
||||||
|
frst_register_id
|
||||||
|
) VALUES (
|
||||||
|
#{tripTypeCd}, #{locationCd}, #{locationTxt}, #{purpose},
|
||||||
|
#{moveCd}, #{tripDt}, #{startTime}, #{endTime}, #{status},
|
||||||
|
#{frstRegisterId}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<insert id="insertTripMember">
|
||||||
|
INSERT INTO biz_trip_member (trip_id, uniq_id, role)
|
||||||
|
VALUES (#{tripId}, #{uniqId}, #{role})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<insert id="insertApprovalLine">
|
||||||
|
INSERT INTO biz_trip_approval (trip_id, approver_id, order_no, approve_status)
|
||||||
|
VALUES (#{tripId}, #{approverId}, #{orderNo}, #{approveStatus})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<select id="selectTripList" resultType="bizTripVO">
|
||||||
|
SELECT
|
||||||
|
bt.trip_id,
|
||||||
|
bt.trip_type_cd,
|
||||||
|
bt.location_cd,
|
||||||
|
bt.location_txt,
|
||||||
|
bt.purpose,
|
||||||
|
bt.move_cd,
|
||||||
|
bt.trip_dt,
|
||||||
|
bt.start_time,
|
||||||
|
bt.end_time,
|
||||||
|
bt.frst_register_id,
|
||||||
|
|
||||||
|
-- 상태 계산 로직
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM biz_trip_approval a
|
||||||
|
WHERE a.trip_id = bt.trip_id
|
||||||
|
AND a.approve_status = '40'
|
||||||
|
) THEN '40' -- 반려
|
||||||
|
|
||||||
|
WHEN NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM biz_trip_approval a
|
||||||
|
WHERE a.trip_id = bt.trip_id
|
||||||
|
AND a.approve_status <> '30'
|
||||||
|
) THEN '30' -- 전체 승인
|
||||||
|
|
||||||
|
WHEN EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM biz_trip_approval a
|
||||||
|
WHERE a.trip_id = bt.trip_id
|
||||||
|
AND a.approve_status <> '10'
|
||||||
|
) THEN '20' -- 일부 결재함 (진행 중)
|
||||||
|
|
||||||
|
ELSE '10' -- 전부 대기
|
||||||
|
END AS status
|
||||||
|
|
||||||
|
FROM biz_trip bt
|
||||||
|
ORDER BY bt.trip_dt DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<!– 모든 코드 그룹을 조회하는 쿼리 –>
|
||||||
|
<select id="findAll" resultType="codeVO">
|
||||||
|
SELECT * FROM common_code
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!– 특정 코드 그룹을 ID로 조회하는 쿼리 –>
|
||||||
|
<select id="findById" parameterType="String" resultType="codeVO">
|
||||||
|
SELECT * FROM common_code WHERE code_group_id = #{codeGroupId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!– 코드 그룹을 추가하는 쿼리 –>
|
||||||
|
<insert id="insert" parameterType="codeVO">
|
||||||
|
INSERT INTO common_code (code_group_id, code_group_name, description, frst_register_id, frst_regist_pnttm, last_updusr_id, last_updt_pnttm)
|
||||||
|
VALUES (#{codeGroupId}, #{codeGroupName}, #{description}, #{frstRegisterId}, #{frstRegistPnttm}, #{lastUpdusrId}, #{lastUpdtPnttm})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<!– 코드 그룹을 수정하는 쿼리 –>
|
||||||
|
<update id="update" parameterType="codeVO">
|
||||||
|
UPDATE common_code
|
||||||
|
SET code_group_name = #{codeGroupName},
|
||||||
|
description = #{description},
|
||||||
|
last_updusr_id = #{lastUpdusrId},
|
||||||
|
last_updt_pnttm = #{lastUpdtPnttm}
|
||||||
|
WHERE code_group_id = #{codeGroupId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!– 코드 그룹을 삭제하는 쿼리 –>
|
||||||
|
<delete id="delete" parameterType="String">
|
||||||
|
DELETE FROM common_code WHERE code_group_id = #{codeGroupId}
|
||||||
|
</delete>-->
|
||||||
|
</mapper>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
, user_id
|
, user_id
|
||||||
, user_pw as password
|
, user_pw as password
|
||||||
, user_name
|
, user_name
|
||||||
, user_rank
|
, rank_cd
|
||||||
, role
|
, role
|
||||||
, gw_id
|
, gw_id
|
||||||
, biostar_id
|
, biostar_id
|
||||||
@ -33,7 +33,7 @@
|
|||||||
, user_id
|
, user_id
|
||||||
, user_pw AS password
|
, user_pw AS password
|
||||||
, user_name
|
, user_name
|
||||||
, user_rank
|
, rank_cd
|
||||||
, mobile_phone
|
, mobile_phone
|
||||||
, dept_cd
|
, dept_cd
|
||||||
, role
|
, role
|
||||||
@ -57,8 +57,8 @@
|
|||||||
|
|
||||||
<update id="updateUserInfo" parameterType="userVO">
|
<update id="updateUserInfo" parameterType="userVO">
|
||||||
UPDATE users SET
|
UPDATE users SET
|
||||||
user_name = #{username}
|
user_name = #{userName}
|
||||||
, user_rank = #{userRank}
|
, rank_cd = #{rankCd}
|
||||||
, dept_cd = #{deptCd}
|
, dept_cd = #{deptCd}
|
||||||
<if test="role != null and role != ''">
|
<if test="role != null and role != ''">
|
||||||
,role = #{role}
|
,role = #{role}
|
||||||
@ -66,6 +66,9 @@
|
|||||||
<if test="gwId != null and gwId != ''">
|
<if test="gwId != null and gwId != ''">
|
||||||
,gw_id = #{gwId}
|
,gw_id = #{gwId}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="mobilePhone != null and mobilePhone != ''">
|
||||||
|
,mobile_phone = #{mobilePhone}
|
||||||
|
</if>
|
||||||
<if test="biostarId != null and biostarId != ''">
|
<if test="biostarId != null and biostarId != ''">
|
||||||
,biostar_id = #{biostarId}
|
,biostar_id = #{biostarId}
|
||||||
</if>
|
</if>
|
||||||
@ -83,4 +86,20 @@
|
|||||||
WHERE uniq_id = #{uniqId}
|
WHERE uniq_id = #{uniqId}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<select id="selectUsersByNameAndRank" resultType="userVO">
|
||||||
|
SELECT u.*
|
||||||
|
FROM users u
|
||||||
|
JOIN common_code_detail ccd
|
||||||
|
on u.rank_cd = ccd.code_id
|
||||||
|
WHERE ccd.code_group_id = 'RANK'
|
||||||
|
AND ccd.sort_order <= (
|
||||||
|
SELECT sort_order
|
||||||
|
FROM common_code_detail
|
||||||
|
WHERE code_group_id = 'RANK'
|
||||||
|
AND code_name = '차장'
|
||||||
|
)
|
||||||
|
AND u.user_name LIKE CONCAT('%', #{userName}, '%')
|
||||||
|
AND u.active_yn = 'Y'
|
||||||
|
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
@ -25,6 +25,10 @@
|
|||||||
|
|
||||||
<typeAlias type="com.itn.admin.itn.commute.mapper.domain.ItnCommuteBackVO" alias="itnCommuteBackVO"/>
|
<typeAlias type="com.itn.admin.itn.commute.mapper.domain.ItnCommuteBackVO" alias="itnCommuteBackVO"/>
|
||||||
|
|
||||||
|
<typeAlias type="com.itn.admin.itn.bizTrip.mapper.domain.BizTripVO" alias="bizTripVO"/>
|
||||||
|
<typeAlias type="com.itn.admin.itn.bizTrip.mapper.domain.BizTripMemberVO" alias="bizTripMemberVO"/>
|
||||||
|
<typeAlias type="com.itn.admin.itn.bizTrip.mapper.domain.BizTripApprovalVO" alias="bizTripApprovalVO"/>
|
||||||
|
|
||||||
<typeAlias type="com.itn.admin.gw.holiday.mapper.domain.HolidayVO" alias="holidayVO"/>
|
<typeAlias type="com.itn.admin.gw.holiday.mapper.domain.HolidayVO" alias="holidayVO"/>
|
||||||
</typeAliases>
|
</typeAliases>
|
||||||
|
|
||||||
|
|||||||
@ -1,177 +0,0 @@
|
|||||||
|
|
||||||
$(function () {
|
|
||||||
|
|
||||||
$(".slider").each(function () {
|
|
||||||
var $slider = $(this); // 현재 슬라이더 요소
|
|
||||||
var $input = $slider.closest('.input-group').find('.sliderValue'); // 해당 슬라이더의 input 요소
|
|
||||||
|
|
||||||
// 슬라이더 초기화
|
|
||||||
$slider.slider({
|
|
||||||
range: "max",
|
|
||||||
min: 1,
|
|
||||||
max: 1000000,
|
|
||||||
value: 1,
|
|
||||||
slide: function (event, ui) {
|
|
||||||
$input.val(ui.value); // 슬라이더 이동 시 input 값 업데이트
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 슬라이더의 초기 값을 input에 설정
|
|
||||||
$input.val($slider.slider("value"));
|
|
||||||
|
|
||||||
// input 변경 시 슬라이더 값 업데이트 (실시간)
|
|
||||||
$input.on("input", function () {
|
|
||||||
var value = $(this).val();
|
|
||||||
// 숫자 범위 확인 후 슬라이더 값 업데이트
|
|
||||||
if ($.isNumeric(value) && value >= 1 && value <= 1000000) {
|
|
||||||
$slider.slider("value", value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("form").on("reset", function () {
|
|
||||||
setTimeout(function () {
|
|
||||||
$("#divTwoSms #sendCnt").val(1); // 건수 필드 값을 1로 설정
|
|
||||||
$("#divTwoSms #slider").slider("value", 1); // 슬라이더 값도 1로 설정
|
|
||||||
}, 0); // setTimeout 사용 이유: reset 이벤트 후에 값 설정
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 예시 버튼
|
|
||||||
* */
|
|
||||||
$(".examBtn").on("click", function () {
|
|
||||||
|
|
||||||
var tagId = getParentsId($(this));
|
|
||||||
var $recvPhone = $(tagId + ' .recvPhone');
|
|
||||||
var $sendPhone = $(tagId + ' .sendPhone');
|
|
||||||
var $msgType = $(tagId + ' .msgType');
|
|
||||||
var $message = $(tagId + ' .message');
|
|
||||||
var $subject = $(tagId + ' .subject');
|
|
||||||
|
|
||||||
// 기본 전화번호 설정
|
|
||||||
$recvPhone.val('01083584250');
|
|
||||||
$sendPhone.val('01083584250');
|
|
||||||
|
|
||||||
// 메시지 타입에 따른 메시지 설정
|
|
||||||
var msgType = $msgType.val();
|
|
||||||
var msg = generateMessage(msgType);
|
|
||||||
|
|
||||||
// 내용
|
|
||||||
$message.val(msg);
|
|
||||||
updateByteCount($message);
|
|
||||||
|
|
||||||
if (msgType === 'L'
|
|
||||||
||msgType === 'M'
|
|
||||||
||msgType === 'A'
|
|
||||||
||msgType === 'F'
|
|
||||||
) {
|
|
||||||
$subject.val('ITN SUBJECT');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
function generateMessage(msgType) {
|
|
||||||
var messages = {
|
|
||||||
'S': 'ITN SMS test ',
|
|
||||||
'L': 'ITN LMS test ',
|
|
||||||
'M': 'ITN MMS message test ',
|
|
||||||
'A': 'ITN ',
|
|
||||||
'F': 'ITN '
|
|
||||||
};
|
|
||||||
// 타입이 위 값들고 같이 않으면 null 반환
|
|
||||||
return (messages[msgType] || '') + getNowDate();
|
|
||||||
}
|
|
||||||
$('.msgType').on('change', function() {
|
|
||||||
|
|
||||||
var msgType = $(this).val();
|
|
||||||
var tagId = getParentsId($(this));
|
|
||||||
|
|
||||||
// 제목
|
|
||||||
$(tagId+' .subject').closest('.form-group').hide();
|
|
||||||
|
|
||||||
// 파일 그룹
|
|
||||||
$(tagId+' .fileUploadGroup').hide();
|
|
||||||
$(tagId+' .fileUploadGroup input[type="file"]').val("");
|
|
||||||
|
|
||||||
if(msgType === 'L'
|
|
||||||
||msgType === 'A'
|
|
||||||
||msgType === 'F'
|
|
||||||
) {
|
|
||||||
$(tagId+' .subject').closest('.form-group').show();
|
|
||||||
}else if(msgType === 'M'){
|
|
||||||
$(tagId+' .subject').closest('.form-group').show();
|
|
||||||
$(tagId+' .fileUploadGroup').show();
|
|
||||||
}
|
|
||||||
|
|
||||||
var $message = $(tagId + ' .message');
|
|
||||||
$message.val(generateMessage(msgType));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$('.toggle-info-btn').on('click', function() {
|
|
||||||
var $card = $(this).closest('.card'); // 클릭한 버튼의 가장 가까운 부모 .card 요소 찾기
|
|
||||||
var $hiddenInfo = $card.find('.hidden-info'); // 해당 카드 내에서 .hidden-info 요소 찾기
|
|
||||||
|
|
||||||
$hiddenInfo.slideToggle(); // 애니메이션 효과를 추가하여 더 부드럽게 보이도록 함
|
|
||||||
var icon = $(this).find('i');
|
|
||||||
if ($hiddenInfo.is(':visible')) {
|
|
||||||
icon.removeClass('fa-info-circle').addClass('fa-times-circle');
|
|
||||||
} else {
|
|
||||||
icon.removeClass('fa-times-circle').addClass('fa-info-circle');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$('textarea').on('input', function() {
|
|
||||||
updateByteCount(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// function updateByteCount(textarea) {
|
|
||||||
// console.log('textarea : ', textarea);
|
|
||||||
// var text = $(textarea).val();
|
|
||||||
// var byteLength = new TextEncoder().encode(text).length;
|
|
||||||
// $(textarea).closest('.form-group').find('.byte-count').text(byteLength + ' bytes');
|
|
||||||
// }
|
|
||||||
function updateByteCount(textarea) {
|
|
||||||
var text = $(textarea).val();
|
|
||||||
var byteLength = calculateByteLength(text);
|
|
||||||
$(textarea).closest('.form-group').find('.byte-count').text(byteLength + ' bytes');
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateByteLength(text) {
|
|
||||||
var byteLength = 0;
|
|
||||||
for (var i = 0; i < text.length; i++) {
|
|
||||||
var charCode = text.charCodeAt(i);
|
|
||||||
if (charCode <= 0x007F) {
|
|
||||||
byteLength += 1; // 1 byte for ASCII characters
|
|
||||||
} else if (charCode <= 0x07FF) {
|
|
||||||
byteLength += 2; // 2 bytes for characters from U+0080 to U+07FF
|
|
||||||
} else {
|
|
||||||
byteLength += 2; // 2 bytes for characters from U+0800 and above (including Hangul)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return byteLength;
|
|
||||||
}
|
|
||||||
function getParentsId($obj){
|
|
||||||
|
|
||||||
var $col = $obj.closest('.col-md-6'); // 클릭한 버튼의 가장 가까운 부모 .card 요소 찾기
|
|
||||||
// 해당 카드 내에서 .hidden-info 요소 찾기
|
|
||||||
return '#' + $col.attr('id');
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNowDate(){
|
|
||||||
|
|
||||||
// 현재 날짜와 시간을 가져와서 포맷팅
|
|
||||||
var now = new Date();
|
|
||||||
var year = String(now.getFullYear()).substring(2); // 년도 마지막 두 자리
|
|
||||||
var month = ('0' + (now.getMonth() + 1)).slice(-2); // 월 (0부터 시작하므로 +1 필요)
|
|
||||||
var day = ('0' + now.getDate()).slice(-2); // 일
|
|
||||||
var hours = ('0' + now.getHours()).slice(-2); // 시
|
|
||||||
var minutes = ('0' + now.getMinutes()).slice(-2); // 분
|
|
||||||
|
|
||||||
return year + month + day + '|' + hours + ':' + minutes;
|
|
||||||
}
|
|
||||||
@ -1,272 +0,0 @@
|
|||||||
|
|
||||||
// 타이머 ID 저장을 위한 변수
|
|
||||||
let oneInsertCntIntervalId;
|
|
||||||
let oneTransferCntIntervalId;
|
|
||||||
let oneReporingCntIntervalId;
|
|
||||||
// insert 타이머
|
|
||||||
let oneIntervalId_insertSeconds;
|
|
||||||
// 이관 타이머
|
|
||||||
let oneIntervalId_transferSeconds;
|
|
||||||
// 이관 타이머
|
|
||||||
let oneIntervalId_reporingSeconds;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function fn_oneInsertScriptStart(){
|
|
||||||
// 건수를 현황확인으로 이동
|
|
||||||
$('#divOneSmsCard .sendCntTxt').text('('+$('#divOneSms .sliderValue').val()+'건)');
|
|
||||||
oneStartInsertTimer(); // insert 타임어택 시작
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// LOG 테이블에
|
|
||||||
function fn_oneReportScriptStart(){
|
|
||||||
oneStartReportTimer(); // report 타임어택 시작
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function oneStartInsertTimer() {
|
|
||||||
console.log(' :: startInsertTimer :: ');
|
|
||||||
let startTime = Date.now();
|
|
||||||
oneStartInsertCntTimer();
|
|
||||||
oneIntervalId_insertSeconds = setInterval(function() {
|
|
||||||
let currentTime = Date.now();
|
|
||||||
let elapsedTime = (currentTime - startTime) / 1000; // 밀리초를 초 단위로 변환
|
|
||||||
// 분과 초로 변환
|
|
||||||
let minutes = Math.floor(elapsedTime / 60); // 분 계산
|
|
||||||
let seconds = (elapsedTime % 60).toFixed(3); // 나머지 초 계산
|
|
||||||
|
|
||||||
document.querySelector('#divOneSmsCard .insertSeconds').innerText = minutes + ' 분 ' + seconds + ' 초';
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function oneStartInsertCntTimer() {
|
|
||||||
console.log('oneStartInsertCntTimer ::');
|
|
||||||
// 1초마다 fn_insertCntAndTime 함수를 호출
|
|
||||||
oneInsertCntIntervalId = setInterval(fn_oneInsertCntAndTime, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function oneStopInsertTimer() {
|
|
||||||
clearInterval(oneIntervalId_insertSeconds);
|
|
||||||
clearInterval(oneInsertCntIntervalId);
|
|
||||||
console.log("insert 타이머가 멈췄습니다.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function fn_oneInsertCntAndTime(){
|
|
||||||
|
|
||||||
console.log('fn_oneInsertCntAndTime ::');
|
|
||||||
// 폼 데이터를 수집
|
|
||||||
var formData = new FormData($("#divOneSms .sendForm")[0]);
|
|
||||||
|
|
||||||
var jsonObject = {};
|
|
||||||
formData.forEach((value, key) => {
|
|
||||||
if (!(value instanceof File)) {
|
|
||||||
jsonObject[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log('url : /agent/one/findByInsertCnt');
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "/agent/one/findByInsertCnt",
|
|
||||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json',
|
|
||||||
// async: true,
|
|
||||||
success: function (data) {
|
|
||||||
console.log(' one findByInsertCnt data : ', data);
|
|
||||||
|
|
||||||
if (data.status === 'OK') {
|
|
||||||
var cnt = data.data;
|
|
||||||
|
|
||||||
$('#divOneSmsCard .insertCnt').text(cnt);
|
|
||||||
let text = $('#divOneSmsCard .sendCntTxt').text();
|
|
||||||
let numberOnly = text.match(/\d+/)[0];
|
|
||||||
console.log(' one numberOnly :', numberOnly);
|
|
||||||
console.log(' one cnt >= numberOnly :', cnt >= numberOnly);
|
|
||||||
if(cnt >= numberOnly){
|
|
||||||
oneStopInsertTimer();
|
|
||||||
// oneStartTransferTimer($('#oneUserId').val()); // 이관 카운트
|
|
||||||
// fn_oneReportScriptStart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert("오류 알림 : :: "+data.msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (e) {
|
|
||||||
alert(" findByInsertCnt 조회에 실패하였습니다.");
|
|
||||||
oneStopInsertTimer();
|
|
||||||
console.log("ERROR : " + JSON.stringify(e));
|
|
||||||
},
|
|
||||||
beforeSend : function(xmlHttpRequest) {
|
|
||||||
},
|
|
||||||
complete : function(xhr, textStatus) {
|
|
||||||
//로딩창 hide
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 이관 타이머 start
|
|
||||||
function oneStartTransferTimer(userId) {
|
|
||||||
console.log(' :: one startTransferTimer :: ');
|
|
||||||
let startTime = Date.now();
|
|
||||||
oneStartTransferCntTimer(userId)
|
|
||||||
oneIntervalId_transferSeconds = setInterval(function() {
|
|
||||||
let currentTime = Date.now();
|
|
||||||
let elapsedTime = (currentTime - startTime) / 1000; // 밀리초를 초 단위로 변환
|
|
||||||
document.querySelector('#divOneSmsCard .transferSeconds').innerText = elapsedTime.toFixed(3) + ' 초';
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function oneStartTransferCntTimer(userId) {
|
|
||||||
// 1초마다 fn_tranferCntAndTime 함수를 호출
|
|
||||||
oneTransferCntIntervalId = setInterval(function() {
|
|
||||||
fn_oneTranferCntAndTime(userId);
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function oneStopTransferTimer() {
|
|
||||||
clearInterval(oneIntervalId_transferSeconds);
|
|
||||||
clearInterval(oneTransferCntIntervalId);
|
|
||||||
console.log("이관 타이머가 멈췄습니다.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function fn_oneTranferCntAndTime(userId){
|
|
||||||
|
|
||||||
// 폼 데이터를 수집
|
|
||||||
var formData = new FormData($("#divOneSms .sendForm")[0]);
|
|
||||||
|
|
||||||
var jsonObject = {};
|
|
||||||
formData.forEach((value, key) => {
|
|
||||||
jsonObject[key] = value;
|
|
||||||
});
|
|
||||||
jsonObject['userId'] = userId;
|
|
||||||
console.log('jsonObject : ', jsonObject);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "/agent/server/findByTransferCnt",
|
|
||||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json',
|
|
||||||
// async: true,
|
|
||||||
success: function (data) {
|
|
||||||
console.log('tranfer data : ', data);
|
|
||||||
|
|
||||||
if (data.status == 'OK') {
|
|
||||||
var cnt = data.data;
|
|
||||||
|
|
||||||
$('#divOneSmsCard .transferCnt').text(cnt);
|
|
||||||
let text = $('#divOneSmsCard .insertCnt').text();
|
|
||||||
let numberOnly = text.match(/\d+/)[0];
|
|
||||||
if(cnt >= Number(numberOnly)){
|
|
||||||
oneStopTransferTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert("오류 알림 : :: "+data.msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (e) {
|
|
||||||
alert("이관 조회에 실패하였습니다.");
|
|
||||||
console.log("ERROR : " + JSON.stringify(e));
|
|
||||||
},
|
|
||||||
beforeSend : function(xmlHttpRequest) {
|
|
||||||
},
|
|
||||||
complete : function(xhr, textStatus) {
|
|
||||||
//로딩창 hide
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 리포트 영역
|
|
||||||
// 리포트 영역
|
|
||||||
// 리포트 영역
|
|
||||||
function oneStartReportTimer(userId) {
|
|
||||||
console.log(' :: startReportTimer :: ');
|
|
||||||
let startTime = Date.now();
|
|
||||||
oneStartReporingCntTimer();
|
|
||||||
oneIntervalId_reporingSeconds = setInterval(function() {
|
|
||||||
let currentTime = Date.now();
|
|
||||||
let elapsedTime = (currentTime - startTime) / 1000; // 밀리초를 초 단위로 변환
|
|
||||||
document.querySelector('#divOneSmsCard .reportSeconds').innerText = elapsedTime.toFixed(3) + ' 초';
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function oneStartReporingCntTimer() {
|
|
||||||
// 1초마다 fn_twoReportCntAndTime 함수를 호출
|
|
||||||
oneReporingCntIntervalId = setInterval(function() {
|
|
||||||
fn_oneReportCntAndTime();
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function oneStopReporingTimer() {
|
|
||||||
clearInterval(oneIntervalId_reporingSeconds);
|
|
||||||
clearInterval(oneReporingCntIntervalId);
|
|
||||||
console.log("report 타이머가 멈췄습니다.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function fn_oneReportCntAndTime(userId){
|
|
||||||
|
|
||||||
// 폼 데이터를 수집
|
|
||||||
var formData = new FormData($("#divOneSms .sendForm")[0]);
|
|
||||||
|
|
||||||
var jsonObject = {};
|
|
||||||
formData.forEach((value, key) => {
|
|
||||||
if (!(value instanceof File)) {
|
|
||||||
jsonObject[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
jsonObject['userId'] = userId;
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "/agent/one/findByLogMoveCntWhereMessage",
|
|
||||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json',
|
|
||||||
// async: true,
|
|
||||||
success: function (data) {
|
|
||||||
console.log('findByLogMoveCntWhereMessage data : ', data);
|
|
||||||
|
|
||||||
if (data.status == 'OK') {
|
|
||||||
var cnt = data.data;
|
|
||||||
$('#divOneSmsCard .reportStartCnt').text(cnt);
|
|
||||||
|
|
||||||
var transferCnt = $('#divOneSmsCard .insertCnt').text();
|
|
||||||
|
|
||||||
|
|
||||||
console.log('cnt : ', cnt);
|
|
||||||
console.log('reportStartCnt : ', transferCnt);
|
|
||||||
console.log('');
|
|
||||||
if(cnt >= Number(transferCnt)){
|
|
||||||
oneStopReporingTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert("오류 알림 : :: "+data.msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (e) {
|
|
||||||
alert("report 조회에 실패하였습니다.");
|
|
||||||
console.log("ERROR : " + JSON.stringify(e));
|
|
||||||
},
|
|
||||||
beforeSend : function(xmlHttpRequest) {
|
|
||||||
|
|
||||||
},
|
|
||||||
complete : function(xhr, textStatus) {
|
|
||||||
//로딩창 hide
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,273 +0,0 @@
|
|||||||
|
|
||||||
// 타이머 ID 저장을 위한 변수
|
|
||||||
let twoInsertCntIntervalId;
|
|
||||||
let twoTransferCntIntervalId;
|
|
||||||
let twoReporingCntIntervalId;
|
|
||||||
// insert 타이머
|
|
||||||
let twoIntervalId_insertSeconds;
|
|
||||||
// 이관 타이머
|
|
||||||
let twoIntervalId_transferSeconds;
|
|
||||||
// 리포트 타이머
|
|
||||||
let twoIntervalId_reporingSeconds;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function fn_twoInsertScriptStart(){
|
|
||||||
// 건수를 현황확인으로 이동
|
|
||||||
$('#divTwoSmsCard .sendCntTxt').text('('+$('#divTwoSms .sliderValue').val()+'건)');
|
|
||||||
twoStartInsertTimer(); // insert 타임어택 시작
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function fn_twoReportScriptStart(){
|
|
||||||
twoStartReportTimer(); // report 타임어택 시작
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function twoStartInsertTimer() {
|
|
||||||
console.log(' :: startInsertTimer :: ');
|
|
||||||
let startTime = Date.now();
|
|
||||||
twoStartInsertCntTimer();
|
|
||||||
twoIntervalId_insertSeconds = setInterval(function() {
|
|
||||||
let currentTime = Date.now();
|
|
||||||
let elapsedTime = (currentTime - startTime) / 1000; // 밀리초를 초 단위로 변환
|
|
||||||
// 분과 초로 변환
|
|
||||||
let minutes = Math.floor(elapsedTime / 60); // 분 계산
|
|
||||||
let seconds = (elapsedTime % 60).toFixed(3); // 나머지 초 계산
|
|
||||||
|
|
||||||
document.querySelector('#divTwoSmsCard .insertSeconds').innerText = minutes + ' 분 ' + seconds + ' 초';
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function twoStartInsertCntTimer() {
|
|
||||||
// 1초마다 fn_insertCntAndTime 함수를 호출
|
|
||||||
twoInsertCntIntervalId = setInterval(fn_twoInsertCntAndTime, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function twoStopInsertTimer() {
|
|
||||||
clearInterval(twoIntervalId_insertSeconds);
|
|
||||||
clearInterval(twoInsertCntIntervalId);
|
|
||||||
console.log("insert 타이머가 멈췄습니다.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function fn_twoInsertCntAndTime(){
|
|
||||||
|
|
||||||
// 폼 데이터를 수집
|
|
||||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
|
||||||
|
|
||||||
var jsonObject = {};
|
|
||||||
formData.forEach((value, key) => {
|
|
||||||
if (!(value instanceof File)) {
|
|
||||||
jsonObject[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('fn_twoInsertCntAndTime : [{}]',jsonObject);
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "/agent/two/findByInsertCnt",
|
|
||||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json',
|
|
||||||
// async: true,
|
|
||||||
success: function (data) {
|
|
||||||
// console.log('insert data : ', data);
|
|
||||||
|
|
||||||
if (data.status == 'OK') {
|
|
||||||
var cnt = data.data;
|
|
||||||
|
|
||||||
$('#divTwoSmsCard .insertCnt').text(cnt);
|
|
||||||
let text = $('#divTwoSmsCard .sendCntTxt').text();
|
|
||||||
let numberOnly = text.match(/\d+/)[0];
|
|
||||||
// console.log('numberOnly :', numberOnly);
|
|
||||||
// console.log('cnt >= numberOnly :', cnt >= numberOnly);
|
|
||||||
if(cnt >= numberOnly){
|
|
||||||
twoStopInsertTimer();
|
|
||||||
// twoStartTransferTimer($('#twoUserId').val()); // 이관 카운트
|
|
||||||
// fn_twoReportScriptStart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert("오류 알림 : :: "+data.msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (e) {
|
|
||||||
alert("조회에 실패하였습니다.");
|
|
||||||
console.log("ERROR : " + JSON.stringify(e));
|
|
||||||
},
|
|
||||||
beforeSend : function(xmlHttpRequest) {
|
|
||||||
},
|
|
||||||
complete : function(xhr, textStatus) {
|
|
||||||
//로딩창 hide
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 이관 타이머 start
|
|
||||||
function twoStartTransferTimer(userId) {
|
|
||||||
console.log(' :: two startTransferTimer :: ');
|
|
||||||
let startTime = Date.now();
|
|
||||||
twoStartTransferCntTimer(userId)
|
|
||||||
twoIntervalId_transferSeconds = setInterval(function() {
|
|
||||||
let currentTime = Date.now();
|
|
||||||
let elapsedTime = (currentTime - startTime) / 1000; // 밀리초를 초 단위로 변환
|
|
||||||
// console.log('elapsedTime : ', elapsedTime);
|
|
||||||
document.querySelector('#divTwoSmsCard .transferSeconds').innerText = elapsedTime.toFixed(3) + ' 초';
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function twoStartTransferCntTimer(userId) {
|
|
||||||
// 1초마다 fn_tranferCntAndTime 함수를 호출
|
|
||||||
twoTransferCntIntervalId = setInterval(function() {
|
|
||||||
fn_twoTranferCntAndTime(userId);
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function twoStopTransferTimer() {
|
|
||||||
clearInterval(twoIntervalId_transferSeconds);
|
|
||||||
clearInterval(twoTransferCntIntervalId);
|
|
||||||
console.log("이관 타이머가 멈췄습니다.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function fn_twoTranferCntAndTime(userId){
|
|
||||||
|
|
||||||
// 폼 데이터를 수집
|
|
||||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
|
||||||
|
|
||||||
// console.log('? :: ', formData);
|
|
||||||
var jsonObject = {};
|
|
||||||
formData.forEach((value, key) => {
|
|
||||||
jsonObject[key] = value;
|
|
||||||
});
|
|
||||||
jsonObject['userId'] = userId;
|
|
||||||
// console.log('jsonObject : ', jsonObject);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "/agent/server/findByTransferCnt",
|
|
||||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json',
|
|
||||||
// async: true,
|
|
||||||
success: function (data) {
|
|
||||||
console.log('tranfer data : ', data);
|
|
||||||
|
|
||||||
if (data.status == 'OK') {
|
|
||||||
var cnt = data.data;
|
|
||||||
|
|
||||||
$('#divTwoSmsCard .transferCnt').text(cnt);
|
|
||||||
let text = $('#divTwoSmsCard .insertCnt').text();
|
|
||||||
let numberOnly = text.match(/\d+/)[0];
|
|
||||||
if(cnt >= Number(numberOnly)){
|
|
||||||
twoStopTransferTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert("오류 알림 : :: "+data.msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (e) {
|
|
||||||
alert("이관 조회에 실패하였습니다.");
|
|
||||||
console.log("ERROR : " + JSON.stringify(e));
|
|
||||||
},
|
|
||||||
beforeSend : function(xmlHttpRequest) {
|
|
||||||
},
|
|
||||||
complete : function(xhr, textStatus) {
|
|
||||||
//로딩창 hide
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 리포트 영역
|
|
||||||
// 리포트 영역
|
|
||||||
// 리포트 영역
|
|
||||||
function twoStartReportTimer() {
|
|
||||||
// console.log(' :: startReportTimer :: ');
|
|
||||||
let startTime = Date.now();
|
|
||||||
twoStartReporingCntTimer();
|
|
||||||
twoIntervalId_reporingSeconds = setInterval(function() {
|
|
||||||
let currentTime = Date.now();
|
|
||||||
let elapsedTime = (currentTime - startTime) / 1000; // 밀리초를 초 단위로 변환
|
|
||||||
document.querySelector('#divTwoSmsCard .reportSeconds').innerText = elapsedTime.toFixed(3) + ' 초';
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function twoStartReporingCntTimer() {
|
|
||||||
// 1초마다 fn_twoReportCntAndTime 함수를 호출
|
|
||||||
twoReporingCntIntervalId = setInterval(function() {
|
|
||||||
fn_twoReportCntAndTime();
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function twoStopReporingTimer() {
|
|
||||||
clearInterval(twoIntervalId_reporingSeconds);
|
|
||||||
clearInterval(twoReporingCntIntervalId);
|
|
||||||
console.log("report 타이머가 멈췄습니다.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function fn_twoReportCntAndTime(userId){
|
|
||||||
|
|
||||||
// 폼 데이터를 수집
|
|
||||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
|
||||||
|
|
||||||
var jsonObject = {};
|
|
||||||
formData.forEach((value, key) => {
|
|
||||||
if (!(value instanceof File)) {
|
|
||||||
jsonObject[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
jsonObject['userId'] = userId;
|
|
||||||
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "/agent/two/findByLogMoveCntWhereMessage",
|
|
||||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json',
|
|
||||||
// async: true,
|
|
||||||
success: function (data) {
|
|
||||||
console.log('findByLogMoveCntWhereMessage data : ', data);
|
|
||||||
|
|
||||||
if (data.status == 'OK') {
|
|
||||||
var cnt = data.data;
|
|
||||||
|
|
||||||
console.log('cnt : ', cnt);
|
|
||||||
// 리포트 영역에 cnt 추가
|
|
||||||
$('#divTwoSmsCard .reportStartCnt').text(cnt);
|
|
||||||
// server DB에 update한 건수와 cnt비교
|
|
||||||
var transferCnt = $('#divTwoSmsCard .insertCnt').text();
|
|
||||||
|
|
||||||
console.log('cnt : ', cnt);
|
|
||||||
console.log('reportStartCnt : ', transferCnt);
|
|
||||||
console.log('');
|
|
||||||
if(cnt >= Number(transferCnt)){
|
|
||||||
twoStopReporingTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert("오류 알림 : :: "+data.msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (e) {
|
|
||||||
alert("report 조회에 실패하였습니다.");
|
|
||||||
console.log("ERROR : " + JSON.stringify(e));
|
|
||||||
},
|
|
||||||
beforeSend : function(xmlHttpRequest) {
|
|
||||||
|
|
||||||
},
|
|
||||||
complete : function(xhr, textStatus) {
|
|
||||||
//로딩창 hide
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
247
src/main/resources/static/cmn/js/bizTrip/event.js
Normal file
247
src/main/resources/static/cmn/js/bizTrip/event.js
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
/**
|
||||||
|
* 페이지 로드 완료 후 실행되는 초기화 함수 (비워둠)
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
$(function () {
|
||||||
|
// 초기화 코드 필요 시 여기에 작성
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enter 키 입력 시 사용자 검색 수행
|
||||||
|
* @event keydown
|
||||||
|
* @param {KeyboardEvent} e
|
||||||
|
*/
|
||||||
|
document.getElementById("userSearchKeyword").addEventListener("keydown", function (e) {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
searchUser();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.getElementById("approvalSearchKeyword").addEventListener("keydown", function (e) {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
searchApproval();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모달이 열릴 때 사용자 목록을 불러오고 포커스를 맞춤
|
||||||
|
* @event shown.bs.modal
|
||||||
|
*/
|
||||||
|
$('#userSearchModal').on('shown.bs.modal', function () {
|
||||||
|
loadUserList();
|
||||||
|
$('#userSearchKeyword').trigger('focus');
|
||||||
|
});
|
||||||
|
$('#approvalSearchModal').on('shown.bs.modal', function () {
|
||||||
|
loadApprovalList();
|
||||||
|
$('#approvalSearchKeyword').trigger('focus');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 날짜 입력 필드 클릭 시 브라우저 기본 날짜 선택기 표시
|
||||||
|
* @event click
|
||||||
|
*/
|
||||||
|
document.querySelector('input[id="tripDate"]').addEventListener('click', function () {
|
||||||
|
this.showPicker && this.showPicker();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 사용자 목록을 불러오는 Ajax 요청 함수
|
||||||
|
* @function
|
||||||
|
* @param {string} [keyword=""] - 검색 키워드
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function loadUserList(keyword = "") {
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/admin/user/search/name',
|
||||||
|
type: 'GET',
|
||||||
|
data: { userName: keyword },
|
||||||
|
success: function (result) {
|
||||||
|
const tbody = document.getElementById("userSearchResult");
|
||||||
|
tbody.innerHTML = "";
|
||||||
|
|
||||||
|
const data = result.data;
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
data.forEach(user => {
|
||||||
|
const row = document.createElement("tr");
|
||||||
|
row.innerHTML = `
|
||||||
|
<td>${user.userName}</td>
|
||||||
|
<td>${user.deptNm || "-"}</td>
|
||||||
|
<td>${user.rankCd || "-"}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-sm btn-success"
|
||||||
|
onclick="selectUser('${user.userName}', '${user.deptNm}', '${user.mobilePhone}', '${user.uniqId}')">
|
||||||
|
<i class="fas fa-user-plus"></i> 추가
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
tbody.appendChild(row);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
tbody.innerHTML = `<tr><td colspan="5" class="text-center text-muted">검색 결과가 없습니다.</td></tr>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
alert("사용자 목록을 불러오는 데 실패했습니다.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadApprovalList(keyword = "") {
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/admin/approval/search/name',
|
||||||
|
type: 'GET',
|
||||||
|
data: { userName: keyword },
|
||||||
|
success: function (result) {
|
||||||
|
const tbody = document.getElementById("approvalSearchResult");
|
||||||
|
const data = result.data;
|
||||||
|
|
||||||
|
tbody.innerHTML = "";
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
data.forEach(user => {
|
||||||
|
const row = document.createElement("tr");
|
||||||
|
row.innerHTML = `
|
||||||
|
<td>${user.userName}</td>
|
||||||
|
<td>${user.deptNm || "-"}</td>
|
||||||
|
<td>${user.rankCd || "-"}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-sm btn-success"
|
||||||
|
onclick="selectApproval('${user.userName}', '${user.deptNm}', '${user.mobilePhone}', '${user.uniqId}')">
|
||||||
|
<i class="fas fa-user-plus"></i> 추가
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
tbody.appendChild(row);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
tbody.innerHTML = `<tr><td colspan="5" class="text-center text-muted">검색 결과가 없습니다.</td></tr>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
alert("사용자 목록을 불러오는 데 실패했습니다.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 사용자를 선택하여 출장 인원 또는 결재라인에 추가
|
||||||
|
* @function
|
||||||
|
* @param {string} name - 사용자 이름
|
||||||
|
* @param {string} dept - 부서명
|
||||||
|
* @param {string} phone - 전화번호
|
||||||
|
* @param {string} uniqId - 사용자 고유 ID
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function selectUser(name, dept, phone, uniqId) {
|
||||||
|
|
||||||
|
const tbody = document.getElementById("tripMemberTbody");
|
||||||
|
const newRow = document.createElement("tr");
|
||||||
|
newRow.setAttribute("data-uniqid", uniqId);
|
||||||
|
newRow.innerHTML = `
|
||||||
|
<td>${name}</td>
|
||||||
|
<td>${dept}</td>
|
||||||
|
<td>${phone}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a href="#" class="btn btn-danger btn-sm" onclick="removeMemberRow(this)">
|
||||||
|
<i class="fas fa-user-minus"></i> 삭제
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
tbody.appendChild(newRow);
|
||||||
|
$('#userSearchModal').modal('hide');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function selectApproval(name, dept, phone, uniqId) {
|
||||||
|
const stageId = $('#approvalSearchModal').data('stageId');
|
||||||
|
|
||||||
|
const rowMap = {
|
||||||
|
approval1: { index: 0, inputId: "approver1" },
|
||||||
|
approval2: { index: 1, inputId: "approver2" },
|
||||||
|
approval3: { index: 2, inputId: "approver3" }
|
||||||
|
};
|
||||||
|
|
||||||
|
const { index, inputId } = rowMap[stageId];
|
||||||
|
const tbody = document.getElementById("approvalLineTbody");
|
||||||
|
const targetRow = tbody.rows[index];
|
||||||
|
if (!targetRow) return;
|
||||||
|
|
||||||
|
targetRow.innerHTML = `
|
||||||
|
<td class="text-center align-middle">${targetRow.cells[0].textContent}</td>
|
||||||
|
<td>${name}</td>
|
||||||
|
<td>${dept}</td>
|
||||||
|
<td>${phone}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a href="#" class="btn btn-danger btn-sm" onclick="resetApproval('${stageId}')">
|
||||||
|
<i class="fas fa-user-minus"></i> 삭제
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// hidden input에 uniqId 저장
|
||||||
|
document.getElementById(inputId).value = uniqId;
|
||||||
|
|
||||||
|
$('#approvalSearchModal').modal('hide');
|
||||||
|
$('#approvalSearchModal').data('stageId', null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 검색창 버튼 클릭 시 사용자 검색 실행
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function searchUser() {
|
||||||
|
const keyword = document.getElementById("userSearchKeyword").value.trim();
|
||||||
|
loadUserList(keyword);
|
||||||
|
}
|
||||||
|
function searchApproval() {
|
||||||
|
const keyword = document.getElementById("userSearchKeyword").value.trim();
|
||||||
|
loadApprovalList(keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 출장 인원 행 삭제
|
||||||
|
* @function
|
||||||
|
* @param {HTMLElement} el - 삭제 버튼 요소
|
||||||
|
*/
|
||||||
|
function removeMemberRow(el) {
|
||||||
|
if (confirm("정말 삭제하시겠습니까?")) {
|
||||||
|
const row = el.closest("tr");
|
||||||
|
if (row) row.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 결재자 지정 모달 열기
|
||||||
|
* @function
|
||||||
|
* @param {string} stageId - 결재 단계 ID (approval1, approval2, approval3)
|
||||||
|
*/
|
||||||
|
function openApprovalModal(stageId) {
|
||||||
|
$('#approvalSearchModal').data('stageId', stageId).modal('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 결재자 삭제 및 단계 초기화
|
||||||
|
* @function
|
||||||
|
* @param {string} stageId - 결재 단계 ID
|
||||||
|
*/
|
||||||
|
function resetApproval(stageId) {
|
||||||
|
const rowIndex = {
|
||||||
|
approval1: 0,
|
||||||
|
approval2: 1,
|
||||||
|
approval3: 2
|
||||||
|
}[stageId];
|
||||||
|
|
||||||
|
const tbody = document.getElementById("approvalLineTbody");
|
||||||
|
const label = ['검토 1', '검토 2', '결제'][rowIndex];
|
||||||
|
|
||||||
|
tbody.rows[rowIndex].innerHTML = `
|
||||||
|
<td class="text-center align-middle">${label}</td>
|
||||||
|
<td colspan="4">
|
||||||
|
<button type="button" class="btn btn-outline-info btn-sm" onclick="openApprovalModal('${stageId}')">
|
||||||
|
<i class="fas fa-user-plus"></i> 사용자 지정
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
}
|
||||||
26
src/main/resources/static/cmn/js/bizTrip/init.js
Normal file
26
src/main/resources/static/cmn/js/bizTrip/init.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 시작 시간 선택기 초기화
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
$('#startTimePicker').datetimepicker({
|
||||||
|
format: 'HH:mm',
|
||||||
|
stepping: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 종료 시간 선택기 초기화
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
$('#endTimePicker').datetimepicker({
|
||||||
|
format: 'HH:mm',
|
||||||
|
stepping: 10,
|
||||||
|
icons: {
|
||||||
|
time: 'far fa-clock',
|
||||||
|
up: 'fas fa-chevron-up',
|
||||||
|
down: 'fas fa-chevron-down'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
52
src/main/resources/static/cmn/js/bizTrip/service.js
Normal file
52
src/main/resources/static/cmn/js/bizTrip/service.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 출장 등록 전송 함수 (값 생성 + 전송 담당)
|
||||||
|
*/
|
||||||
|
function collectAndSubmitTripData() {
|
||||||
|
if (!validateTripForm()) return;
|
||||||
|
|
||||||
|
// 값 생성
|
||||||
|
const tripInfo = {
|
||||||
|
tripTypeCd: $('#tripType').val(),
|
||||||
|
locationCd: $('#tripLocation').val(),
|
||||||
|
locationTxt: $('#locationTxt').val(),
|
||||||
|
purpose: $('#purpose').val(),
|
||||||
|
moveCd: $('#tripMove').val(),
|
||||||
|
tripDt: $('#tripDate').val(),
|
||||||
|
startTime: $('#startTimePicker input').val(),
|
||||||
|
endTime: $('#endTimePicker input').val(),
|
||||||
|
status: '10'
|
||||||
|
};
|
||||||
|
|
||||||
|
const tripMembers = [];
|
||||||
|
$('#tripMemberTbody tr').each(function () {
|
||||||
|
const uniqId = $(this).data('uniqid');
|
||||||
|
if (!uniqId) return;
|
||||||
|
const role = $(this).find('td').eq(3).text().trim() === '기안자' ? '0' : '1';
|
||||||
|
tripMembers.push({ uniqId, role });
|
||||||
|
});
|
||||||
|
|
||||||
|
const approvalLines = [];
|
||||||
|
['approver1', 'approver2', 'approver3'].forEach((id, idx) => {
|
||||||
|
const uniqId = $(`#${id}`).val();
|
||||||
|
if (uniqId) {
|
||||||
|
approvalLines.push({
|
||||||
|
approverId: uniqId,
|
||||||
|
orderNo: idx + 1,
|
||||||
|
approveStatus: '10'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const payload = { tripInfo, tripMembers, approvalLines };
|
||||||
|
console.log("payload:", payload);
|
||||||
|
|
||||||
|
// Ajax 전송
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/bizTrip/register',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/json',
|
||||||
|
data: JSON.stringify(payload),
|
||||||
|
success: () => fn_successAlert("등록 성공", "출장 정보가 저장되었습니다."),
|
||||||
|
error: () => fn_failedAlert("등록 실패", "오류가 발생했습니다.")
|
||||||
|
});
|
||||||
|
}
|
||||||
65
src/main/resources/static/cmn/js/bizTrip/validation.js
Normal file
65
src/main/resources/static/cmn/js/bizTrip/validation.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* 출장 등록 입력값 유효성 검사 함수
|
||||||
|
* - 필수 항목 누락 여부 확인
|
||||||
|
* - 출장일자가 오늘 이전인지 확인
|
||||||
|
* - 시작 시간이 종료 시간보다 늦은지 확인
|
||||||
|
*
|
||||||
|
* @returns {boolean} 유효하면 true, 유효하지 않으면 false
|
||||||
|
*/
|
||||||
|
function validateTripForm() {
|
||||||
|
// ===== [1] 입력값 가져오기 =====
|
||||||
|
const tripType = $('#tripType');
|
||||||
|
const location = $('#tripLocation');
|
||||||
|
const locationTxt = $('#locationTxt');
|
||||||
|
const purpose = $('#purpose');
|
||||||
|
const move = $('#tripMove');
|
||||||
|
const date = $('#tripDate');
|
||||||
|
const start = $('#startTimePicker input');
|
||||||
|
const end = $('#endTimePicker input');
|
||||||
|
const approver = $('#approver3');
|
||||||
|
|
||||||
|
const tripTypeCd = tripType.val();
|
||||||
|
const locationCd = location.val();
|
||||||
|
const locationTxtVal = locationTxt.val();
|
||||||
|
const purposeVal = purpose.val();
|
||||||
|
const moveCd = move.val();
|
||||||
|
const tripDt = date.val();
|
||||||
|
const startTime = start.val();
|
||||||
|
const endTime = end.val();
|
||||||
|
const approver3 = approver.val();
|
||||||
|
|
||||||
|
// ===== [2] 필수값 체크 + focus =====
|
||||||
|
if (!tripTypeCd) return fn_failedAlert("입력 오류", "출장 구분을 선택해주세요.", 1000), tripType.focus(), false;
|
||||||
|
if (!locationCd) return fn_failedAlert("입력 오류", "출장지를 선택해주세요.", 1000), location.focus(), false;
|
||||||
|
if (!locationTxtVal || locationTxtVal.trim() === "") return fn_failedAlert("입력 오류", "목적지를 입력해주세요.", 1000), locationTxt.focus(), false;
|
||||||
|
if (!purposeVal || purposeVal.trim() === "") return fn_failedAlert("입력 오류", "출장 목적을 입력해주세요.", 1000), purpose.focus(), false;
|
||||||
|
if (!moveCd) return fn_failedAlert("입력 오류", "이동 수단을 선택해주세요.", 1000), move.focus(), false;
|
||||||
|
if (!tripDt) return fn_failedAlert("입력 오류", "출장일자를 선택해주세요.", 1000), date.focus(), false;
|
||||||
|
if (!startTime || !endTime) return fn_failedAlert("입력 오류", "시작/종료 시간을 입력해주세요.", 1000), start.focus(), false;
|
||||||
|
if (!approver3) return fn_failedAlert("입력 오류", "최종 결재자를 지정해주세요.", 1000), approver.focus(), false;
|
||||||
|
|
||||||
|
// ===== [3] 출장일자가 오늘보다 과거일 경우 =====
|
||||||
|
const today = new Date();
|
||||||
|
const inputDate = new Date(tripDt);
|
||||||
|
today.setHours(0, 0, 0, 0);
|
||||||
|
inputDate.setHours(0, 0, 0, 0);
|
||||||
|
if (inputDate < today) {
|
||||||
|
fn_failedAlert("입력 오류", "출장일자는 오늘보다 빠를 수 없습니다.");
|
||||||
|
date.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== [4] 시간 순서 확인 (종료 > 시작) =====
|
||||||
|
const [sH, sM] = startTime.split(':').map(Number);
|
||||||
|
const [eH, eM] = endTime.split(':').map(Number);
|
||||||
|
const startDate = new Date(); startDate.setHours(sH, sM, 0, 0);
|
||||||
|
const endDate = new Date(); endDate.setHours(eH, eM, 0, 0);
|
||||||
|
if (endDate <= startDate) {
|
||||||
|
fn_failedAlert("입력 오류", "종료 시간은 시작 시간보다 이후여야 합니다.");
|
||||||
|
end.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== [5] 유효성 통과 =====
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
<link rel="stylesheet" th:href="@{/plugins/toastr/toastr.min.css}">
|
<link rel="stylesheet" th:href="@{/plugins/toastr/toastr.min.css}">
|
||||||
|
<!-- CSS -->
|
||||||
|
|
||||||
|
|
||||||
<!-- jQuery -->
|
<!-- jQuery -->
|
||||||
@ -121,6 +121,16 @@
|
|||||||
body: msg
|
body: msg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
function fn_failedAlert(title, msg, delay){
|
||||||
|
$(document).Toasts('create', {
|
||||||
|
class: 'bg-danger',
|
||||||
|
title: title,
|
||||||
|
subtitle: '',
|
||||||
|
autohide : true,
|
||||||
|
delay: delay,
|
||||||
|
body: msg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@ -92,7 +92,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<ul class="nav nav-treeview">
|
<ul class="nav nav-treeview">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a th:href="@{/itn/trip/reg}" class="nav-link">
|
<a th:href="@{/itn/bizTrip/reg}" class="nav-link">
|
||||||
<!-- <i class="far fa-circle nav-icon"></i>-->
|
<!-- <i class="far fa-circle nav-icon"></i>-->
|
||||||
<!-- <i class="far fa-clock nav-icon"></i>-->
|
<!-- <i class="far fa-clock nav-icon"></i>-->
|
||||||
<i class="nav-icon fas fa-calendar-check"></i>
|
<i class="nav-icon fas fa-calendar-check"></i>
|
||||||
|
|||||||
220
src/main/resources/templates/itn/bizTrip/list.html
Normal file
220
src/main/resources/templates/itn/bizTrip/list.html
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
<!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}">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.cursor-pointer:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</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">
|
||||||
|
<table id="tripTb" class="table table-bordered table-striped" style="width: 100%;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>출장ID</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 th:each="row, stat : ${list}">
|
||||||
|
<td th:text="${stat.count}"/>
|
||||||
|
<td th:text="${row.tripId}"/>
|
||||||
|
<td th:text="${#temporals.format(row.tripDt, 'yyyy-MM-dd')}"/>
|
||||||
|
<td th:text="${row.startTime + ' ~ ' + row.endTime}"/>
|
||||||
|
<td th:text="${@TCodeUtils.getCodeName('TRIP_TYPE', row.tripTypeCd)}"/>
|
||||||
|
<td th:text="${@TCodeUtils.getCodeName('TRIP_LOCATION', row.locationCd)}"/>
|
||||||
|
<td th:text="${row.locationTxt}"/>
|
||||||
|
<td th:text="${row.purpose}"/>
|
||||||
|
<td th:text="${@TCodeUtils.getCodeName('TRIP_MOVE', row.moveCd)}"/>
|
||||||
|
<td>
|
||||||
|
<span th:switch="${row.status}">
|
||||||
|
<span th:case="'10'" class="badge badge-warning">대기</span>
|
||||||
|
<span th:case="'20'" class="badge badge-primary">진행</span>
|
||||||
|
<span th:case="'30'" class="badge badge-success">승인</span>
|
||||||
|
<span th:case="'40'" class="badge badge-danger">반려</span>
|
||||||
|
<span th:case="*">-</span>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span th:switch="${row.latestApproveStatus}">
|
||||||
|
<span th:case="'10'" class="badge badge-warning">대기</span>
|
||||||
|
<span th:case="'20'" class="badge badge-primary">진행</span>
|
||||||
|
<span th:case="'30'" class="badge badge-success">승인</span>
|
||||||
|
<span th:case="'40'" class="badge badge-danger">반려</span>
|
||||||
|
<span th:case="*">-</span>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td th:text="${row.frstRegisterId}"/>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
const commonExportOptions = {
|
||||||
|
columns: ':visible',
|
||||||
|
format: {
|
||||||
|
body: function (data, row, column, node) {
|
||||||
|
if ($(node).find('select').length) {
|
||||||
|
return $(node).find('select option:selected').text();
|
||||||
|
}
|
||||||
|
// 태그 제거: 보이는 텍스트만 반환
|
||||||
|
return $(node).text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$("#tripTb").DataTable({
|
||||||
|
"responsive": true
|
||||||
|
, "lengthChange": false
|
||||||
|
, "autoWidth": false
|
||||||
|
, "pageLength": 20
|
||||||
|
, "buttons": [
|
||||||
|
{
|
||||||
|
extend: 'copy',
|
||||||
|
charset: 'UTF-8',
|
||||||
|
exportOptions: commonExportOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
extend: 'csv',
|
||||||
|
charset: 'UTF-8',
|
||||||
|
bom: true,
|
||||||
|
exportOptions: commonExportOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
extend: 'excel',
|
||||||
|
charset: 'UTF-8',
|
||||||
|
exportOptions: commonExportOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
extend: 'pdf',
|
||||||
|
charset: 'UTF-8',
|
||||||
|
exportOptions: commonExportOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
extend: 'print',
|
||||||
|
charset: 'UTF-8',
|
||||||
|
exportOptions: commonExportOptions
|
||||||
|
},
|
||||||
|
"colvis"]
|
||||||
|
}).buttons().container().appendTo('#commuteTb_wrapper .col-md-6:eq(0)');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</html>
|
||||||
@ -6,7 +6,7 @@
|
|||||||
layout:decorate="layout">
|
layout:decorate="layout">
|
||||||
<head>
|
<head>
|
||||||
<!-- layout.html 에 들어간 head 부분을 제외하고 개별 파일에만 적용되는 head 부분 추가 -->
|
<!-- layout.html 에 들어간 head 부분을 제외하고 개별 파일에만 적용되는 head 부분 추가 -->
|
||||||
<title>사용자 관리</title>
|
<title>출장 등록</title>
|
||||||
|
|
||||||
<!-- 필요하다면 개별 파일에 사용될 css/js 선언 -->
|
<!-- 필요하다면 개별 파일에 사용될 css/js 선언 -->
|
||||||
|
|
||||||
@ -33,14 +33,6 @@
|
|||||||
border-top: 2px solid #009fe3;
|
border-top: 2px solid #009fe3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-custom {
|
|
||||||
border: 1px solid #dcdcdc;
|
|
||||||
background-color: #ffffff;
|
|
||||||
color: #009fe3;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 6px 18px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -81,7 +73,7 @@
|
|||||||
<!-- 출장신청 영역 -->
|
<!-- 출장신청 영역 -->
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
출장신청
|
출장정보
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table table-bordered table-form" style="table-layout: fixed;">
|
<table class="table table-bordered table-form" style="table-layout: fixed;">
|
||||||
@ -100,19 +92,19 @@
|
|||||||
<th>출장지</th>
|
<th>출장지</th>
|
||||||
<td>
|
<td>
|
||||||
<select class="form-control d-inline" style="width: 20%;" id="tripLocation" name="tripLocation">
|
<select class="form-control d-inline" style="width: 20%;" id="tripLocation" name="tripLocation">
|
||||||
<option value="" th:selected>-- 선택 --</option>
|
<option value="" th:selected>-- 지역 --</option>
|
||||||
<option th:each="code : ${@TCodeUtils.getCodeList('TRIP_LOCATION')}"
|
<option th:each="code : ${@TCodeUtils.getCodeList('TRIP_LOCATION')}"
|
||||||
th:value="${code.codeId}"
|
th:value="${code.codeId}"
|
||||||
th:text="${code.codeName}">
|
th:text="${code.codeName}">
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<input type="text" class="form-control d-inline" style="width: 70%;">
|
<input type="text" id="locationTxt" class="form-control d-inline" style="width: 70%;" placeholder="목적지">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>출장목적</th>
|
<th>출장목적</th>
|
||||||
<td><input type="text" class="form-control"></td>
|
<td><input type="text" id="purpose" class="form-control"></td>
|
||||||
<th>이동사항</th>
|
<th>이동사항</th>
|
||||||
<td>
|
<td>
|
||||||
<select class="form-control" id="tripMove" name="tripMove">
|
<select class="form-control" id="tripMove" name="tripMove">
|
||||||
@ -131,12 +123,30 @@
|
|||||||
</td>
|
</td>
|
||||||
<th>시간</th>
|
<th>시간</th>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex">
|
||||||
<input type="time" id="startTime" class="form-control" style="margin-right: 4px;">
|
<!-- 시작 시간 -->
|
||||||
<span class="align-self-center">~</span>
|
<div class="input-group date" id="startTimePicker" data-target-input="nearest" style="margin-right: 5px;">
|
||||||
<input type="time" id="endTime" class="form-control" style="margin-left: 4px;">
|
<input type="text"
|
||||||
|
class="form-control datetimepicker-input"
|
||||||
|
data-target="#startTimePicker"
|
||||||
|
data-toggle="datetimepicker" />
|
||||||
|
<div class="input-group-append" data-target="#startTimePicker" data-toggle="datetimepicker">
|
||||||
|
<div class="input-group-text"><i class="far fa-clock"></i></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="align-self-center mx-2">~</span>
|
||||||
|
<!-- 종료 시간 -->
|
||||||
|
<div class="input-group date" id="endTimePicker" data-target-input="nearest">
|
||||||
|
<input type="text"
|
||||||
|
class="form-control datetimepicker-input"
|
||||||
|
data-target="#endTimePicker"
|
||||||
|
data-toggle="datetimepicker" />
|
||||||
|
<div class="input-group-append" data-target="#endTimePicker" data-toggle="datetimepicker">
|
||||||
|
<div class="input-group-text"><i class="far fa-clock"></i></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -163,9 +173,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="tripMemberTbody">
|
<tbody id="tripMemberTbody">
|
||||||
<tr>
|
<tr th:data-uniqid="${loginUser.getUniqId()}">
|
||||||
<td th:text="${loginUser.getUserName()}"/>
|
<td th:text="${loginUser.getUserName()}"/>
|
||||||
|
|
||||||
<td th:text="${@TCodeUtils.getCodeName('DEPT', loginUser.getDeptCd())}"/>
|
<td th:text="${@TCodeUtils.getCodeName('DEPT', loginUser.getDeptCd())}"/>
|
||||||
<td th:text="${loginUser.getMobilePhone()}"/>
|
<td th:text="${loginUser.getMobilePhone()}"/>
|
||||||
<td class="text-center">기안자</td>
|
<td class="text-center">기안자</td>
|
||||||
@ -175,9 +184,57 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 결제 라인 영역 -->
|
||||||
|
<div class="card mt-4">
|
||||||
|
<div class="card-header">
|
||||||
|
결제라인
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<table class="table table-bordered table-form mb-0">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center bg-light">
|
||||||
|
<th style="width: 20%;">결재 단계</th>
|
||||||
|
<th style="width: 20%;">이름</th>
|
||||||
|
<th style="width: 25%;">부서명</th>
|
||||||
|
<th style="width: 25%;">연락처</th>
|
||||||
|
<th style="width: 10%;" class="text-center">관리</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="approvalLineTbody">
|
||||||
|
<tr>
|
||||||
|
<td class="text-center align-middle">검토 1</td>
|
||||||
|
<td colspan="4">
|
||||||
|
<button type="button" class="btn btn-outline-info btn-sm" onclick="openApprovalModal('approval1')">
|
||||||
|
<i class="fas fa-user-plus"></i> 사용자 지정
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-center align-middle">검토 2</td>
|
||||||
|
<td colspan="4">
|
||||||
|
<button type="button" class="btn btn-outline-info btn-sm" onclick="openApprovalModal('approval2')">
|
||||||
|
<i class="fas fa-user-plus"></i> 사용자 지정
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-center align-middle">결제</td>
|
||||||
|
<td colspan="4">
|
||||||
|
<button type="button" class="btn btn-outline-info btn-sm" onclick="openApprovalModal('approval3')">
|
||||||
|
<i class="fas fa-user-plus"></i> 사용자 지정
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="approver1" name="approver1">
|
||||||
|
<input type="hidden" id="approver2" name="approver2">
|
||||||
|
<input type="hidden" id="approver3" name="approver3">
|
||||||
|
</div>
|
||||||
<div class="text-right mt-2">
|
<div class="text-right mt-2">
|
||||||
<!-- 등록 버튼 -->
|
<!-- 등록 버튼 -->
|
||||||
<button type="submit" class="btn btn-primary btn-sm">
|
<button type="submit" class="btn btn-primary btn-sm" onclick="collectAndSubmitTripData()">
|
||||||
<i class="fas fa-save"></i> 등록
|
<i class="fas fa-save"></i> 등록
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -191,6 +248,52 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 사용자 검색 모달 -->
|
||||||
|
<div class="modal fade" id="approvalSearchModal" tabindex="-1" role="dialog" aria-labelledby="userSearchModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-xl" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header bg-info">
|
||||||
|
<h5 class="modal-title text-white" id="approvalSearchModalLabel">사용자 검색</h5>
|
||||||
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<!-- 검색 영역 -->
|
||||||
|
<div class="form-inline mb-3">
|
||||||
|
<label class="mr-2">이름 검색</label>
|
||||||
|
<input type="text" class="form-control mr-2" auto id="approvalSearchKeyword" placeholder="검색어 입력" autocomplete="off">
|
||||||
|
<button type="button" class="btn btn-info btn-sm" onclick="searchUser()">검색</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 결과 테이블 -->
|
||||||
|
<div class="table-responsive" style="max-height: 500px; overflow-y: auto;">
|
||||||
|
<table class="table table-hover table-bordered table-sm text-center">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>이름</th>
|
||||||
|
<th>부서</th>
|
||||||
|
<th>직급</th>
|
||||||
|
<th>추가</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="approvalSearchResult">
|
||||||
|
<!-- 검색 결과 동적 렌더링 -->
|
||||||
|
<!-- 예시 -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">닫기</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- 사용자 검색 모달 -->
|
<!-- 사용자 검색 모달 -->
|
||||||
<div class="modal fade" id="userSearchModal" tabindex="-1" role="dialog" aria-labelledby="userSearchModalLabel" aria-hidden="true">
|
<div class="modal fade" id="userSearchModal" tabindex="-1" role="dialog" aria-labelledby="userSearchModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-xl" role="document">
|
<div class="modal-dialog modal-xl" role="document">
|
||||||
@ -206,7 +309,7 @@
|
|||||||
<!-- 검색 영역 -->
|
<!-- 검색 영역 -->
|
||||||
<div class="form-inline mb-3">
|
<div class="form-inline mb-3">
|
||||||
<label class="mr-2">이름 검색</label>
|
<label class="mr-2">이름 검색</label>
|
||||||
<input type="text" class="form-control mr-2" id="userSearchKeyword" placeholder="검색어 입력">
|
<input type="text" class="form-control mr-2" auto id="userSearchKeyword" placeholder="검색어 입력" autocomplete="off">
|
||||||
<button type="button" class="btn btn-info btn-sm" onclick="searchUser()">검색</button>
|
<button type="button" class="btn btn-info btn-sm" onclick="searchUser()">검색</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -249,127 +352,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- ./wrapper -->
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
<!-- DataTables & Plugins -->
|
<script th:src="@{/cmn/js/bizTrip/init.js}"></script>
|
||||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
<script th:src="@{/cmn/js/bizTrip/event.js}"></script>
|
||||||
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
<script th:src="@{/cmn/js/bizTrip/service.js}"></script>
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
<script th:src="@{/cmn/js/bizTrip/validation.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>
|
|
||||||
document.querySelector('input[id="startTime"]').addEventListener('click', function() {
|
|
||||||
this.showPicker && this.showPicker(); // 일부 브라우저에서 시간 선택기 강제 실행
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector('input[id="endTime"]').addEventListener('click', function() {
|
|
||||||
this.showPicker && this.showPicker(); // 일부 브라우저에서 시간 선택기 강제 실행
|
|
||||||
});
|
|
||||||
document.querySelector('input[id="tripDate"]').addEventListener('click', function() {
|
|
||||||
this.showPicker && this.showPicker(); // 일부 브라우저에서 시간 선택기 강제 실행
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 사용자 목록 로딩 (검색 포함)
|
|
||||||
function loadUserList(keyword = "") {
|
|
||||||
$.ajax({
|
|
||||||
url: '/api/admin/user/search/name'
|
|
||||||
,type: 'GET'
|
|
||||||
,data: { userName: keyword }
|
|
||||||
,success: function (resutl) {
|
|
||||||
console.log(' + loadUserList resutl : ', resutl);
|
|
||||||
const tbody = document.getElementById("userSearchResult");
|
|
||||||
tbody.innerHTML = ""; // 초기화
|
|
||||||
|
|
||||||
var data = resutl.data;
|
|
||||||
if (data && data.length > 0) {
|
|
||||||
data.forEach(user => {
|
|
||||||
const row = document.createElement("tr");
|
|
||||||
row.innerHTML = `
|
|
||||||
<td>${user.userName}</td>
|
|
||||||
<td>${user.deptNm || "-"}</td>
|
|
||||||
<td>${user.userRank || "-"}</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-sm btn-success" onclick="selectUser('${user.userName}', '${user.deptNm}', '${user.mobilePhone}')">
|
|
||||||
<i class="fas fa-user-plus"></i> 추가
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
tbody.appendChild(row);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
tbody.innerHTML = `<tr><td colspan="5" class="text-center text-muted">검색 결과가 없습니다.</td></tr>`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function () {
|
|
||||||
alert("사용자 목록을 불러오는 데 실패했습니다.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 모달 열릴 때 사용자 목록 자동 로드
|
|
||||||
$('#userSearchModal').on('shown.bs.modal', function () {
|
|
||||||
loadUserList(); // 최초 전체 목록 로드
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function selectUser(name, dept, phone) {
|
|
||||||
console.log('phone: ', phone);
|
|
||||||
// 원하는 방식으로 테이블에 사용자 추가
|
|
||||||
const tbody = document.getElementById("tripMemberTbody");
|
|
||||||
|
|
||||||
const newRow = document.createElement("tr");
|
|
||||||
newRow.innerHTML = `
|
|
||||||
<td>${name}</td>
|
|
||||||
<td>${dept}</td>
|
|
||||||
<td>${phone}</td>
|
|
||||||
<td class="text-center">
|
|
||||||
<a href="#" class="btn btn-danger btn-sm" onclick="removeMemberRow(this)">
|
|
||||||
<i class="fas fa-user-minus"></i> 삭제
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
tbody.appendChild(newRow);
|
|
||||||
|
|
||||||
// 모달 닫기
|
|
||||||
$('#userSearchModal').modal('hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 검색 버튼 클릭 시
|
|
||||||
function searchUser() {
|
|
||||||
const keyword = document.getElementById("userSearchKeyword").value.trim();
|
|
||||||
loadUserList(keyword);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 출장 인원 행 삭제 함수
|
|
||||||
function removeMemberRow(el) {
|
|
||||||
if (confirm("정말 삭제하시겠습니까?")) {
|
|
||||||
const row = el.closest("tr");
|
|
||||||
if (row) {
|
|
||||||
row.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
||||||
@ -161,13 +161,23 @@
|
|||||||
<label for="userId">ID</label>
|
<label for="userId">ID</label>
|
||||||
<input type="text" class="form-control" id="userId" name="userId" readonly>
|
<input type="text" class="form-control" id="userId" name="userId" readonly>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mobilePhone">핸드폰번호</label>
|
||||||
|
<input type="text" class="form-control" id="mobilePhone" name="mobilePhone">
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="userName">이름</label>
|
<label for="userName">이름</label>
|
||||||
<input type="text" class="form-control" id="userName" name="userName">
|
<input type="text" class="form-control" id="userName" name="userName">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="userRank">직급</label>
|
<label for="rankCd">직급</label>
|
||||||
<input type="text" class="form-control" id="userRank" name="userRank" placeholder="직급을 입력해 주세요.">
|
<select class="form-control" id="rankCd" name="rankCd">
|
||||||
|
<option value="" th:selected>-- 선택 --</option>
|
||||||
|
<option th:each="code : ${@TCodeUtils.getCodeList('RANK')}"
|
||||||
|
th:value="${code.codeId}"
|
||||||
|
th:text="${code.codeName}">
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="deptCd">부서명</label>
|
<label for="deptCd">부서명</label>
|
||||||
@ -328,8 +338,9 @@
|
|||||||
var modalId = '#editUserInfoModal';
|
var modalId = '#editUserInfoModal';
|
||||||
$(modalId+' #uniqId').val(dataInfo.uniqId);
|
$(modalId+' #uniqId').val(dataInfo.uniqId);
|
||||||
$(modalId+' #userId').val(dataInfo.userId);
|
$(modalId+' #userId').val(dataInfo.userId);
|
||||||
$(modalId+' #userName').val(dataInfo.username);
|
$(modalId+' #userName').val(dataInfo.userName);
|
||||||
$(modalId+' #userRank').val(dataInfo.userRank);
|
$(modalId+' #mobilePhone').val(dataInfo.mobilePhone);
|
||||||
|
$(modalId+' #rankCd').val(dataInfo.rankCd);
|
||||||
$(modalId+' #deptCd').val(dataInfo.deptCd);
|
$(modalId+' #deptCd').val(dataInfo.deptCd);
|
||||||
$(modalId+' #hireDate').val(dataInfo.hireDate);
|
$(modalId+' #hireDate').val(dataInfo.hireDate);
|
||||||
$(modalId+' #resignDate').val(dataInfo.resignDate);
|
$(modalId+' #resignDate').val(dataInfo.resignDate);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user