Compare commits
32 Commits
d6989887a5
...
8f1cfd02b3
| Author | SHA1 | Date |
|---|---|---|
|
|
8f1cfd02b3 | 3 weeks ago |
|
|
93680c1a4e | 3 weeks ago |
|
|
b9ef394ec0 | 3 weeks ago |
|
|
b02ebfebab | 3 weeks ago |
|
|
d8bbc6ad94 | 3 weeks ago |
|
|
a67c5f17df | 3 weeks ago |
|
|
dd8536c609 | 3 weeks ago |
|
|
67c2d6b2d2 | 3 weeks ago |
|
|
9a4df669bf | 3 weeks ago |
|
|
9b2bcaa009 | 3 weeks ago |
|
|
e283a23656 | 3 weeks ago |
|
|
243e0f01e9 | 3 weeks ago |
|
|
b5aa1fcc3f | 3 weeks ago |
|
|
d05e9df28a | 3 weeks ago |
|
|
f059994e8d | 3 weeks ago |
|
|
8e5aedd20d | 3 weeks ago |
|
|
6d7b1a3d01 | 3 weeks ago |
|
|
a1b44b7116 | 3 weeks ago |
|
|
d14ee189b5 | 3 weeks ago |
|
|
b0695b34f3 | 3 weeks ago |
|
|
a0e73e0830 | 3 weeks ago |
|
|
0df29c1e50 | 3 weeks ago |
|
|
a585f27b37 | 3 weeks ago |
|
|
46a7008155 | 4 weeks ago |
|
|
3758117293 | 4 weeks ago |
|
|
d7cbecc2a3 | 1 month ago |
|
|
ff24ec3a52 | 1 month ago |
|
|
b0c4918476 | 1 month ago |
|
|
e985be10bb | 1 month ago |
|
|
09b6b2953a | 2 months ago |
|
|
8a88e7c128 | 2 months ago |
|
|
6d006ec6b9 | 2 months ago |
@ -0,0 +1,53 @@
|
|||||||
|
package go.kr.project.biz.common.controller;
|
||||||
|
|
||||||
|
import go.kr.project.biz.common.dto.CommonDto;
|
||||||
|
import go.kr.project.biz.common.service.CommonService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CommonContorller {
|
||||||
|
|
||||||
|
private final CommonService commonService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 위반항목, 법정동, 미부과사유 코드 조회
|
||||||
|
*/
|
||||||
|
@GetMapping("/common/code/find.ajax")
|
||||||
|
public ResponseEntity<?> getCode(@ModelAttribute CommonDto.Request commonDto) {
|
||||||
|
|
||||||
|
CommonDto.Response.CodeResult result = commonService.findCode(commonDto);
|
||||||
|
|
||||||
|
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 차적조회
|
||||||
|
*/
|
||||||
|
@GetMapping("/common/car/info/find.ajax")
|
||||||
|
public ResponseEntity<?> findCarInfo() {
|
||||||
|
|
||||||
|
return ResponseEntity.ok("aaa");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 표지조회
|
||||||
|
*/
|
||||||
|
@GetMapping("/cover/info/find.ajax")
|
||||||
|
public ResponseEntity<?> findCoverInfo() {
|
||||||
|
|
||||||
|
return ResponseEntity.ok("aaa");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package go.kr.project.biz.common.dto;
|
||||||
|
|
||||||
|
import go.kr.project.vo.CpBdongVO;
|
||||||
|
import go.kr.project.vo.CpCancelAnswerVO;
|
||||||
|
import go.kr.project.vo.CpViolationVO;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CommonDto {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class Request {
|
||||||
|
|
||||||
|
private String sggCode;
|
||||||
|
private String jobGroup;
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static class Response {
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public static class CodeResult {
|
||||||
|
private List<CpViolationVO> cpViolation;
|
||||||
|
private List<CpBdongVO> cpBdong;
|
||||||
|
private List<CpCancelAnswerVO> cpCancelAnswer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
package go.kr.project.biz.common.repository;
|
||||||
|
|
||||||
|
import com.querydsl.core.types.Projections;
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
|
import go.kr.project.biz.common.dto.CommonDto;
|
||||||
|
import go.kr.project.domain.entity.CpBdong;
|
||||||
|
import go.kr.project.domain.entity.CpViolation;
|
||||||
|
import go.kr.project.vo.CpBdongVO;
|
||||||
|
import go.kr.project.vo.CpCancelAnswerVO;
|
||||||
|
import go.kr.project.vo.CpViolationVO;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static go.kr.project.domain.entity.QCpBdong.cpBdong;
|
||||||
|
import static go.kr.project.domain.entity.QCpCancelAnswer.cpCancelAnswer;
|
||||||
|
import static go.kr.project.domain.entity.QCpViolation.cpViolation;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CommonRepository {
|
||||||
|
|
||||||
|
|
||||||
|
private final JPAQueryFactory queryFactory;
|
||||||
|
|
||||||
|
|
||||||
|
public List<CpViolationVO> findViolationCode(CommonDto.Request commonDto) {
|
||||||
|
|
||||||
|
commonDto.setSggCode("41590");
|
||||||
|
commonDto.setJobGroup("1");
|
||||||
|
|
||||||
|
List<CpViolationVO> result = queryFactory
|
||||||
|
.select(
|
||||||
|
Projections.fields(
|
||||||
|
CpViolationVO.class,
|
||||||
|
cpViolation.id.vlCode,
|
||||||
|
cpViolation.id.vlJobgroup,
|
||||||
|
cpViolation.id.vlSggcode,
|
||||||
|
cpViolation.vlId,
|
||||||
|
cpViolation.vlAnswer,
|
||||||
|
cpViolation.vlEnable,
|
||||||
|
cpViolation.vlKeum,
|
||||||
|
cpViolation.vlLaw1,
|
||||||
|
cpViolation.vlLaw2,
|
||||||
|
cpViolation.vlLaw3,
|
||||||
|
cpViolation.vlSemok1,
|
||||||
|
cpViolation.vlSemok2,
|
||||||
|
cpViolation.vlSemok3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(cpViolation)
|
||||||
|
.where(
|
||||||
|
cpViolation.id.vlJobgroup.eq(commonDto.getJobGroup()),
|
||||||
|
cpViolation.id.vlSggcode.eq(commonDto.getSggCode())
|
||||||
|
)
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CpBdongVO> findBdongCode() {
|
||||||
|
List<CpBdongVO> result = queryFactory
|
||||||
|
.select(
|
||||||
|
Projections.fields(
|
||||||
|
CpBdongVO.class,
|
||||||
|
cpBdong.bdCode,
|
||||||
|
cpBdong.bdDongName,
|
||||||
|
cpBdong.bdSggName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(cpBdong)
|
||||||
|
.where(cpBdong.bdEnable.eq("1"))
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CpCancelAnswerVO> findCancelAnswerCode(CommonDto.Request commonDto) {
|
||||||
|
|
||||||
|
commonDto.setSggCode("41590");
|
||||||
|
|
||||||
|
List<CpCancelAnswerVO> result = queryFactory
|
||||||
|
.select(
|
||||||
|
Projections.fields(
|
||||||
|
CpCancelAnswerVO.class,
|
||||||
|
cpCancelAnswer.id.caSggCode,
|
||||||
|
cpCancelAnswer.id.caCode,
|
||||||
|
cpCancelAnswer.caId,
|
||||||
|
cpCancelAnswer.caAnswerText,
|
||||||
|
cpCancelAnswer.caIsAnswer
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(cpCancelAnswer)
|
||||||
|
.where(cpCancelAnswer.id.caSggCode.eq(commonDto.getSggCode()))
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package go.kr.project.biz.common.service;
|
||||||
|
|
||||||
|
import go.kr.project.biz.common.dto.CommonDto;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface CommonService {
|
||||||
|
CommonDto.Response.CodeResult findCode(CommonDto.Request commonDto);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package go.kr.project.biz.common.service.impl;
|
||||||
|
|
||||||
|
import go.kr.project.biz.common.dto.CommonDto;
|
||||||
|
import go.kr.project.biz.common.repository.CommonRepository;
|
||||||
|
import go.kr.project.biz.common.service.CommonService;
|
||||||
|
import go.kr.project.vo.mapper.EntityVoMapper;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CommonServiceImpl implements CommonService {
|
||||||
|
|
||||||
|
private final EntityVoMapper mapper;
|
||||||
|
private final CommonRepository commonRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonDto.Response.CodeResult findCode(CommonDto.Request commonDto) {
|
||||||
|
|
||||||
|
return CommonDto.Response.CodeResult.builder()
|
||||||
|
.cpViolation(commonRepository.findViolationCode(commonDto))
|
||||||
|
.cpBdong(commonRepository.findBdongCode())
|
||||||
|
.cpCancelAnswer(commonRepository.findCancelAnswerCode(commonDto))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
package go.kr.project.biz.minwon.indivreg.controller;
|
||||||
|
|
||||||
|
import egovframework.constant.TilesConstants;
|
||||||
|
import egovframework.util.ApiResponseUtil;
|
||||||
|
import go.kr.project.biz.minwon.indivreg.dto.IndivRegDto;
|
||||||
|
import go.kr.project.biz.minwon.indivreg.service.IndivRegService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
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.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Controller
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class IndivRegController {
|
||||||
|
|
||||||
|
// 생성자 인젝션
|
||||||
|
private final IndivRegService indivRegService;
|
||||||
|
|
||||||
|
@GetMapping("/minwon/indivreg/indivreg.do")
|
||||||
|
public String pageReturnIndivReg() {
|
||||||
|
return "biz/minwon/indivreg/indivreg" + TilesConstants.BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/minwon/indivreg/indivreg-search-myBatis.ajax")
|
||||||
|
public ResponseEntity<?> openIndivRegList(@ModelAttribute IndivRegDto.Request.Search dto) {
|
||||||
|
|
||||||
|
int totalCount = 0;
|
||||||
|
dto.setTotalCount(totalCount);
|
||||||
|
|
||||||
|
// 페이징 처리를 위한 설정
|
||||||
|
dto.setPagingYn("Y");
|
||||||
|
|
||||||
|
List<IndivRegDto.Response.cpSeallOne> result = indivRegService.searchIndivRegMybatis(dto);
|
||||||
|
|
||||||
|
return ApiResponseUtil.successWithGrid(result, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/minwon/indivreg/indivregform.do")
|
||||||
|
public String openIndivRegForm(Model model) {
|
||||||
|
// 등록 폼에 필요한 초기 데이터가 있다면 여기서 설정
|
||||||
|
model.addAttribute("indivreg", new IndivRegDto());
|
||||||
|
|
||||||
|
return "biz/minwon/indivreg/indivregform" + TilesConstants.BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/minwon/indivreg/indivreginsert.ajax")
|
||||||
|
@ResponseBody
|
||||||
|
public ResponseEntity<?> insertIndivReg(@RequestBody IndivRegDto.Request.InsertData dto) {
|
||||||
|
try {
|
||||||
|
log.info("등록 요청: {}", dto);
|
||||||
|
|
||||||
|
indivRegService.insertIndivReg(dto);
|
||||||
|
|
||||||
|
return ResponseEntity.ok(
|
||||||
|
Collections.singletonMap("result", "succeses")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ResponseEntity
|
||||||
|
.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
.body(Collections.singletonMap("result", "fail"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package go.kr.project.biz.minwon.indivreg.dto;
|
||||||
|
|
||||||
|
import go.kr.project.system.common.model.PagingVO;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class IndivRegDto {
|
||||||
|
|
||||||
|
// 요즘 트렌드에 맞춰 이너클래스를 사용한다.
|
||||||
|
// Request(파라미터를 받을 형식 객체) 와 Response(응답해줄 형식 객체)로 나눠서 관리한다.
|
||||||
|
|
||||||
|
// 프론트에서 파라미터 받아오는 객체
|
||||||
|
public static class Request {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class Search extends PagingVO {
|
||||||
|
|
||||||
|
private String searchCondition;
|
||||||
|
private String searchKeyword;
|
||||||
|
private String searchUseYn;
|
||||||
|
private String fromDt;
|
||||||
|
private String toDt;
|
||||||
|
private String worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class InsertData {
|
||||||
|
|
||||||
|
private String soSggcode; // 시군구 코드
|
||||||
|
private String soInGb; // 등록구분
|
||||||
|
private String soInDt; // 입력일자
|
||||||
|
private String soJsdate; // 접수일자
|
||||||
|
private String soBbsNo; // 목록번호
|
||||||
|
private String soState; // 상태
|
||||||
|
private Integer soUser; // 사용자 코드
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 디비 조회해서 프론트로 반납해주는 객체
|
||||||
|
public static class Response {
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class cpSeallOne {
|
||||||
|
private String soSggcode ;
|
||||||
|
private String soInDt;
|
||||||
|
private String soInGb;
|
||||||
|
private String soJsdate;
|
||||||
|
private String soBbsNo;
|
||||||
|
private String soMmcode;
|
||||||
|
private String soState;
|
||||||
|
private Integer soUser;
|
||||||
|
private String soPutDt;
|
||||||
|
private String umName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package go.kr.project.biz.minwon.indivreg.mapper;
|
||||||
|
|
||||||
|
import go.kr.project.biz.minwon.indivreg.dto.IndivRegDto;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface IndivRegMapper {
|
||||||
|
|
||||||
|
// SQL문이 있는 xml과 연결 해줌
|
||||||
|
// 해당 메서드가 호출되면 sql문이 나감
|
||||||
|
List<IndivRegDto.Response.cpSeallOne> selectAllIndivReg(IndivRegDto.Request.Search searchDto);
|
||||||
|
|
||||||
|
void insertIndivReg(IndivRegDto.Request.InsertData dto);
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package go.kr.project.biz.minwon.indivreg.service;
|
||||||
|
|
||||||
|
import go.kr.project.biz.minwon.indivreg.dto.IndivRegDto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
// 실제 로직을 이어주는 인터페이스
|
||||||
|
// 해당 인터페이스를 정의하면 반드시 implements를 통해 구현을 해야한다.
|
||||||
|
// eGov 에서 필수라 사용할 뿐
|
||||||
|
public interface IndivRegService {
|
||||||
|
|
||||||
|
// 해당 인터페이스에 정의한 메소드는 반드시 impl로 구현해야함.
|
||||||
|
List<IndivRegDto.Response.cpSeallOne> searchIndivRegMybatis(IndivRegDto.Request.Search dto);
|
||||||
|
|
||||||
|
void insertIndivReg(IndivRegDto.Request.InsertData dto);
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package go.kr.project.biz.minwon.indivreg.service.impl;
|
||||||
|
|
||||||
|
import go.kr.project.biz.minwon.indivreg.dto.IndivRegDto;
|
||||||
|
import go.kr.project.biz.minwon.indivreg.mapper.IndivRegMapper;
|
||||||
|
import go.kr.project.biz.minwon.indivreg.service.IndivRegService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class IndivRegServiceImpl extends EgovAbstractServiceImpl implements IndivRegService {
|
||||||
|
|
||||||
|
//dao : DataBase Access Object로 디비와 연겷하는 역할은 한다.
|
||||||
|
// 현재 프로젝트에서는 dao역할은 mybatis 매퍼인터페이스로 한다.
|
||||||
|
private final IndivRegMapper indivRegMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IndivRegDto.Response.cpSeallOne> searchIndivRegMybatis(IndivRegDto.Request.Search testDto) {
|
||||||
|
// 매퍼 xml의 resultType을 리턴값으로 받아야한다.
|
||||||
|
List<IndivRegDto.Response.cpSeallOne> result = indivRegMapper.selectAllIndivReg(testDto);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insertIndivReg(IndivRegDto.Request.InsertData dto) {
|
||||||
|
indivRegMapper.insertIndivReg(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package go.kr.project.biz.post.notice.status.controller;
|
||||||
|
|
||||||
|
import egovframework.constant.TilesConstants;
|
||||||
|
import egovframework.util.ApiResponseUtil;
|
||||||
|
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.dto.PreNoticeSendTargetDto;
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.service.PreNoticeSendTargetService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class NoticeStatusController {
|
||||||
|
|
||||||
|
private final PreNoticeSendTargetService preNoticeSendTargetService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 발송/반송 > 고지서 발송현황 목록 페이지
|
||||||
|
* @return 뷰 경로
|
||||||
|
*/
|
||||||
|
@GetMapping("post/notice/status/noticeStatus.do")
|
||||||
|
public String minwonInitView() {
|
||||||
|
|
||||||
|
return "biz/post/notice/status/noticeStatus" + TilesConstants.BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("post/notice/status/noticeStatus.ajax")
|
||||||
|
public ResponseEntity<?> getPreNoticeSendTargetistAjax(@ModelAttribute MinwonInitDto.Request.SearchMinwonInitList dto) {
|
||||||
|
|
||||||
|
// 총 게시물 수 조회
|
||||||
|
int totalCount = 0;
|
||||||
|
dto.setTotalCount(totalCount);
|
||||||
|
|
||||||
|
// 페이징 처리를 위한 설정
|
||||||
|
dto.setPagingYn("N");
|
||||||
|
|
||||||
|
// 리스트 조회
|
||||||
|
// List<PreNoticeSendTargetDto.Response.PreNoticeSendTarget> result = preNoticeSendTargetService.findPreNoticeSendTarget();
|
||||||
|
|
||||||
|
return ApiResponseUtil.successWithGrid(null, dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package go.kr.project.biz.post.notice.status.service;
|
||||||
|
|
||||||
|
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface NoticeStatusService {
|
||||||
|
List<MinwonInitDto.Response.InitAnswers> findPreNoticeSendTarget();
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package go.kr.project.biz.post.notice.status.service.impl;
|
||||||
|
|
||||||
|
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
|
||||||
|
import go.kr.project.biz.post.notice.status.service.NoticeStatusService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class NoticsStatusServiceImpl implements NoticeStatusService {
|
||||||
|
@Override
|
||||||
|
public List<MinwonInitDto.Response.InitAnswers> findPreNoticeSendTarget() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.sendTarget.controller;
|
||||||
|
|
||||||
|
import egovframework.constant.TilesConstants;
|
||||||
|
import egovframework.util.ApiResponseUtil;
|
||||||
|
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.dto.PreNoticeSendTargetDto;
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.service.PreNoticeSendTargetService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PreNoticeSendTargetController {
|
||||||
|
|
||||||
|
private final PreNoticeSendTargetService preNoticeSendTargetService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 발송/반송 > 사전통보 > 사전통보 대상 목록 페이지
|
||||||
|
* @return 뷰 경로
|
||||||
|
*/
|
||||||
|
@GetMapping("post/preNotice/sendTarget/sendTarget.do")
|
||||||
|
public String preNoticeSendTargetView() {
|
||||||
|
|
||||||
|
return "biz/post/preNotice/sendTarget/preNoticeSendTarget" + TilesConstants.BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/post/preNotice/sendTarget/sendTargetList.ajax")
|
||||||
|
public ResponseEntity<?> getPreNoticeSendTargetistAjax(@ModelAttribute PreNoticeSendTargetDto.Request.Search dto) {
|
||||||
|
|
||||||
|
// 총 게시물 수 조회
|
||||||
|
int totalCount = 0;
|
||||||
|
dto.setTotalCount(totalCount);
|
||||||
|
|
||||||
|
// 페이징 처리를 위한 설정
|
||||||
|
dto.setPagingYn("N");
|
||||||
|
|
||||||
|
// 리스트 조회
|
||||||
|
List<PreNoticeSendTargetDto.Response.PreNoticeSendTarget> result = preNoticeSendTargetService.findPreNoticeSendTarget(dto);
|
||||||
|
|
||||||
|
return ApiResponseUtil.successWithGrid(result, dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.sendTarget.dto;
|
||||||
|
|
||||||
|
import go.kr.project.domain.entity.CpAnswer;
|
||||||
|
import go.kr.project.domain.entity.CpMain;
|
||||||
|
import go.kr.project.domain.entity.CpOwner;
|
||||||
|
import go.kr.project.system.common.model.PagingVO;
|
||||||
|
import go.kr.project.vo.CpAnswerVO;
|
||||||
|
import go.kr.project.vo.CpMainVO;
|
||||||
|
import go.kr.project.vo.CpOwnerVO;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class PreNoticeSendTargetDto {
|
||||||
|
|
||||||
|
public static class Request {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class Search extends PagingVO {
|
||||||
|
private String mmSggcode;
|
||||||
|
private String searchLawgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Response {
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class PreNoticeSendTargetEntities{
|
||||||
|
private CpMain cpMain;
|
||||||
|
private CpAnswer cpAnswer;
|
||||||
|
private CpOwner cpOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public static class PreNoticeSendTarget {
|
||||||
|
private CpMainVO cpMain;
|
||||||
|
private CpAnswerVO cpAnswer;
|
||||||
|
private CpOwnerVO cpOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.sendTarget.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PreNoticeSendTargetMapper {
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.sendTarget.repository;
|
||||||
|
|
||||||
|
import com.querydsl.core.types.Projections;
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.dto.PreNoticeSendTargetDto;
|
||||||
|
import go.kr.project.vo.code.MmStateEnum;
|
||||||
|
import go.kr.project.vo.mapper.EntityVoMapper;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static go.kr.project.domain.entity.QCpAnswer.cpAnswer;
|
||||||
|
import static go.kr.project.domain.entity.QCpMain.cpMain;
|
||||||
|
import static go.kr.project.domain.entity.QCpOwner.cpOwner;
|
||||||
|
import static go.kr.project.domain.entity.QCpUser.cpUser;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PreNoticeSendTargetQueryDslRepository {
|
||||||
|
|
||||||
|
private final JPAQueryFactory queryFactory;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<PreNoticeSendTargetDto.Response.PreNoticeSendTargetEntities> findPreNoticeSendTarget(PreNoticeSendTargetDto.Request.Search dto) {
|
||||||
|
|
||||||
|
|
||||||
|
List<PreNoticeSendTargetDto.Response.PreNoticeSendTargetEntities> result = queryFactory
|
||||||
|
.select(
|
||||||
|
Projections.fields(
|
||||||
|
PreNoticeSendTargetDto.Response.PreNoticeSendTargetEntities.class,
|
||||||
|
cpMain,
|
||||||
|
cpAnswer,
|
||||||
|
cpOwner
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(cpMain)
|
||||||
|
.leftJoin(cpAnswer).on(cpMain.mmCode.eq(cpAnswer.asMmcode))
|
||||||
|
.leftJoin(cpUser).on(cpAnswer.asReuser.eq(cpUser.umCode))
|
||||||
|
.leftJoin(cpOwner).on(cpMain.mmOmcode.eq(cpOwner.omCode))
|
||||||
|
.where(
|
||||||
|
// cpMain.mmSggcode.eq(dto.getMmSggcode()),
|
||||||
|
cpMain.mmState.eq(MmStateEnum.VEHICLE_CHECKED.getCode()),
|
||||||
|
cpAnswer.asState.ne("0").or(cpAnswer.asState.isNull()),
|
||||||
|
cpMain.mmLawgb.eq(dto.getSearchLawgb())
|
||||||
|
)
|
||||||
|
.orderBy(cpMain.mmCarno.asc(), cpMain.mmDate.asc(), cpMain.mmTime.asc())
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.sendTarget.service;
|
||||||
|
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.dto.PreNoticeSendTargetDto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface PreNoticeSendTargetService {
|
||||||
|
List<PreNoticeSendTargetDto.Response.PreNoticeSendTarget> findPreNoticeSendTarget(PreNoticeSendTargetDto.Request.Search dto);
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.sendTarget.service.impl;
|
||||||
|
|
||||||
|
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.dto.PreNoticeSendTargetDto;
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.repository.PreNoticeSendTargetQueryDslRepository;
|
||||||
|
import go.kr.project.biz.post.preNotice.sendTarget.service.PreNoticeSendTargetService;
|
||||||
|
import go.kr.project.vo.mapper.EntityVoMapper;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PreNoticeSendTargetServiceImpl implements PreNoticeSendTargetService {
|
||||||
|
|
||||||
|
private final EntityVoMapper mapper;
|
||||||
|
private final PreNoticeSendTargetQueryDslRepository preNoticeSendTargetQueryDslRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PreNoticeSendTargetDto.Response.PreNoticeSendTarget> findPreNoticeSendTarget(PreNoticeSendTargetDto.Request.Search dto) {
|
||||||
|
|
||||||
|
List<PreNoticeSendTargetDto.Response.PreNoticeSendTargetEntities> list = preNoticeSendTargetQueryDslRepository.findPreNoticeSendTarget(dto);
|
||||||
|
|
||||||
|
List<PreNoticeSendTargetDto.Response.PreNoticeSendTarget> result =
|
||||||
|
list.stream().map(e ->
|
||||||
|
PreNoticeSendTargetDto.Response.PreNoticeSendTarget.builder()
|
||||||
|
.cpMain(mapper.toCpMainVO(e.getCpMain()))
|
||||||
|
.cpAnswer(mapper.toCpAnswerVO(e.getCpAnswer()))
|
||||||
|
.cpOwner(mapper.toCpOwnerVO(e.getCpOwner()))
|
||||||
|
.build()
|
||||||
|
).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.status.controller;
|
||||||
|
|
||||||
|
import egovframework.constant.TilesConstants;
|
||||||
|
import egovframework.util.ApiResponseUtil;
|
||||||
|
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
|
||||||
|
import go.kr.project.biz.post.preNotice.status.service.StatusService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class StatusController {
|
||||||
|
|
||||||
|
private final StatusService statusService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 발송/반송 > 사전통보 > 사전통보 현황 목록 페이지
|
||||||
|
* @return 뷰 경로
|
||||||
|
*/
|
||||||
|
@GetMapping("/post/preNotice/status/status.do")
|
||||||
|
public String minwonInitView() {
|
||||||
|
|
||||||
|
return "preNoticeStatus" + TilesConstants.BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("post/preNotice/status/status.ajax")
|
||||||
|
public ResponseEntity<?> getPreNoticeStatusListAjax(@ModelAttribute MinwonInitDto.Request.SearchMinwonInitList dto) {
|
||||||
|
|
||||||
|
// 총 게시물 수 조회
|
||||||
|
int totalCount = 0;
|
||||||
|
dto.setTotalCount(totalCount);
|
||||||
|
|
||||||
|
// 페이징 처리를 위한 설정
|
||||||
|
dto.setPagingYn("N");
|
||||||
|
|
||||||
|
// 리스트 조회
|
||||||
|
List<MinwonInitDto.Response.InitAnswers> result = statusService.findPreNoticeStatus();
|
||||||
|
|
||||||
|
return ApiResponseUtil.successWithGrid(result, dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.status.service;
|
||||||
|
|
||||||
|
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface StatusService {
|
||||||
|
|
||||||
|
List<MinwonInitDto.Response.InitAnswers> findPreNoticeStatus();
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package go.kr.project.biz.post.preNotice.status.service.impl;
|
||||||
|
|
||||||
|
import go.kr.project.biz.minwon.init.dto.MinwonInitDto;
|
||||||
|
import go.kr.project.biz.post.preNotice.status.service.StatusService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class StatusServiceImpl implements StatusService {
|
||||||
|
@Override
|
||||||
|
public List<MinwonInitDto.Response.InitAnswers> findPreNoticeStatus() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
package go.kr.project.biz.search.caution.controller;
|
||||||
|
|
||||||
|
import egovframework.constant.TilesConstants;
|
||||||
|
import egovframework.util.ApiResponseUtil;
|
||||||
|
import go.kr.project.biz.search.caution.model.CautionDto;
|
||||||
|
import go.kr.project.biz.search.caution.service.CautionService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CautionController {
|
||||||
|
|
||||||
|
private final CautionService cautionService;
|
||||||
|
|
||||||
|
@GetMapping("/search/caution/caution.do")
|
||||||
|
public String cautionPageReturn() {
|
||||||
|
return "biz/search/caution" + TilesConstants.BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/search/caution/caution-select.ajax")
|
||||||
|
public ResponseEntity<?> list(@ModelAttribute CautionDto.Request.Search dto) {
|
||||||
|
|
||||||
|
dto.setTotalCount(0);
|
||||||
|
dto.setPagingYn("N");
|
||||||
|
|
||||||
|
List<?> result = cautionService.selectAllSearch(dto);
|
||||||
|
|
||||||
|
return ApiResponseUtil.successWithGrid(result, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/search/caution/caution-hwp-download.do")
|
||||||
|
public void downloadCautionHwp(@ModelAttribute CautionDto.Request.Search dto,
|
||||||
|
HttpServletResponse response) throws Exception {
|
||||||
|
|
||||||
|
byte[] fileBytes = cautionService.generateCautionStatsHwp(dto);
|
||||||
|
|
||||||
|
String fileName = "경고통계_" + LocalDate.now() + ".hwp";
|
||||||
|
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())
|
||||||
|
.replaceAll("\\+", "%20");
|
||||||
|
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
response.setHeader("Content-Disposition",
|
||||||
|
"attachment; filename=\"" + encodedFileName + "\";");
|
||||||
|
response.setContentLength(fileBytes.length);
|
||||||
|
|
||||||
|
response.getOutputStream().write(fileBytes);
|
||||||
|
response.getOutputStream().flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package go.kr.project.biz.search.caution.mapper;
|
||||||
|
|
||||||
|
import go.kr.project.biz.search.caution.model.CautionDto;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface CautionMapper {
|
||||||
|
|
||||||
|
// List<CautionDto.Response.cpMain> selectAllSearch(CautionDto.Request.Search dto);
|
||||||
|
|
||||||
|
|
||||||
|
List<CautionDto.Response.YearStats> selectYearStats(CautionDto.Request.Search dto);
|
||||||
|
|
||||||
|
List<CautionDto.Response.DeviceStats> selectDeviceStats(CautionDto.Request.Search dto);
|
||||||
|
|
||||||
|
List<CautionDto.Response.TypeStats> selectTypeStats(CautionDto.Request.Search dto);
|
||||||
|
|
||||||
|
List<CautionDto.Response.DetailStats> selectDetailStats(CautionDto.Request.Search dto);
|
||||||
|
}
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
package go.kr.project.biz.search.caution.model;
|
||||||
|
|
||||||
|
import go.kr.project.system.common.model.PagingVO;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CautionDto {
|
||||||
|
public static class Request {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class Search extends PagingVO {
|
||||||
|
|
||||||
|
|
||||||
|
private String gridId;
|
||||||
|
|
||||||
|
private String searchStartDt;
|
||||||
|
private String searchEndDt;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class Response {
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class cpMain {
|
||||||
|
|
||||||
|
private String mmIngb;
|
||||||
|
private String mmDate;
|
||||||
|
private String mmCarno;
|
||||||
|
private String omJno;
|
||||||
|
private String omName;
|
||||||
|
private String mmKeum2;
|
||||||
|
private String mmImageGb;
|
||||||
|
private String mmImageCnt;
|
||||||
|
private String mmCarcheck;
|
||||||
|
private String mmState;
|
||||||
|
private String mmCode;
|
||||||
|
private String asUser;
|
||||||
|
private String asJsno;
|
||||||
|
private String asJsdate;
|
||||||
|
private String asBbsNo;
|
||||||
|
private String ccCause;
|
||||||
|
private String ccDate;
|
||||||
|
private String ccEtc;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class YearStats {
|
||||||
|
private String year;
|
||||||
|
private String insCnt;
|
||||||
|
private String violCnt;
|
||||||
|
private String totalCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class DeviceStats {
|
||||||
|
private String year;
|
||||||
|
private String cctvCnt;
|
||||||
|
private String smgCnt;
|
||||||
|
private String totalCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class TypeStats {
|
||||||
|
private String vlId;
|
||||||
|
private String insCnt;
|
||||||
|
private String violCnt;
|
||||||
|
private String totalCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class DetailStats {
|
||||||
|
private String year;
|
||||||
|
private String instructNormalCnt;
|
||||||
|
private String instructRegistCnt;
|
||||||
|
private String sajunNormalCnt;
|
||||||
|
private String sajunRegistCnt;
|
||||||
|
private String bugwaNormalCnt;
|
||||||
|
private String bugwaRegistCnt;
|
||||||
|
private String dokNormalCnt;
|
||||||
|
private String dokRegistCnt;
|
||||||
|
private String totalCnt;
|
||||||
|
}
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class StatsForHwp {
|
||||||
|
private List<YearStats> yearList;
|
||||||
|
private List<DeviceStats> deviceList;
|
||||||
|
private List<TypeStats> typeList;
|
||||||
|
private List<DetailStats> detailList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package go.kr.project.biz.search.caution.service;
|
||||||
|
|
||||||
|
import go.kr.project.biz.search.caution.model.CautionDto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface CautionService {
|
||||||
|
|
||||||
|
List<?> selectAllSearch(CautionDto.Request.Search dto);
|
||||||
|
|
||||||
|
CautionDto.Response.StatsForHwp getStatsForHwp(CautionDto.Request.Search dto);
|
||||||
|
|
||||||
|
byte[] generateCautionStatsHwp(CautionDto.Request.Search dto) throws Exception;
|
||||||
|
}
|
||||||
@ -0,0 +1,143 @@
|
|||||||
|
package go.kr.project.biz.search.caution.service.impl;
|
||||||
|
|
||||||
|
import go.kr.project.biz.search.caution.mapper.CautionMapper;
|
||||||
|
import go.kr.project.biz.search.caution.model.CautionDto;
|
||||||
|
import go.kr.project.biz.search.caution.service.CautionService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class CautionServiceImpl extends EgovAbstractServiceImpl implements CautionService {
|
||||||
|
|
||||||
|
private final CautionMapper cautionMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<?> selectAllSearch(CautionDto.Request.Search dto) {
|
||||||
|
|
||||||
|
String gridId = dto.getGridId();
|
||||||
|
log.info("selectAllSearch gridId = {}", gridId);
|
||||||
|
|
||||||
|
List<?> list;
|
||||||
|
|
||||||
|
if ("YEAR".equals(gridId)) {
|
||||||
|
list = cautionMapper.selectYearStats(dto);
|
||||||
|
} else if ("DEVICE".equals(gridId)) {
|
||||||
|
list = cautionMapper.selectDeviceStats(dto);
|
||||||
|
} else if ("TYPE".equals(gridId)) {
|
||||||
|
list = cautionMapper.selectTypeStats(dto);
|
||||||
|
} else if ("DETAIL".equals(gridId)) {
|
||||||
|
list = cautionMapper.selectDetailStats(dto);
|
||||||
|
} else {
|
||||||
|
list = Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("gridId={}, resultSize={}", gridId, list.size());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CautionDto.Response.StatsForHwp getStatsForHwp(CautionDto.Request.Search dto) {
|
||||||
|
|
||||||
|
if (dto.getSearchStartDt() != null) {
|
||||||
|
dto.setSearchStartDt(dto.getSearchStartDt().replaceAll("-", ""));
|
||||||
|
}
|
||||||
|
if (dto.getSearchEndDt() != null) {
|
||||||
|
dto.setSearchEndDt(dto.getSearchEndDt().replaceAll("-", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
CautionDto.Response.StatsForHwp stats = new CautionDto.Response.StatsForHwp();
|
||||||
|
|
||||||
|
stats.setYearList( cautionMapper.selectYearStats(dto));
|
||||||
|
stats.setDeviceList( cautionMapper.selectDeviceStats(dto));
|
||||||
|
stats.setTypeList( cautionMapper.selectTypeStats(dto));
|
||||||
|
stats.setDetailList( cautionMapper.selectDetailStats(dto));
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] generateCautionStatsHwp(CautionDto.Request.Search dto) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
|
CautionDto.Response.StatsForHwp stats = getStatsForHwp(dto);
|
||||||
|
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.append("[경고 통계]\n");
|
||||||
|
sb.append("조회기간: ")
|
||||||
|
.append(dto.getSearchStartDt())
|
||||||
|
.append(" ~ ")
|
||||||
|
.append(dto.getSearchEndDt())
|
||||||
|
.append("\n\n");
|
||||||
|
|
||||||
|
sb.append("1. 연도별 경고/과태료/전체\n");
|
||||||
|
if (stats.getYearList() != null) {
|
||||||
|
for (CautionDto.Response.YearStats y : stats.getYearList()) {
|
||||||
|
sb.append(y.getYear()).append("년 경고:")
|
||||||
|
.append(y.getInsCnt())
|
||||||
|
.append(" 과태료:")
|
||||||
|
.append(y.getViolCnt())
|
||||||
|
.append(" 합계:")
|
||||||
|
.append(y.getTotalCnt())
|
||||||
|
.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("\n");
|
||||||
|
|
||||||
|
sb.append("2. 단속장비/안전신문고\n");
|
||||||
|
if (stats.getDeviceList() != null) {
|
||||||
|
for (CautionDto.Response.DeviceStats d : stats.getDeviceList()) {
|
||||||
|
sb.append(d.getYear()).append("년 자동단속기:")
|
||||||
|
.append(d.getCctvCnt())
|
||||||
|
.append(" 안전신문고:")
|
||||||
|
.append(d.getSmgCnt())
|
||||||
|
.append(" 합계:")
|
||||||
|
.append(d.getTotalCnt())
|
||||||
|
.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("\n");
|
||||||
|
|
||||||
|
sb.append("3. 위반유형별 경고/과태료/합계\n");
|
||||||
|
if (stats.getTypeList() != null) {
|
||||||
|
for (CautionDto.Response.TypeStats t : stats.getTypeList()) {
|
||||||
|
sb.append(t.getVlId()).append(" 경고:")
|
||||||
|
.append(t.getInsCnt())
|
||||||
|
.append(" 과태료:")
|
||||||
|
.append(t.getViolCnt())
|
||||||
|
.append(" 합계:")
|
||||||
|
.append(t.getTotalCnt())
|
||||||
|
.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("\n");
|
||||||
|
|
||||||
|
sb.append("4. 단계별(계도/사전/부과/독촉) 합계\n");
|
||||||
|
if (stats.getDetailList() != null) {
|
||||||
|
for (CautionDto.Response.DetailStats d : stats.getDetailList()) {
|
||||||
|
sb.append(d.getYear()).append("년 ")
|
||||||
|
.append("계도(일반/등기): ")
|
||||||
|
.append(d.getInstructNormalCnt()).append("/").append(d.getInstructRegistCnt())
|
||||||
|
.append(" 사전(일반/등기): ")
|
||||||
|
.append(d.getSajunNormalCnt()).append("/").append(d.getSajunRegistCnt())
|
||||||
|
.append(" 부과(일반/등기): ")
|
||||||
|
.append(d.getBugwaNormalCnt()).append("/").append(d.getBugwaRegistCnt())
|
||||||
|
.append(" 독촉(일반/등기): ")
|
||||||
|
.append(d.getDokNormalCnt()).append("/").append(d.getDokRegistCnt())
|
||||||
|
.append(" 합계: ")
|
||||||
|
.append(d.getTotalCnt())
|
||||||
|
.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package go.kr.project.biz.search.filtersearch.controller;
|
||||||
|
|
||||||
|
import egovframework.constant.TilesConstants;
|
||||||
|
import egovframework.util.ApiResponseUtil;
|
||||||
|
import go.kr.project.biz.search.filtersearch.model.FilterSearchDto;
|
||||||
|
import go.kr.project.biz.search.filtersearch.service.FilterSearchService;
|
||||||
|
import go.kr.project.biz.search.model.SearchDto;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class FilterSearchController {
|
||||||
|
|
||||||
|
private final FilterSearchService filterSearchService;
|
||||||
|
|
||||||
|
@GetMapping("/search/filtersearch/filtersearch.do")
|
||||||
|
|
||||||
|
public String searchPageReturn() {
|
||||||
|
return "biz/search/filtersearch" + TilesConstants.BASE;
|
||||||
|
}
|
||||||
|
@PostMapping("/search/filtersearch/filtersearch-select.ajax")
|
||||||
|
public ResponseEntity<?> list(@ModelAttribute FilterSearchDto.Request.Search dto) {
|
||||||
|
|
||||||
|
dto.setTotalCount(0);
|
||||||
|
dto.setPagingYn("N");
|
||||||
|
|
||||||
|
List<FilterSearchDto.Response.cpMain> result = filterSearchService.selectAllSearch(dto);
|
||||||
|
|
||||||
|
return ApiResponseUtil.successWithGrid(result,dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package go.kr.project.biz.search.filtersearch.mapper;
|
||||||
|
|
||||||
|
import go.kr.project.biz.search.filtersearch.model.FilterSearchDto;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface FilterSearchMapper {
|
||||||
|
|
||||||
|
List<FilterSearchDto.Response.cpMain> selectAllSearch(FilterSearchDto.Request.Search dto);
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
package go.kr.project.biz.search.filtersearch.model;
|
||||||
|
|
||||||
|
import go.kr.project.system.common.model.PagingVO;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class FilterSearchDto {
|
||||||
|
public static class Request {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class Search extends PagingVO {
|
||||||
|
|
||||||
|
|
||||||
|
private String searchCondition;
|
||||||
|
private String searchCondition1;
|
||||||
|
private String searchCondition2;
|
||||||
|
private String searchCondition3;
|
||||||
|
private String searchCondition4;
|
||||||
|
private String searchKeyword;
|
||||||
|
private String searchStartDt;
|
||||||
|
private String searchEndDt;
|
||||||
|
private String searchCarno;
|
||||||
|
private String searchName;
|
||||||
|
private String searchJno;
|
||||||
|
private String searchUser;
|
||||||
|
private String searchTel;
|
||||||
|
private String searchBbsno;
|
||||||
|
private String searchPos;
|
||||||
|
private String searchAddr;
|
||||||
|
private String searchTime1;
|
||||||
|
private String searchTime2;
|
||||||
|
private String worker;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class Response {
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class cpMain {
|
||||||
|
|
||||||
|
private String mmIngb;
|
||||||
|
private String mmDate;
|
||||||
|
private String mmCarno;
|
||||||
|
private String omJno;
|
||||||
|
private String omName;
|
||||||
|
private String mmKeum2;
|
||||||
|
private String mmImageGb;
|
||||||
|
private String mmImageCnt;
|
||||||
|
private String mmCarcheck;
|
||||||
|
private String mmState;
|
||||||
|
private String mmCode;
|
||||||
|
private String asUser;
|
||||||
|
private String asJsno;
|
||||||
|
private String asJsdate;
|
||||||
|
private String asBbsNo;
|
||||||
|
private String ccCause;
|
||||||
|
private String ccDate;
|
||||||
|
private String ccEtc;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class Violation {
|
||||||
|
|
||||||
|
private String vlCode;
|
||||||
|
private String vlId;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package go.kr.project.biz.search.filtersearch.service;
|
||||||
|
|
||||||
|
import go.kr.project.biz.search.filtersearch.model.FilterSearchDto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface FilterSearchService {
|
||||||
|
List<FilterSearchDto.Response.cpMain> selectAllSearch(FilterSearchDto.Request.Search dto);
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package go.kr.project.biz.search.filtersearch.service.impl;
|
||||||
|
|
||||||
|
import go.kr.project.biz.search.filtersearch.mapper.FilterSearchMapper;
|
||||||
|
import go.kr.project.biz.search.filtersearch.model.FilterSearchDto;
|
||||||
|
import go.kr.project.biz.search.filtersearch.service.FilterSearchService;
|
||||||
|
import go.kr.project.vo.code.MmIngbEnum;
|
||||||
|
import go.kr.project.vo.code.MmStateEnum;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class FilterSearchServiceImpl extends EgovAbstractServiceImpl implements FilterSearchService {
|
||||||
|
|
||||||
|
private final FilterSearchMapper filterSearchMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FilterSearchDto.Response.cpMain> selectAllSearch(FilterSearchDto.Request.Search dto) {
|
||||||
|
|
||||||
|
List<FilterSearchDto.Response.cpMain> list = filterSearchMapper.selectAllSearch(dto);
|
||||||
|
|
||||||
|
// Enum Desc 변환
|
||||||
|
list.forEach(item -> {
|
||||||
|
item.setMmIngb(MmIngbEnum.getDescByCode(item.getMmIngb()));
|
||||||
|
item.setMmState(MmStateEnum.getDescByCode(item.getMmState()));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dto.getSearchCondition1() != null && !dto.getSearchCondition1().isEmpty()) {
|
||||||
|
MmStateEnum.getCodeByDesc(dto.getSearchCondition1());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package go.kr.project.vo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class CpCancelAnswerVO {
|
||||||
|
|
||||||
|
private String caSggCode;
|
||||||
|
private String caCode;
|
||||||
|
private String caId;
|
||||||
|
private String caIsAnswer;
|
||||||
|
private String caAnswerText;
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
<?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="go.kr.project.biz.minwon.indivreg.mapper.IndivRegMapper">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
매퍼인터페이스의 매소드명과 id가 일치해야 한다.
|
||||||
|
parameterType은 사용할 파라미터,
|
||||||
|
resultType은 쿼리 결과를 반납하는 객체를 넣어준다.
|
||||||
|
아래 보면 이너클래스는 $형태로 들어간다.
|
||||||
|
-->
|
||||||
|
<select id="selectAllIndivReg"
|
||||||
|
parameterType="go.kr.project.biz.minwon.indivreg.dto.IndivRegDto$Request$Search"
|
||||||
|
resultType="go.kr.project.biz.minwon.indivreg.dto.IndivRegDto$Response$cpSeallOne">
|
||||||
|
select *
|
||||||
|
from CP_SEALL_ONE
|
||||||
|
inner join CP_USER on (SO_USER=UM_CODE)
|
||||||
|
WHERE 1=1
|
||||||
|
<if test="searchKeyword != null and searchKeyword != ''">
|
||||||
|
<choose>
|
||||||
|
<when test="searchCondition == 'soJsdate'">
|
||||||
|
AND SO_JSDATE LIKE CONCAT('%', #{searchKeyword}, '%')
|
||||||
|
</when>
|
||||||
|
<when test="searchCondition == 'soBbsNo'">
|
||||||
|
AND SO_BBS_NO LIKE CONCAT('%', #{searchKeyword}, '%')
|
||||||
|
</when>
|
||||||
|
<when test="searchCondition == 'umName'">
|
||||||
|
AND UM_NAME LIKE CONCAT('%', #{searchKeyword}, '%')
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
AND (
|
||||||
|
SO_JSDATE LIKE CONCAT('%', #{searchKeyword}, '%')
|
||||||
|
OR SO_BBS_NO LIKE CONCAT('%', #{searchKeyword}, '%')
|
||||||
|
OR UM_NAME LIKE CONCAT('%', #{searchKeyword}, '%')
|
||||||
|
)
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</if>
|
||||||
|
ORDER BY SO_SGGCODE, SO_JSDATE, SO_BBS_NO
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertIndivReg" parameterType="go.kr.project.biz.minwon.indivreg.dto.IndivRegDto$Request$InsertData">
|
||||||
|
INSERT INTO CP_SEALL_ONE (
|
||||||
|
SO_SGGCODE, SO_IN_GB, SO_IN_DT, SO_JSDATE, SO_BBS_NO, SO_STATE, SO_USER
|
||||||
|
) VALUES (
|
||||||
|
#{soSggcode}, #{soInGb}, #{soInDt}, #{soJsdate}, #{soBbsNo}, #{soState}, #{soUser}, #{soMMcode}, #{soPutDt}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
<?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="go.kr.project.biz.search.caution.mapper.CautionMapper">
|
||||||
|
|
||||||
|
<select id="selectYearStats"
|
||||||
|
parameterType="go.kr.project.biz.search.caution.model.CautionDto$Request$Search"
|
||||||
|
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$YearStats">
|
||||||
|
|
||||||
|
SELECT SUBSTR(mm_date,1,4) AS year,
|
||||||
|
CONCAT(COUNT(NULLIF(CASE WHEN mm_state = '83' THEN '0'
|
||||||
|
WHEN mm_state = '84' THEN '0'
|
||||||
|
ELSE '1' END, '1'))) AS insCnt,
|
||||||
|
CONCAT(COUNT(NULLIF(CASE WHEN mm_state = '83' THEN '0'
|
||||||
|
WHEN mm_state = '84' THEN '0'
|
||||||
|
ELSE '1' END, '0'))) AS violCnt,
|
||||||
|
CONCAT(COUNT(*)) AS totalCnt
|
||||||
|
FROM cp_main
|
||||||
|
WHERE mm_state IN ('21','31','42','51','52','53','54','55','71','72','73','74','75','83','84')
|
||||||
|
AND mm_date BETWEEN REPLACE(#{searchStartDt}, '-', '') AND REPLACE(#{searchEndDt}, '-', '')
|
||||||
|
GROUP BY SUBSTR(mm_date,1,4)
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDeviceStats"
|
||||||
|
parameterType="go.kr.project.biz.search.caution.model.CautionDto$Request$Search"
|
||||||
|
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$DeviceStats">
|
||||||
|
|
||||||
|
SELECT SUBSTR(mm_date,1,4) AS year,
|
||||||
|
CONCAT(COUNT(NULLIF(CASE WHEN mm_dlgb = '0' THEN '0'
|
||||||
|
ELSE '1' END, '1'))) AS cctvCnt,
|
||||||
|
CONCAT(COUNT(NULLIF(CASE WHEN mm_dlgb = '0' THEN '0'
|
||||||
|
ELSE '1' END, '0'))) AS smgCnt,
|
||||||
|
CONCAT(COUNT(*)) AS totalCnt
|
||||||
|
FROM cp_main
|
||||||
|
WHERE 1 = 1
|
||||||
|
AND mm_date BETWEEN REPLACE(#{searchStartDt}, '-', '') AND REPLACE(#{searchEndDt}, '-', '')
|
||||||
|
GROUP BY SUBSTR(mm_date,1,4)
|
||||||
|
</select>
|
||||||
|
<select id="selectTypeStats"
|
||||||
|
parameterType="go.kr.project.biz.search.caution.model.CautionDto$Request$Search"
|
||||||
|
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$TypeStats">
|
||||||
|
|
||||||
|
SELECT vl_id,
|
||||||
|
CONCAT(COUNT(NULLIF(CASE WHEN mm_state = '83' THEN '0'
|
||||||
|
WHEN mm_state = '84' THEN '0'
|
||||||
|
ELSE '1' END, '1'))) AS insCnt,
|
||||||
|
CONCAT(COUNT(NULLIF(CASE WHEN mm_state = '83' THEN '0'
|
||||||
|
WHEN mm_state = '84' THEN '0'
|
||||||
|
ELSE '1' END, '0'))) AS violCnt,
|
||||||
|
CONCAT(COUNT(*)) AS totalCnt
|
||||||
|
FROM cp_main
|
||||||
|
LEFT OUTER JOIN cp_violation
|
||||||
|
ON mm_sggcode = vl_sggcode
|
||||||
|
AND mm_lawgb = vl_code
|
||||||
|
WHERE mm_state IN ('21','31','42','51','52','53','54','55','71','72','73','74','75','83','84')
|
||||||
|
AND mm_date BETWEEN REPLACE(#{searchStartDt}, '-', '') AND REPLACE(#{searchEndDt}, '-', '')
|
||||||
|
GROUP BY mm_lawgb, vl_id
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDetailStats"
|
||||||
|
parameterType="go.kr.project.biz.search.caution.model.CautionDto$Request$Search"
|
||||||
|
resultType="go.kr.project.biz.search.caution.model.CautionDto$Response$DetailStats">
|
||||||
|
|
||||||
|
SELECT SUBSTR(R.REG_YMD,1,4) AS year,
|
||||||
|
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '1' AND R.RECEV_DIV_CD = '0' THEN 1 END)) AS instructNormalCnt,
|
||||||
|
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '1' AND R.RECEV_DIV_CD = '1' THEN 1 END)) AS instructRegistCnt,
|
||||||
|
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '2' AND R.RECEV_DIV_CD = '0' THEN 1 END)) AS sajunNormalCnt,
|
||||||
|
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '2' AND R.RECEV_DIV_CD = '1' THEN 1 END)) AS sajunRegistCnt,
|
||||||
|
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '3' AND R.RECEV_DIV_CD = '0' THEN 1 END)) AS bugwaNormalCnt,
|
||||||
|
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '3' AND R.RECEV_DIV_CD = '1' THEN 1 END)) AS bugwaRegistCnt,
|
||||||
|
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '4' AND R.RECEV_DIV_CD = '0' THEN 1 END)) AS dokNormalCnt,
|
||||||
|
CONCAT(COUNT(CASE WHEN SUBSTR(R.JOB_CD,4,1) = '4' AND R.RECEV_DIV_CD = '1' THEN 1 END)) AS dokRegistCnt,
|
||||||
|
CONCAT(COUNT(*)) AS totalCnt
|
||||||
|
FROM epost_sender_detail D
|
||||||
|
LEFT OUTER JOIN epost_sender_reg R
|
||||||
|
ON D.CON_KEY = R.CON_KEY
|
||||||
|
WHERE R.REG_YMD BETWEEN REPLACE(#{searchStartDt}, '-', '') AND REPLACE(#{searchEndDt}, '-', '')
|
||||||
|
AND R.DELETE_AT <> 'Y'
|
||||||
|
GROUP BY SUBSTR(R.REG_YMD,1,4)
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,126 @@
|
|||||||
|
<?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="go.kr.project.biz.search.filtersearch.mapper.FilterSearchMapper">
|
||||||
|
|
||||||
|
<select id="selectAllSearch"
|
||||||
|
parameterType="go.kr.project.biz.search.filtersearch.model.FilterSearchDto"
|
||||||
|
resultType="go.kr.project.biz.search.filtersearch.model.FilterSearchDto$Response$cpMain">
|
||||||
|
SELECT M.MM_INGB,
|
||||||
|
DATE_FORMAT(
|
||||||
|
STR_TO_DATE(CONCAT(M.MM_DATE, M.MM_TIME), '%Y%m%d%H%i%s'),
|
||||||
|
'%Y-%m-%d %H:%i:%s' ) AS mmDate,
|
||||||
|
M.MM_CARNO,
|
||||||
|
O.OM_JNO,
|
||||||
|
O.OM_NAME,
|
||||||
|
M.MM_KEUM2,
|
||||||
|
M.MM_IMAGEGB,
|
||||||
|
M.MM_IMAGECNT,
|
||||||
|
M.MM_CARCHECK,
|
||||||
|
M.MM_STATE,
|
||||||
|
DATE_FORMAT(A.AS_JSDATE, '%Y-%m-%d') AS AS_JSDATE,
|
||||||
|
A.AS_USER,
|
||||||
|
A.AS_JSNO,
|
||||||
|
A.AS_BBS_NO,
|
||||||
|
C.CC_CAUSE,
|
||||||
|
DATE_FORMAT(C.CC_DATE, '%Y-%m-%d') AS CC_DATE,
|
||||||
|
C.CC_ETC,
|
||||||
|
M.MM_CODE
|
||||||
|
FROM CP_MAIN M
|
||||||
|
LEFT OUTER JOIN CP_ANSWER A ON M.MM_CODE = AS_MMCODE
|
||||||
|
LEFT OUTER JOIN CP_CANCEL C ON M.MM_CODE=CC_MMCODE
|
||||||
|
LEFT OUTER JOIN CP_OWNER O ON M.MM_OMCODE=O.OM_CODE
|
||||||
|
<where>
|
||||||
|
<!-- 날짜 -->
|
||||||
|
<if test="searchStartDt != null and searchStartDt != ''">
|
||||||
|
AND M.MM_DATE >= REPLACE(#{searchStartDt}, '-', '')
|
||||||
|
</if>
|
||||||
|
<if test="searchEndDt != null and searchEndDt != ''">
|
||||||
|
AND M.MM_DATE <= REPLACE(#{searchEndDt}, '-', '')
|
||||||
|
</if>
|
||||||
|
<!-- 시간 -->
|
||||||
|
<if test="searchTime1 != null and searchTime1 != ''">
|
||||||
|
AND M.MM_TIME >= REPLACE(#{searchTime1}, '-', '')
|
||||||
|
</if>
|
||||||
|
<if test="searchTime2 != null and searchTime2 != ''">
|
||||||
|
AND M.MM_TIME <= REPLACE(#{searchTime2}, '-', '')
|
||||||
|
</if>
|
||||||
|
<!-- 위반내용 (searchCondition : code1~6) -->
|
||||||
|
<!-- <if test="searchCondition != null and searchCondition != ''">-->
|
||||||
|
<!-- <!– 코드가없다. –>-->
|
||||||
|
<!-- AND M.VL_CODE = #{searchCondition}-->
|
||||||
|
<!-- </if>-->
|
||||||
|
|
||||||
|
<!-- 처리상태 (searchCondition1 : code1~22) -->
|
||||||
|
<if test="searchCondition1 != null and searchCondition1 != ''">
|
||||||
|
AND M.MM_STATE = #{searchCondition1}
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- 등록구분 -->
|
||||||
|
<if test="searchCondition2 != null and searchCondition2 != ''">
|
||||||
|
AND M.MM_DLGB = #{searchCondition2}
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- 자료출처 -->
|
||||||
|
<if test="searchCondition3 != null and searchCondition3 != ''">
|
||||||
|
AND M.MM_INGB = #{searchCondition3}
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- <!– 법정동 –>-->
|
||||||
|
<!-- <if test="searchCondition4 != null and searchCondition4 != ''">-->
|
||||||
|
<!-- AND M.MM_DONG = #{searchCondition4}-->
|
||||||
|
<!-- </if>-->
|
||||||
|
|
||||||
|
<!-- ===== 텍스트 입력 필드들 (값이 있으면 AND LIKE) ===== -->
|
||||||
|
|
||||||
|
<!-- 차량번호 -->
|
||||||
|
<if test="searchCarno != null and searchCarno != ''">
|
||||||
|
AND M.MM_CARNO LIKE CONCAT('%', #{searchCarno}, '%')
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- 소유자성명 -->
|
||||||
|
<if test="searchName != null and searchName != ''">
|
||||||
|
AND O.OM_NAME LIKE CONCAT('%', #{searchName}, '%')
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- 주민번호 -->
|
||||||
|
<if test="searchJno != null and searchJno != ''">
|
||||||
|
AND O.OM_JNO LIKE CONCAT('%', #{searchJno}, '%')
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- 신고자 -->
|
||||||
|
<if test="searchUser != null and searchUser != ''">
|
||||||
|
AND A.AS_USER LIKE CONCAT('%', #{searchUser}, '%')
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- 신고자 전화번호 -->
|
||||||
|
<if test="searchTel != null and searchTel != ''">
|
||||||
|
AND A.AS_TEL LIKE CONCAT('%', #{searchTel}, '%')
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- 목록번호 -->
|
||||||
|
<if test="searchBbsno != null and searchBbsno != ''">
|
||||||
|
AND A.AS_BBS_NO LIKE CONCAT('%', #{searchBbsno}, '%')
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- <!– 위반장소 –>-->
|
||||||
|
<!-- <if test="searchPos != null and searchPos != ''">-->
|
||||||
|
<!-- AND M.MM_PLACE LIKE CONCAT('%', #{searchPos}, '%')-->
|
||||||
|
<!-- </if>-->
|
||||||
|
|
||||||
|
<!-- 상세주소 (예: O.OM_ADDR) -->
|
||||||
|
<!-- <if test="searchAddr != null and searchAddr != ''">-->
|
||||||
|
<!-- AND O.OM_ADDR LIKE CONCAT('%', #{searchAddr}, '%')-->
|
||||||
|
<!-- </if>-->
|
||||||
|
</where>
|
||||||
|
ORDER BY AS_JSDATE DESC, AS_JSNO DESC
|
||||||
|
</select>
|
||||||
|
<select id="selectViolationList"
|
||||||
|
resultType="go.kr.project.biz.search.filtersearch.model.FilterSearchDto$Response$Violation">
|
||||||
|
SELECT
|
||||||
|
VL_CODE,
|
||||||
|
VL_ID
|
||||||
|
FROM CP_VIOLATION
|
||||||
|
</select>
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,136 @@
|
|||||||
|
<%--
|
||||||
|
Created by IntelliJ IDEA.
|
||||||
|
User: kurt
|
||||||
|
Date: 2025. 11. 28.
|
||||||
|
Time: 오후 1:46
|
||||||
|
To change this template use File | Settings | File Templates.
|
||||||
|
--%>
|
||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="destruction_doc_dialog" style="display:none;">
|
||||||
|
<div class="left">
|
||||||
|
<div class="form-grid">
|
||||||
|
|
||||||
|
<!-- 1줄 -->
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="field-group">
|
||||||
|
<div class="lbl">처리사유</div>
|
||||||
|
<div class="fld">
|
||||||
|
<select name="cpCancelAnswer" id="cpCancelAnswer">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field-group empty"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 2줄 -->
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="field-group">
|
||||||
|
<div class="lbl">처리일자</div>
|
||||||
|
<div class="fld">
|
||||||
|
<input type="text" id="desDate" name="desDate" class="input calender datepicker" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field-group empty"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 3줄 -->
|
||||||
|
<div class="form-row block">
|
||||||
|
<div class="field-group">
|
||||||
|
<div class="lbl">특기사항</div>
|
||||||
|
<div class="fld">
|
||||||
|
<input type="text" name="cpMain" data-field="mmDlgb" id="mmDlgb" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="disdoc-btn-area">
|
||||||
|
<button type="button" class="btn btn-light disdoc-btn" name="" id="dis-doc">미부과처리</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
let fnDesDocFn = {
|
||||||
|
init: () => {
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
updateDestructionDoc: () => {
|
||||||
|
$.ajax({
|
||||||
|
url: "",
|
||||||
|
type: "post",
|
||||||
|
contentType: 'application/json',
|
||||||
|
success: function(response) {
|
||||||
|
|
||||||
|
//다이얼로그 하이드
|
||||||
|
|
||||||
|
|
||||||
|
//네이게이팅 다음으로
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//로컬스토리지 mmCodes에 해당 mmCode 제거
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
$("#result").text("서손처리 실패");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
$("#dis-doc").on("click", () => {
|
||||||
|
fnDesDocFn.updateDestructionDoc();
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
/* 다이얼로그 설정 */
|
||||||
|
$("#destruction_doc_dialog").dialog({
|
||||||
|
autoOpen: false,
|
||||||
|
modal: true,
|
||||||
|
resizable: true,
|
||||||
|
// width: "auto",
|
||||||
|
width: 1000,
|
||||||
|
maxHeight: 800,
|
||||||
|
show: { effect: "drop", direction: "left", duration: 200 },
|
||||||
|
hide: { effect: "drop", direction: "left", duration: 200 },
|
||||||
|
title: "서손처리",
|
||||||
|
open: function () {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 오늘날짜 기본세팅 */
|
||||||
|
$('#desDate').datepicker('setDate', new Date());
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,364 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<!-- Main body -->
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/minwon/indivreg/indivregform.do'/>'" class="newbtn bg1">요청등록</button>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">한건삭제</button>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">전체삭제</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<input type="text" id="bbs_no">
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
<ul class="lef">
|
||||||
|
<li class="th">검색구분</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition" name="searchCondition" class="input">
|
||||||
|
<option value="">검색구분</option>
|
||||||
|
<option value="soJsdate" <c:if test="${paramVO.searchCondition eq 'soJsdate'}">selected</c:if>>접수일자</option>
|
||||||
|
<option value="soBbsNo" <c:if test="${paramVO.searchCondition eq 'soBbsNo'}">selected</c:if>>목록번호</option>
|
||||||
|
<option value="umName" <c:if test="${paramVO.searchCondition eq 'umName'}">selected</c:if>>사용자성명</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">검색어</li>
|
||||||
|
<li><input type="text" id="searchKeyword" name="searchKeyword" class="input" value="${param.searchKeyword}"/></li>
|
||||||
|
<li class="th">담당자지정</li>
|
||||||
|
<li><input type="text" id="worker" name="worker" class="input" value=""/></li>
|
||||||
|
<li class="th">사용여부</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchUseYn" name="searchUseYn" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="Y" <c:if test="${param.searchUseYn eq 'Y'}">selected</c:if>>사용</option>
|
||||||
|
<option value="N" <c:if test="${param.searchUseYn eq 'N'}">selected</c:if>>미사용</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">접수일자 지정</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="20" <c:if test="${param.perPage eq '20'}">selected</c:if>>페이지당 20</option>
|
||||||
|
<option value="30" <c:if test="${param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><sapn id="totalPages"></sapn> Pages</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="gs_booking">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<div id="grid"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Main body -->
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
/**
|
||||||
|
* 게시판 목록 관리 모듈
|
||||||
|
* 게시판 목록을 조회하고 관리하는 기능을 제공합니다.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
(function(window, $) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var SEARCH_COND = {};
|
||||||
|
|
||||||
|
// 검색정보 셋팅
|
||||||
|
var setSearchCond = function() {
|
||||||
|
var searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
|
||||||
|
var searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
|
||||||
|
var searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
|
||||||
|
var searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
var searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
|
||||||
|
SEARCH_COND.searchCondition = searchCondition;
|
||||||
|
SEARCH_COND.searchKeyword = searchKeyword;
|
||||||
|
SEARCH_COND.searchUseYn = searchUseYn;
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 게시판 목록 관리 네임스페이스
|
||||||
|
*/
|
||||||
|
var NoticeList = {
|
||||||
|
/**
|
||||||
|
* 그리드 관련 객체
|
||||||
|
*/
|
||||||
|
grid: {
|
||||||
|
/**
|
||||||
|
* 그리드 인스턴스
|
||||||
|
*/
|
||||||
|
instance: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 그리드 설정 초기화
|
||||||
|
* @returns {Object} 그리드 설정 객체
|
||||||
|
*/
|
||||||
|
initConfig: function() {
|
||||||
|
// 데이터 소스 설정
|
||||||
|
var dataSource = this.createDataSource();
|
||||||
|
|
||||||
|
// 현재 선택된 perPage 값 가져오기
|
||||||
|
var perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
// 그리드 설정 객체 생성
|
||||||
|
var gridConfig = new XitTuiGridConfig();
|
||||||
|
|
||||||
|
// 기본 설정
|
||||||
|
gridConfig.setOptDataSource(dataSource); // 데이터소스 연결
|
||||||
|
gridConfig.setOptGridId('grid'); // 그리드를 출력할 Element ID
|
||||||
|
gridConfig.setOptGridHeight(390); // 그리드 높이(단위: px)
|
||||||
|
gridConfig.setOptRowHeight(30); // 그리드 행 높이(단위: px)
|
||||||
|
gridConfig.setOptRowHeaderType('checkbox'); // 행 첫번째 셀 타입(rowNum: 순번, checkbox: 체크박스, '': 출력 안함)
|
||||||
|
|
||||||
|
// 페이징 옵션 설정
|
||||||
|
gridConfig.setOptPageOptions({
|
||||||
|
useClient: false, // 클라이언트 페이징 여부(false: 서버 페이징)
|
||||||
|
perPage: perPage // 페이지당 표시 건수
|
||||||
|
});
|
||||||
|
gridConfig.setOptUseClientSort(false); // 서버사이드 정렬 false
|
||||||
|
|
||||||
|
// 컬럼 정보 설정
|
||||||
|
gridConfig.setOptColumns([
|
||||||
|
{
|
||||||
|
header: '시군구코드',
|
||||||
|
name: 'soSggcode',
|
||||||
|
width: 70,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '신청일시',
|
||||||
|
name: 'soInDt',
|
||||||
|
width: 70,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '등록구분',
|
||||||
|
name: 'soInGb',
|
||||||
|
width: 50,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '접수일자',
|
||||||
|
name: 'soJsdate',
|
||||||
|
width: 70,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '목록번호',
|
||||||
|
name: 'soBbsNo',
|
||||||
|
width: 70,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '단속ID',
|
||||||
|
name: 'soMmcode',
|
||||||
|
width: 120,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '자료상태',
|
||||||
|
name: 'soState',
|
||||||
|
width: 70,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '등록사용자',
|
||||||
|
name: 'soUser',
|
||||||
|
width: 70,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '등록일시',
|
||||||
|
name: 'soPutDt',
|
||||||
|
width: 70,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '사용자성명',
|
||||||
|
name: 'umName',
|
||||||
|
width: 70,
|
||||||
|
align: 'center'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
return gridConfig;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 데이터 소스 생성
|
||||||
|
* @returns {Object} 데이터 소스 객체
|
||||||
|
*/
|
||||||
|
createDataSource: function() {
|
||||||
|
return {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/minwon/indivreg/indivreg-search-myBatis.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: false,
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 그리드 인스턴스 생성
|
||||||
|
*/
|
||||||
|
create: function() {
|
||||||
|
var gridConfig = this.initConfig();
|
||||||
|
var Grid = tui.Grid;
|
||||||
|
this.instance = gridConfig.instance(Grid);
|
||||||
|
|
||||||
|
// 그리드 테마 설정
|
||||||
|
Grid.applyTheme('striped');
|
||||||
|
|
||||||
|
// 그리드 이벤트 설정
|
||||||
|
this.gridBindEvents();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 그리드 이벤트 바인딩
|
||||||
|
*/
|
||||||
|
gridBindEvents: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// 요청 성공 시 총 건수 표시
|
||||||
|
this.instance.on('successResponse', function(ev) {
|
||||||
|
var responseObj = JSON.parse(ev.xhr.response);
|
||||||
|
//$('.totCnt').text(responseObj.data.pagination.totalCount);
|
||||||
|
$("#currentPage").text(responseObj.data.pagination.page);
|
||||||
|
$("#totalPages").text(responseObj.data.pagination.totalPages);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 행 더블클릭 이벤트 - 게시물 상세 페이지로 이동
|
||||||
|
this.instance.on('dblclick', function(ev) {
|
||||||
|
var popUrl = '${pageContext.request.contextPath}/total/info.do';
|
||||||
|
var popTitle = "비밀번호 변경";
|
||||||
|
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
|
||||||
|
window.open(popUrl, popTitle, popOption);
|
||||||
|
<%--if (ev.rowKey !== undefined && ev.columnName !== '_number') {--%>
|
||||||
|
<%-- var rowData = self.instance.getRow(ev.rowKey);--%>
|
||||||
|
<%-- if (rowData && rowData.noticeId) {--%>
|
||||||
|
<%-- // 새로운 함수를 사용하여 URL 생성 및 페이지 이동--%>
|
||||||
|
<%-- window.location.href = "<c:url value="/minwon/init/init.do"/>";--%>
|
||||||
|
<%-- console.log("asd11`11")--%>
|
||||||
|
<%-- }--%>
|
||||||
|
<%--}--%>
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 이벤트 핸들러 설정
|
||||||
|
*/
|
||||||
|
eventBindEvents: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// 검색 버튼 클릭 이벤트
|
||||||
|
$('#search_btn').on('click', function() {
|
||||||
|
// 등록일 from~to 유효성 검사
|
||||||
|
var startDate = $("#searchStartDt").val();
|
||||||
|
var endDate = $("#searchEndDt").val();
|
||||||
|
|
||||||
|
// 시작일과 종료일 중 하나만 입력된 경우 체크
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일과 종료일이 모두 입력된 경우 유효성 검사
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일이 종료일보다 늦은 경우 체크
|
||||||
|
var startDateObj = new Date(startDate);
|
||||||
|
var endDateObj = new Date(endDate);
|
||||||
|
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지를 1로 리셋
|
||||||
|
$("#page").val(1);
|
||||||
|
// 그리드 데이터 리로드
|
||||||
|
self.grid.instance.readData(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 검색어 입력 필드에서 엔터키 이벤트 처리
|
||||||
|
$('#searchKeyword').on('keypress', function(e) {
|
||||||
|
if (e.which === 13) { // 엔터키 코드는 13
|
||||||
|
e.preventDefault(); // 기본 이벤트 방지
|
||||||
|
$('#search_btn').trigger('click'); // 검색 버튼 클릭 이벤트 트리거
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// perPage 변경 이벤트 추가
|
||||||
|
$('#perPageSelect').on('change', function() {
|
||||||
|
var perPage = parseInt($(this).val(), 10);
|
||||||
|
// Grid의 perPage 설정 변경 및 데이터 리로드
|
||||||
|
self.grid.instance.setPerPage(perPage);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모듈 초기화
|
||||||
|
*/
|
||||||
|
init: function() {
|
||||||
|
|
||||||
|
// 그리드 생성
|
||||||
|
this.grid.create();
|
||||||
|
|
||||||
|
// 이벤트 핸들러 설정
|
||||||
|
this.eventBindEvents();
|
||||||
|
|
||||||
|
this.grid.instance.readData(${param.page eq null or param.page eq 0 ? 1 : param.page});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 페이지 로드 시 초기화
|
||||||
|
$(function() {
|
||||||
|
NoticeList.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 전역 네임스페이스에 모듈 노출
|
||||||
|
window.NoticeList = NoticeList;
|
||||||
|
|
||||||
|
})(window, jQuery);
|
||||||
|
</script>
|
||||||
@ -0,0 +1,124 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<!-- TOAST UI Editor CDN -->
|
||||||
|
<link rel="stylesheet" href="<c:url value="/plugins/tuiEditor/3.2.2/toastui-editor.min.css"/>" />
|
||||||
|
<script src="<c:url value="/plugins/tuiEditor/3.2.2/toastui-editor-all.min.js"/>"></script>
|
||||||
|
<!-- TOAST UI Editor 한국어 지원 -->
|
||||||
|
<script src="<c:url value="/plugins/tuiEditor/3.2.2/i18n/ko-kr.min.js"/>"></script>
|
||||||
|
|
||||||
|
<!-- Main body -->
|
||||||
|
<div class="main_body">
|
||||||
|
<input type="text" id="soJsdate" name="soJsdate" class="input calender datepicker" value="${param.soJsdate}" />
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" id="btnSave" class="newbtn bg4">확인</button>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/minwon/indivreg/indivreg.do'/>'" class="newbtn bg1">목록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="contants_body" >
|
||||||
|
<form id="registerForm" name="registerForm" enctype="multipart/form-data">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="">
|
||||||
|
<div class="forms_table_non">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th class="th"><span class="required">*</span>접수일자</th>
|
||||||
|
<td colspan="3">
|
||||||
|
<input type="text" id="soJsdate" name="soJsdate" class="input calender datepicker" value="${param.soJsdate}" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="th"><span class="required">*</span>목록번호</th>
|
||||||
|
<td colspan="3">
|
||||||
|
<input type="text" id="soBbsNo" name="soBbsNo" class="input" validation-check="required" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Main body -->
|
||||||
|
|
||||||
|
<%--<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>--%>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
search: (formData) => {
|
||||||
|
$.ajax({
|
||||||
|
url: '/minwon/indivreg/indivreginsert.ajax',
|
||||||
|
type: 'POST',
|
||||||
|
contentType: 'application/json; charset=UTF-8',
|
||||||
|
data: JSON.stringify(formData),
|
||||||
|
success: function(res) {
|
||||||
|
alert('등록이 완료되었습니다.');
|
||||||
|
window.close();
|
||||||
|
if (opener &&opener.NoticeList && opener.NoticeList.grid) {
|
||||||
|
opener.NoticeList.grid.instance.readData(1);
|
||||||
|
} else if (opener) {
|
||||||
|
opener.location.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (xhr, status, error) {
|
||||||
|
console.log('등록 실패 응답', xhr.responseText);
|
||||||
|
alert('등록 실패, 다시 시도해주세요.');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
$('#btnSave').on('click', function() {
|
||||||
|
// 1) 현재 일시 생성 (YYYYMMDDHHmmss)
|
||||||
|
var now = new Date();
|
||||||
|
var yyyy = now.getFullYear();
|
||||||
|
var MM = ('0' + (now.getMonth() + 1)).slice(-2);
|
||||||
|
var dd = ('0' + now.getDate()).slice(-2);
|
||||||
|
var HH = ('0' + now.getHours()).slice(-2);
|
||||||
|
var mm = ('0' + now.getMinutes()).slice(-2);
|
||||||
|
var ss = ('0' + now.getSeconds()).slice(-2);
|
||||||
|
var yyyymmddhhmmss = yyyy + MM + dd + HH + mm + ss;
|
||||||
|
|
||||||
|
// 2) 접수일자 yyyy-mm-dd → yyyymmdd 변환
|
||||||
|
var jsd = $('#soJsdate').val(); // 예: "2025-11-19"
|
||||||
|
var jsdFormat = jsd ? jsd.split('-').join('') : ""; // "20251119"
|
||||||
|
|
||||||
|
// 3) 서버로 보낼 데이터
|
||||||
|
var formData = {
|
||||||
|
soSggcode: "41590",
|
||||||
|
soInGb: "1",
|
||||||
|
soInDt: yyyymmddhhmmss,
|
||||||
|
soJsdate: jsdFormat, // ← 여기!
|
||||||
|
soBbsNo: $('#soBbsNo').val(),
|
||||||
|
soState: "B",
|
||||||
|
soUser: 20
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('보내는 데이터:', formData); // 디버깅용
|
||||||
|
|
||||||
|
fnBiz.search(formData);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
fnBiz.eventListener();
|
||||||
|
|
||||||
|
$('.datepicker').datepicker({
|
||||||
|
orientation: "top",
|
||||||
|
autoclose: true,
|
||||||
|
language: "ko",
|
||||||
|
format: "yyyy.mm.dd"
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,250 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<!-- Main body -->
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">등록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
<ul class="lef">
|
||||||
|
<li class="th">검색구분</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition" name="searchCondition" class="input">
|
||||||
|
<option value="">검색구분</option>
|
||||||
|
<option value="title" <c:if test="${paramVO.searchCondition eq 'title'}">selected</c:if>>제목</option>
|
||||||
|
<option value="contents" <c:if test="${paramVO.searchCondition eq 'contents'}">selected</c:if>>내용</option>
|
||||||
|
<option value="writer" <c:if test="${paramVO.searchCondition eq 'writer'}">selected</c:if>>수정자명</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">검색어</li>
|
||||||
|
<li><input type="text" id="searchKeyword" name="searchKeyword" class="input" value="${param.searchKeyword}"/></li>
|
||||||
|
<li class="th">담당자지정</li>
|
||||||
|
<li><input type="text" id="worker" name="worker" class="input" value=""/></li>
|
||||||
|
<li class="th">사용여부</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchUseYn" name="searchUseYn" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="Y" <c:if test="${param.searchUseYn eq 'Y'}">selected</c:if>>사용</option>
|
||||||
|
<option value="N" <c:if test="${param.searchUseYn eq 'N'}">selected</c:if>>미사용</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">접수일자 지정</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker bottom" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="30" <c:if test="${empty param.perPage or param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
<option value="100" <c:if test="${param.perPage eq '100'}">selected</c:if>>페이지당 100</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><sapn id="totalPages"></sapn> Pages</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="gs_booking">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<div id="grid"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Main body -->
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
let GRID = null;
|
||||||
|
let INIT_POPUP = null;
|
||||||
|
|
||||||
|
let SEARCH_COND = {};
|
||||||
|
|
||||||
|
let perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
// 검색정보 셋팅
|
||||||
|
let setSearchCond = function() {
|
||||||
|
let searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
|
||||||
|
let searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
|
||||||
|
let searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
|
||||||
|
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
|
||||||
|
SEARCH_COND.searchCondition = searchCondition;
|
||||||
|
SEARCH_COND.searchKeyword = searchKeyword;
|
||||||
|
SEARCH_COND.searchUseYn = searchUseYn;
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
initGrid();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
// 검색 버튼 클릭 이벤트
|
||||||
|
$('#search_btn').on('click', function() {
|
||||||
|
// 등록일 from~to 유효성 검사
|
||||||
|
let startDate = $("#searchStartDt").val();
|
||||||
|
let endDate = $("#searchEndDt").val();
|
||||||
|
|
||||||
|
// 시작일과 종료일 중 하나만 입력된 경우 체크
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일과 종료일이 모두 입력된 경우 유효성 검사
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일이 종료일보다 늦은 경우 체크
|
||||||
|
let startDateObj = new Date(startDate);
|
||||||
|
let endDateObj = new Date(endDate);
|
||||||
|
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지를 1로 리셋
|
||||||
|
$("#page").val(1);
|
||||||
|
// 그리드 데이터 리로드
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 검색어 입력 필드에서 엔터키 이벤트 처리
|
||||||
|
$('#searchKeyword').on('keypress', function(e) {
|
||||||
|
if (e.which === 13) { // 엔터키 코드는 13
|
||||||
|
e.preventDefault(); // 기본 이벤트 방지
|
||||||
|
$('#search_btn').trigger('click'); // 검색 버튼 클릭 이벤트 트리거
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// perPage 변경 이벤트 추가
|
||||||
|
$('#perPageSelect').on('change', () => {
|
||||||
|
const pagination = TuiGrid.instance.getPagination();
|
||||||
|
|
||||||
|
GRID.setPerPage($('#perPageSelect').val());
|
||||||
|
pagination.setItemsPerPage($('#perPageSelect').val());
|
||||||
|
pagination.reset(TuiGrid.instance.getRowCount());
|
||||||
|
pagination.movePageTo(1);
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** tui-grid Set */
|
||||||
|
let initGrid = () => {
|
||||||
|
const gridColumns = [
|
||||||
|
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 50,},
|
||||||
|
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 70,},
|
||||||
|
{header: '신고자', name: 'mmSgnm', sortable: true, width: 100,},
|
||||||
|
{header: '담당자', name: 'mmSgtel', sortable: true, width: 100,},
|
||||||
|
{header: '전화번호', name: 'asTel', width: 150,},
|
||||||
|
{header: '접수일자', name: 'asJsdate', sortable: true, width: 70,},
|
||||||
|
{header: '처리기한', name: 'asLimitDt', sortable: true, width: 70,},
|
||||||
|
{header: '위반일자', name: 'mmDate', sortable: true, width: 150,},
|
||||||
|
{header: '첨부', name: 'mmImagegb', width: 150,},
|
||||||
|
{header: '사진갯수', name: 'mmImagecnt', width: 50,},
|
||||||
|
{header: '위반내용', name: 'mmSgcont', width: 250,},
|
||||||
|
{header: '접수번호', name: 'asJsno', sortable: true, width: 150,},
|
||||||
|
{header: '차량번호', name: 'mmCarno', sortable: true, width: 150,},
|
||||||
|
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
|
||||||
|
];
|
||||||
|
let gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/minwon/init/list.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true, //초기화시 조회
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gridOptions = {
|
||||||
|
el: 'grid',
|
||||||
|
rowHeaders: ['checkbox'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "처리 할 초기자료가 없습니다.",
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징)
|
||||||
|
perPage: perPage,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
|
||||||
|
|
||||||
|
GRID.on("dblclick", (e) => {
|
||||||
|
var popUrl = '/minwon/init/init_popup.do';
|
||||||
|
var popTitle = "initPopup";
|
||||||
|
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
|
||||||
|
|
||||||
|
// 1) localStorage에 저장
|
||||||
|
console.log(e)
|
||||||
|
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
|
||||||
|
let mmCodes = e.instance.getData().map(row => row.mmCode);
|
||||||
|
|
||||||
|
const state = { cursor, mmCodes, savedAt: Date.now() };
|
||||||
|
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
|
||||||
|
|
||||||
|
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
|
||||||
|
if (!INIT_POPUP || INIT_POPUP.closed) {
|
||||||
|
INIT_POPUP = window.open(popUrl, popTitle, popOption);
|
||||||
|
} else {
|
||||||
|
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
|
||||||
|
INIT_POPUP.focus();
|
||||||
|
INIT_POPUP.INIT_POP_API.search();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 레디펑션
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
fnBiz.init();
|
||||||
|
fnBiz.eventListener();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,250 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<!-- Main body -->
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">등록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
<ul class="lef">
|
||||||
|
<li class="th">검색구분</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition" name="searchCondition" class="input">
|
||||||
|
<option value="">검색구분</option>
|
||||||
|
<option value="title" <c:if test="${paramVO.searchCondition eq 'title'}">selected</c:if>>제목</option>
|
||||||
|
<option value="contents" <c:if test="${paramVO.searchCondition eq 'contents'}">selected</c:if>>내용</option>
|
||||||
|
<option value="writer" <c:if test="${paramVO.searchCondition eq 'writer'}">selected</c:if>>수정자명</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">검색어</li>
|
||||||
|
<li><input type="text" id="searchKeyword" name="searchKeyword" class="input" value="${param.searchKeyword}"/></li>
|
||||||
|
<li class="th">담당자지정</li>
|
||||||
|
<li><input type="text" id="worker" name="worker" class="input" value=""/></li>
|
||||||
|
<li class="th">사용여부</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchUseYn" name="searchUseYn" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="Y" <c:if test="${param.searchUseYn eq 'Y'}">selected</c:if>>사용</option>
|
||||||
|
<option value="N" <c:if test="${param.searchUseYn eq 'N'}">selected</c:if>>미사용</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">접수일자 지정</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker bottom" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="30" <c:if test="${empty param.perPage or param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
<option value="100" <c:if test="${param.perPage eq '100'}">selected</c:if>>페이지당 100</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><sapn id="totalPages"></sapn> Pages</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="gs_booking">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<div id="grid"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Main body -->
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
let GRID = null;
|
||||||
|
let INIT_POPUP = null;
|
||||||
|
|
||||||
|
let SEARCH_COND = {};
|
||||||
|
|
||||||
|
let perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
// 검색정보 셋팅
|
||||||
|
let setSearchCond = function() {
|
||||||
|
let searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
|
||||||
|
let searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
|
||||||
|
let searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
|
||||||
|
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
|
||||||
|
SEARCH_COND.searchCondition = searchCondition;
|
||||||
|
SEARCH_COND.searchKeyword = searchKeyword;
|
||||||
|
SEARCH_COND.searchUseYn = searchUseYn;
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
initGrid();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
// 검색 버튼 클릭 이벤트
|
||||||
|
$('#search_btn').on('click', function() {
|
||||||
|
// 등록일 from~to 유효성 검사
|
||||||
|
let startDate = $("#searchStartDt").val();
|
||||||
|
let endDate = $("#searchEndDt").val();
|
||||||
|
|
||||||
|
// 시작일과 종료일 중 하나만 입력된 경우 체크
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일과 종료일이 모두 입력된 경우 유효성 검사
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일이 종료일보다 늦은 경우 체크
|
||||||
|
let startDateObj = new Date(startDate);
|
||||||
|
let endDateObj = new Date(endDate);
|
||||||
|
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지를 1로 리셋
|
||||||
|
$("#page").val(1);
|
||||||
|
// 그리드 데이터 리로드
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 검색어 입력 필드에서 엔터키 이벤트 처리
|
||||||
|
$('#searchKeyword').on('keypress', function(e) {
|
||||||
|
if (e.which === 13) { // 엔터키 코드는 13
|
||||||
|
e.preventDefault(); // 기본 이벤트 방지
|
||||||
|
$('#search_btn').trigger('click'); // 검색 버튼 클릭 이벤트 트리거
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// perPage 변경 이벤트 추가
|
||||||
|
$('#perPageSelect').on('change', () => {
|
||||||
|
const pagination = TuiGrid.instance.getPagination();
|
||||||
|
|
||||||
|
GRID.setPerPage($('#perPageSelect').val());
|
||||||
|
pagination.setItemsPerPage($('#perPageSelect').val());
|
||||||
|
pagination.reset(TuiGrid.instance.getRowCount());
|
||||||
|
pagination.movePageTo(1);
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** tui-grid Set */
|
||||||
|
let initGrid = () => {
|
||||||
|
const gridColumns = [
|
||||||
|
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 50,},
|
||||||
|
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 70,},
|
||||||
|
{header: '신고자', name: 'mmSgnm', sortable: true, width: 100,},
|
||||||
|
{header: '담당자', name: 'mmSgtel', sortable: true, width: 100,},
|
||||||
|
{header: '전화번호', name: 'asTel', width: 150,},
|
||||||
|
{header: '접수일자', name: 'asJsdate', sortable: true, width: 70,},
|
||||||
|
{header: '처리기한', name: 'asLimitDt', sortable: true, width: 70,},
|
||||||
|
{header: '위반일자', name: 'mmDate', sortable: true, width: 150,},
|
||||||
|
{header: '첨부', name: 'mmImagegb', width: 150,},
|
||||||
|
{header: '사진갯수', name: 'mmImagecnt', width: 50,},
|
||||||
|
{header: '위반내용', name: 'mmSgcont', width: 250,},
|
||||||
|
{header: '접수번호', name: 'asJsno', sortable: true, width: 150,},
|
||||||
|
{header: '차량번호', name: 'mmCarno', sortable: true, width: 150,},
|
||||||
|
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
|
||||||
|
];
|
||||||
|
let gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/minwon/init/list.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true, //초기화시 조회
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gridOptions = {
|
||||||
|
el: 'grid',
|
||||||
|
rowHeaders: ['checkbox'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "처리 할 초기자료가 없습니다.",
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징)
|
||||||
|
perPage: perPage,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
|
||||||
|
|
||||||
|
GRID.on("dblclick", (e) => {
|
||||||
|
var popUrl = '/minwon/init/init_popup.do';
|
||||||
|
var popTitle = "initPopup";
|
||||||
|
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
|
||||||
|
|
||||||
|
// 1) localStorage에 저장
|
||||||
|
console.log(e)
|
||||||
|
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
|
||||||
|
let mmCodes = e.instance.getData().map(row => row.mmCode);
|
||||||
|
|
||||||
|
const state = { cursor, mmCodes, savedAt: Date.now() };
|
||||||
|
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
|
||||||
|
|
||||||
|
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
|
||||||
|
if (!INIT_POPUP || INIT_POPUP.closed) {
|
||||||
|
INIT_POPUP = window.open(popUrl, popTitle, popOption);
|
||||||
|
} else {
|
||||||
|
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
|
||||||
|
INIT_POPUP.focus();
|
||||||
|
INIT_POPUP.INIT_POP_API.search();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 레디펑션
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
fnBiz.init();
|
||||||
|
fnBiz.eventListener();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,250 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<!-- Main body -->
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">등록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
<ul class="lef">
|
||||||
|
<li class="th">검색구분</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition" name="searchCondition" class="input">
|
||||||
|
<option value="">검색구분</option>
|
||||||
|
<option value="title" <c:if test="${paramVO.searchCondition eq 'title'}">selected</c:if>>제목</option>
|
||||||
|
<option value="contents" <c:if test="${paramVO.searchCondition eq 'contents'}">selected</c:if>>내용</option>
|
||||||
|
<option value="writer" <c:if test="${paramVO.searchCondition eq 'writer'}">selected</c:if>>수정자명</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">검색어</li>
|
||||||
|
<li><input type="text" id="searchKeyword" name="searchKeyword" class="input" value="${param.searchKeyword}"/></li>
|
||||||
|
<li class="th">담당자지정</li>
|
||||||
|
<li><input type="text" id="worker" name="worker" class="input" value=""/></li>
|
||||||
|
<li class="th">사용여부</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchUseYn" name="searchUseYn" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="Y" <c:if test="${param.searchUseYn eq 'Y'}">selected</c:if>>사용</option>
|
||||||
|
<option value="N" <c:if test="${param.searchUseYn eq 'N'}">selected</c:if>>미사용</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">접수일자 지정</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker bottom" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="30" <c:if test="${empty param.perPage or param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
<option value="100" <c:if test="${param.perPage eq '100'}">selected</c:if>>페이지당 100</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><sapn id="totalPages"></sapn> Pages</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="gs_booking">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<div id="grid"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Main body -->
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
let GRID = null;
|
||||||
|
let INIT_POPUP = null;
|
||||||
|
|
||||||
|
let SEARCH_COND = {};
|
||||||
|
|
||||||
|
let perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
// 검색정보 셋팅
|
||||||
|
let setSearchCond = function() {
|
||||||
|
let searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
|
||||||
|
let searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
|
||||||
|
let searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
|
||||||
|
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
|
||||||
|
SEARCH_COND.searchCondition = searchCondition;
|
||||||
|
SEARCH_COND.searchKeyword = searchKeyword;
|
||||||
|
SEARCH_COND.searchUseYn = searchUseYn;
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
initGrid();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
// 검색 버튼 클릭 이벤트
|
||||||
|
$('#search_btn').on('click', function() {
|
||||||
|
// 등록일 from~to 유효성 검사
|
||||||
|
let startDate = $("#searchStartDt").val();
|
||||||
|
let endDate = $("#searchEndDt").val();
|
||||||
|
|
||||||
|
// 시작일과 종료일 중 하나만 입력된 경우 체크
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일과 종료일이 모두 입력된 경우 유효성 검사
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일이 종료일보다 늦은 경우 체크
|
||||||
|
let startDateObj = new Date(startDate);
|
||||||
|
let endDateObj = new Date(endDate);
|
||||||
|
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지를 1로 리셋
|
||||||
|
$("#page").val(1);
|
||||||
|
// 그리드 데이터 리로드
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 검색어 입력 필드에서 엔터키 이벤트 처리
|
||||||
|
$('#searchKeyword').on('keypress', function(e) {
|
||||||
|
if (e.which === 13) { // 엔터키 코드는 13
|
||||||
|
e.preventDefault(); // 기본 이벤트 방지
|
||||||
|
$('#search_btn').trigger('click'); // 검색 버튼 클릭 이벤트 트리거
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// perPage 변경 이벤트 추가
|
||||||
|
$('#perPageSelect').on('change', () => {
|
||||||
|
const pagination = TuiGrid.instance.getPagination();
|
||||||
|
|
||||||
|
GRID.setPerPage($('#perPageSelect').val());
|
||||||
|
pagination.setItemsPerPage($('#perPageSelect').val());
|
||||||
|
pagination.reset(TuiGrid.instance.getRowCount());
|
||||||
|
pagination.movePageTo(1);
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** tui-grid Set */
|
||||||
|
let initGrid = () => {
|
||||||
|
const gridColumns = [
|
||||||
|
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 50,},
|
||||||
|
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 70,},
|
||||||
|
{header: '신고자', name: 'mmSgnm', sortable: true, width: 100,},
|
||||||
|
{header: '담당자', name: 'mmSgtel', sortable: true, width: 100,},
|
||||||
|
{header: '전화번호', name: 'asTel', width: 150,},
|
||||||
|
{header: '접수일자', name: 'asJsdate', sortable: true, width: 70,},
|
||||||
|
{header: '처리기한', name: 'asLimitDt', sortable: true, width: 70,},
|
||||||
|
{header: '위반일자', name: 'mmDate', sortable: true, width: 150,},
|
||||||
|
{header: '첨부', name: 'mmImagegb', width: 150,},
|
||||||
|
{header: '사진갯수', name: 'mmImagecnt', width: 50,},
|
||||||
|
{header: '위반내용', name: 'mmSgcont', width: 250,},
|
||||||
|
{header: '접수번호', name: 'asJsno', sortable: true, width: 150,},
|
||||||
|
{header: '차량번호', name: 'mmCarno', sortable: true, width: 150,},
|
||||||
|
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
|
||||||
|
];
|
||||||
|
let gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/minwon/init/list.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true, //초기화시 조회
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gridOptions = {
|
||||||
|
el: 'grid',
|
||||||
|
rowHeaders: ['checkbox'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "처리 할 초기자료가 없습니다.",
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징)
|
||||||
|
perPage: perPage,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
|
||||||
|
|
||||||
|
GRID.on("dblclick", (e) => {
|
||||||
|
var popUrl = '/minwon/init/init_popup.do';
|
||||||
|
var popTitle = "initPopup";
|
||||||
|
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
|
||||||
|
|
||||||
|
// 1) localStorage에 저장
|
||||||
|
console.log(e)
|
||||||
|
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
|
||||||
|
let mmCodes = e.instance.getData().map(row => row.mmCode);
|
||||||
|
|
||||||
|
const state = { cursor, mmCodes, savedAt: Date.now() };
|
||||||
|
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
|
||||||
|
|
||||||
|
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
|
||||||
|
if (!INIT_POPUP || INIT_POPUP.closed) {
|
||||||
|
INIT_POPUP = window.open(popUrl, popTitle, popOption);
|
||||||
|
} else {
|
||||||
|
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
|
||||||
|
INIT_POPUP.focus();
|
||||||
|
INIT_POPUP.INIT_POP_API.search();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 레디펑션
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
fnBiz.init();
|
||||||
|
fnBiz.eventListener();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,298 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<!-- Main body -->
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">등록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
<ul class="lef">
|
||||||
|
<li class="th">검색구분</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition" name="searchCondition" class="input">
|
||||||
|
<option value="">검색구분</option>
|
||||||
|
<option value="title" <c:if test="${paramVO.searchCondition eq 'title'}">selected</c:if>>제목</option>
|
||||||
|
<option value="contents" <c:if test="${paramVO.searchCondition eq 'contents'}">selected</c:if>>내용</option>
|
||||||
|
<option value="writer" <c:if test="${paramVO.searchCondition eq 'writer'}">selected</c:if>>수정자명</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">검색어</li>
|
||||||
|
<li><input type="text" id="searchKeyword" name="searchKeyword" class="input" value="${param.searchKeyword}"/></li>
|
||||||
|
<li class="th">담당자지정</li>
|
||||||
|
<li><input type="text" id="worker" name="worker" class="input" value=""/></li>
|
||||||
|
<li class="th">사용여부</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchUseYn" name="searchUseYn" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="Y" <c:if test="${param.searchUseYn eq 'Y'}">selected</c:if>>사용</option>
|
||||||
|
<option value="N" <c:if test="${param.searchUseYn eq 'N'}">selected</c:if>>미사용</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">접수일자 지정</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker bottom" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="30" <c:if test="${empty param.perPage or param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
<option value="100" <c:if test="${param.perPage eq '100'}">selected</c:if>>페이지당 100</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><sapn id="totalPages"></sapn> Pages</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="state-tab-wrap">
|
||||||
|
<ul class="state-tabs">
|
||||||
|
<%-- <li data-state="FIN_BU" value="6">답변완료(부과)</li>--%>
|
||||||
|
<%-- <li data-state="FIN_GE" value="7">답변완료(계도)</li>--%>
|
||||||
|
<%-- <li data-state="FIN_ME" value="8">답변완료(미부과)</li>--%>
|
||||||
|
<%-- <li data-state="FIN_ADD" value="9">답변완료(수기)</li>--%>
|
||||||
|
<%-- <li data-state="FAIL" value="5">답변실패</li>--%>
|
||||||
|
<%-- <li data-state="INCOMP" value="fail">답변미대상</li>--%>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="gs_booking">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<div id="grid"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Main body -->
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
|
||||||
|
let GRID = null;
|
||||||
|
let TOTAL_POPUP = null;
|
||||||
|
|
||||||
|
let SEARCH_COND = {};
|
||||||
|
|
||||||
|
let perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
// 검색정보 셋팅
|
||||||
|
let setSearchCond = function() {
|
||||||
|
let searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
|
||||||
|
let searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
|
||||||
|
let searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
|
||||||
|
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
let searchLawgb = $(".state-tabs li.on").attr("value");
|
||||||
|
|
||||||
|
|
||||||
|
SEARCH_COND.searchCondition = searchCondition;
|
||||||
|
SEARCH_COND.searchKeyword = searchKeyword;
|
||||||
|
SEARCH_COND.searchUseYn = searchUseYn;
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
SEARCH_COND.searchLawgb = searchLawgb;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
fnBiz.setCode();
|
||||||
|
},
|
||||||
|
|
||||||
|
setCode: () => {
|
||||||
|
$.ajax({
|
||||||
|
url: "/common/code/find.ajax",
|
||||||
|
type: "GET",
|
||||||
|
contentType: 'application/json',
|
||||||
|
success: function(response) {
|
||||||
|
response.cpViolation.forEach((item) => {
|
||||||
|
$(".state-tabs").append('<li value="' + item.vlCode + '">' + item.vlId + '</li>');
|
||||||
|
});
|
||||||
|
|
||||||
|
initGrid();
|
||||||
|
$(".state-tabs li").first().addClass("on").trigger("click");
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
$("#result").text("조회 실패");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
// 검색 버튼 클릭 이벤트
|
||||||
|
$('#search_btn').on('click', function() {
|
||||||
|
// 등록일 from~to 유효성 검사
|
||||||
|
let startDate = $("#searchStartDt").val();
|
||||||
|
let endDate = $("#searchEndDt").val();
|
||||||
|
|
||||||
|
// 시작일과 종료일 중 하나만 입력된 경우 체크
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일과 종료일이 모두 입력된 경우 유효성 검사
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일이 종료일보다 늦은 경우 체크
|
||||||
|
let startDateObj = new Date(startDate);
|
||||||
|
let endDateObj = new Date(endDate);
|
||||||
|
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지를 1로 리셋
|
||||||
|
$("#page").val(1);
|
||||||
|
// 그리드 데이터 리로드
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 검색어 입력 필드에서 엔터키 이벤트 처리
|
||||||
|
$('#searchKeyword').on('keypress', function(e) {
|
||||||
|
if (e.which === 13) { // 엔터키 코드는 13
|
||||||
|
e.preventDefault(); // 기본 이벤트 방지
|
||||||
|
$('#search_btn').trigger('click'); // 검색 버튼 클릭 이벤트 트리거
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// perPage 변경 이벤트 추가
|
||||||
|
$('#perPageSelect').on('change', () => {
|
||||||
|
const pagination = TuiGrid.instance.getPagination();
|
||||||
|
|
||||||
|
GRID.setPerPage($('#perPageSelect').val());
|
||||||
|
pagination.setItemsPerPage($('#perPageSelect').val());
|
||||||
|
pagination.reset(TuiGrid.instance.getRowCount());
|
||||||
|
pagination.movePageTo(1);
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 상태 탭 클릭
|
||||||
|
$(".state-tabs").on("click", "li", function () {
|
||||||
|
$(".state-tabs li").removeClass("on");
|
||||||
|
$(this).addClass("on");
|
||||||
|
|
||||||
|
// const state = $(this).data('state') || '';
|
||||||
|
// $('#tabState').val(state);
|
||||||
|
|
||||||
|
|
||||||
|
SEARCH_COND = {};
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** tui-grid Set */
|
||||||
|
let initGrid = () => {
|
||||||
|
const gridColumns = [
|
||||||
|
{header: '등록구분', name: '', sortable: true, width: 50,},
|
||||||
|
{header: '목록번호', name: '', sortable: true, width: 70,},
|
||||||
|
{header: '접수일', name: '', sortable: true, width: 100,},
|
||||||
|
{header: '신고자', name: '', sortable: true, width: 100,},
|
||||||
|
{header: '담당자', name: '', width: 150,},
|
||||||
|
{header: '위반내용', name: '', sortable: true, width: 70,},
|
||||||
|
{header: '위반일시', name: '', sortable: true, width: 70,},
|
||||||
|
{header: '차량번호', name: '', sortable: true, width: 150,},
|
||||||
|
{header: '소유자', name: '', width: 150,},
|
||||||
|
{header: '소유주구분', name: '', width: 50,},
|
||||||
|
{header: '주민번호', name: '', width: 250,},
|
||||||
|
{header: '위반장소', name: '', sortable: true, width: 150,},
|
||||||
|
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
|
||||||
|
];
|
||||||
|
let gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/post/preNotice/sendTarget/sendTargetList.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: false, //초기화시 조회
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gridOptions = {
|
||||||
|
el: 'grid',
|
||||||
|
rowHeaders: ['checkbox'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "조회된 사전통보 대상이 없습니다.",
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징)
|
||||||
|
perPage: perPage,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
|
||||||
|
|
||||||
|
GRID.on("dblclick", (e) => {
|
||||||
|
var popUrl = '/total/info.do';
|
||||||
|
var popTitle = "TotalPopup";
|
||||||
|
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
|
||||||
|
|
||||||
|
// 1) localStorage에 저장
|
||||||
|
console.log(e)
|
||||||
|
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
|
||||||
|
let mmCodes = e.instance.getData().map(row => row.mmCode);
|
||||||
|
|
||||||
|
const state = { cursor, mmCodes, savedAt: Date.now() };
|
||||||
|
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
|
||||||
|
|
||||||
|
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
|
||||||
|
if (!TOTAL_POPUP || TOTAL_POPUP.closed) {
|
||||||
|
TOTAL_POPUP = window.open(popUrl, popTitle, popOption);
|
||||||
|
} else {
|
||||||
|
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
|
||||||
|
TOTAL_POPUP.focus();
|
||||||
|
TOTAL_POPUP.TOTAL_INFO_POPUP_API.search();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 레디펑션
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
fnBiz.init();
|
||||||
|
fnBiz.eventListener();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,250 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<!-- Main body -->
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">등록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
<ul class="lef">
|
||||||
|
<li class="th">검색구분</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition" name="searchCondition" class="input">
|
||||||
|
<option value="">검색구분</option>
|
||||||
|
<option value="title" <c:if test="${paramVO.searchCondition eq 'title'}">selected</c:if>>제목</option>
|
||||||
|
<option value="contents" <c:if test="${paramVO.searchCondition eq 'contents'}">selected</c:if>>내용</option>
|
||||||
|
<option value="writer" <c:if test="${paramVO.searchCondition eq 'writer'}">selected</c:if>>수정자명</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">검색어</li>
|
||||||
|
<li><input type="text" id="searchKeyword" name="searchKeyword" class="input" value="${param.searchKeyword}"/></li>
|
||||||
|
<li class="th">담당자지정</li>
|
||||||
|
<li><input type="text" id="worker" name="worker" class="input" value=""/></li>
|
||||||
|
<li class="th">사용여부</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchUseYn" name="searchUseYn" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="Y" <c:if test="${param.searchUseYn eq 'Y'}">selected</c:if>>사용</option>
|
||||||
|
<option value="N" <c:if test="${param.searchUseYn eq 'N'}">selected</c:if>>미사용</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">접수일자 지정</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker bottom" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="30" <c:if test="${empty param.perPage or param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
<option value="100" <c:if test="${param.perPage eq '100'}">selected</c:if>>페이지당 100</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><sapn id="totalPages"></sapn> Pages</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="gs_booking">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<div id="grid"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Main body -->
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
let GRID = null;
|
||||||
|
let INIT_POPUP = null;
|
||||||
|
|
||||||
|
let SEARCH_COND = {};
|
||||||
|
|
||||||
|
let perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
// 검색정보 셋팅
|
||||||
|
let setSearchCond = function() {
|
||||||
|
let searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
|
||||||
|
let searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
|
||||||
|
let searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
|
||||||
|
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
|
||||||
|
SEARCH_COND.searchCondition = searchCondition;
|
||||||
|
SEARCH_COND.searchKeyword = searchKeyword;
|
||||||
|
SEARCH_COND.searchUseYn = searchUseYn;
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
initGrid();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
// 검색 버튼 클릭 이벤트
|
||||||
|
$('#search_btn').on('click', function() {
|
||||||
|
// 등록일 from~to 유효성 검사
|
||||||
|
let startDate = $("#searchStartDt").val();
|
||||||
|
let endDate = $("#searchEndDt").val();
|
||||||
|
|
||||||
|
// 시작일과 종료일 중 하나만 입력된 경우 체크
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일과 종료일이 모두 입력된 경우 유효성 검사
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일이 종료일보다 늦은 경우 체크
|
||||||
|
let startDateObj = new Date(startDate);
|
||||||
|
let endDateObj = new Date(endDate);
|
||||||
|
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지를 1로 리셋
|
||||||
|
$("#page").val(1);
|
||||||
|
// 그리드 데이터 리로드
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 검색어 입력 필드에서 엔터키 이벤트 처리
|
||||||
|
$('#searchKeyword').on('keypress', function(e) {
|
||||||
|
if (e.which === 13) { // 엔터키 코드는 13
|
||||||
|
e.preventDefault(); // 기본 이벤트 방지
|
||||||
|
$('#search_btn').trigger('click'); // 검색 버튼 클릭 이벤트 트리거
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// perPage 변경 이벤트 추가
|
||||||
|
$('#perPageSelect').on('change', () => {
|
||||||
|
const pagination = TuiGrid.instance.getPagination();
|
||||||
|
|
||||||
|
GRID.setPerPage($('#perPageSelect').val());
|
||||||
|
pagination.setItemsPerPage($('#perPageSelect').val());
|
||||||
|
pagination.reset(TuiGrid.instance.getRowCount());
|
||||||
|
pagination.movePageTo(1);
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** tui-grid Set */
|
||||||
|
let initGrid = () => {
|
||||||
|
const gridColumns = [
|
||||||
|
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 50,},
|
||||||
|
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 70,},
|
||||||
|
{header: '신고자', name: 'mmSgnm', sortable: true, width: 100,},
|
||||||
|
{header: '담당자', name: 'mmSgtel', sortable: true, width: 100,},
|
||||||
|
{header: '전화번호', name: 'asTel', width: 150,},
|
||||||
|
{header: '접수일자', name: 'asJsdate', sortable: true, width: 70,},
|
||||||
|
{header: '처리기한', name: 'asLimitDt', sortable: true, width: 70,},
|
||||||
|
{header: '위반일자', name: 'mmDate', sortable: true, width: 150,},
|
||||||
|
{header: '첨부', name: 'mmImagegb', width: 150,},
|
||||||
|
{header: '사진갯수', name: 'mmImagecnt', width: 50,},
|
||||||
|
{header: '위반내용', name: 'mmSgcont', width: 250,},
|
||||||
|
{header: '접수번호', name: 'asJsno', sortable: true, width: 150,},
|
||||||
|
{header: '차량번호', name: 'mmCarno', sortable: true, width: 150,},
|
||||||
|
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
|
||||||
|
];
|
||||||
|
let gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/minwon/init/list.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true, //초기화시 조회
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gridOptions = {
|
||||||
|
el: 'grid',
|
||||||
|
rowHeaders: ['checkbox'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "처리 할 초기자료가 없습니다.",
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징)
|
||||||
|
perPage: perPage,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
|
||||||
|
|
||||||
|
GRID.on("dblclick", (e) => {
|
||||||
|
var popUrl = '/minwon/init/init_popup.do';
|
||||||
|
var popTitle = "initPopup";
|
||||||
|
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
|
||||||
|
|
||||||
|
// 1) localStorage에 저장
|
||||||
|
console.log(e)
|
||||||
|
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
|
||||||
|
let mmCodes = e.instance.getData().map(row => row.mmCode);
|
||||||
|
|
||||||
|
const state = { cursor, mmCodes, savedAt: Date.now() };
|
||||||
|
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
|
||||||
|
|
||||||
|
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
|
||||||
|
if (!INIT_POPUP || INIT_POPUP.closed) {
|
||||||
|
INIT_POPUP = window.open(popUrl, popTitle, popOption);
|
||||||
|
} else {
|
||||||
|
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
|
||||||
|
INIT_POPUP.focus();
|
||||||
|
INIT_POPUP.INIT_POP_API.search();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 레디펑션
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
fnBiz.init();
|
||||||
|
fnBiz.eventListener();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
<%--
|
||||||
|
Created by IntelliJ IDEA.
|
||||||
|
User: kurt
|
||||||
|
Date: 2025. 11. 25.
|
||||||
|
Time: 오후 3:41
|
||||||
|
To change this template use File | Settings | File Templates.
|
||||||
|
--%>
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,250 @@
|
|||||||
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<!-- Main body -->
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">등록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
<ul class="lef">
|
||||||
|
<li class="th">검색구분</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition" name="searchCondition" class="input">
|
||||||
|
<option value="">검색구분</option>
|
||||||
|
<option value="title" <c:if test="${paramVO.searchCondition eq 'title'}">selected</c:if>>제목</option>
|
||||||
|
<option value="contents" <c:if test="${paramVO.searchCondition eq 'contents'}">selected</c:if>>내용</option>
|
||||||
|
<option value="writer" <c:if test="${paramVO.searchCondition eq 'writer'}">selected</c:if>>수정자명</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">검색어</li>
|
||||||
|
<li><input type="text" id="searchKeyword" name="searchKeyword" class="input" value="${param.searchKeyword}"/></li>
|
||||||
|
<li class="th">담당자지정</li>
|
||||||
|
<li><input type="text" id="worker" name="worker" class="input" value=""/></li>
|
||||||
|
<li class="th">사용여부</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchUseYn" name="searchUseYn" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="Y" <c:if test="${param.searchUseYn eq 'Y'}">selected</c:if>>사용</option>
|
||||||
|
<option value="N" <c:if test="${param.searchUseYn eq 'N'}">selected</c:if>>미사용</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="th">접수일자 지정</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker bottom" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="30" <c:if test="${empty param.perPage or param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
<option value="100" <c:if test="${param.perPage eq '100'}">selected</c:if>>페이지당 100</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><sapn id="totalPages"></sapn> Pages</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="gs_booking">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<div id="grid"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Main body -->
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
let GRID = null;
|
||||||
|
let INIT_POPUP = null;
|
||||||
|
|
||||||
|
let SEARCH_COND = {};
|
||||||
|
|
||||||
|
let perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
// 검색정보 셋팅
|
||||||
|
let setSearchCond = function() {
|
||||||
|
let searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
|
||||||
|
let searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
|
||||||
|
let searchUseYn = $.trim(nvl($("#searchUseYn").val(), ""));
|
||||||
|
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
|
||||||
|
SEARCH_COND.searchCondition = searchCondition;
|
||||||
|
SEARCH_COND.searchKeyword = searchKeyword;
|
||||||
|
SEARCH_COND.searchUseYn = searchUseYn;
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
initGrid();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
// 검색 버튼 클릭 이벤트
|
||||||
|
$('#search_btn').on('click', function() {
|
||||||
|
// 등록일 from~to 유효성 검사
|
||||||
|
let startDate = $("#searchStartDt").val();
|
||||||
|
let endDate = $("#searchEndDt").val();
|
||||||
|
|
||||||
|
// 시작일과 종료일 중 하나만 입력된 경우 체크
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일과 종료일이 모두 입력된 경우 유효성 검사
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시작일이 종료일보다 늦은 경우 체크
|
||||||
|
let startDateObj = new Date(startDate);
|
||||||
|
let endDateObj = new Date(endDate);
|
||||||
|
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지를 1로 리셋
|
||||||
|
$("#page").val(1);
|
||||||
|
// 그리드 데이터 리로드
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 검색어 입력 필드에서 엔터키 이벤트 처리
|
||||||
|
$('#searchKeyword').on('keypress', function(e) {
|
||||||
|
if (e.which === 13) { // 엔터키 코드는 13
|
||||||
|
e.preventDefault(); // 기본 이벤트 방지
|
||||||
|
$('#search_btn').trigger('click'); // 검색 버튼 클릭 이벤트 트리거
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// perPage 변경 이벤트 추가
|
||||||
|
$('#perPageSelect').on('change', () => {
|
||||||
|
const pagination = TuiGrid.instance.getPagination();
|
||||||
|
|
||||||
|
GRID.setPerPage($('#perPageSelect').val());
|
||||||
|
pagination.setItemsPerPage($('#perPageSelect').val());
|
||||||
|
pagination.reset(TuiGrid.instance.getRowCount());
|
||||||
|
pagination.movePageTo(1);
|
||||||
|
TuiGrid.instance.readData(1);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** tui-grid Set */
|
||||||
|
let initGrid = () => {
|
||||||
|
const gridColumns = [
|
||||||
|
{header: '등록구분', name: 'mmDlgb', sortable: true, width: 50,},
|
||||||
|
{header: '목록번호', name: 'asBbsNo', sortable: true, width: 70,},
|
||||||
|
{header: '신고자', name: 'mmSgnm', sortable: true, width: 100,},
|
||||||
|
{header: '담당자', name: 'mmSgtel', sortable: true, width: 100,},
|
||||||
|
{header: '전화번호', name: 'asTel', width: 150,},
|
||||||
|
{header: '접수일자', name: 'asJsdate', sortable: true, width: 70,},
|
||||||
|
{header: '처리기한', name: 'asLimitDt', sortable: true, width: 70,},
|
||||||
|
{header: '위반일자', name: 'mmDate', sortable: true, width: 150,},
|
||||||
|
{header: '첨부', name: 'mmImagegb', width: 150,},
|
||||||
|
{header: '사진갯수', name: 'mmImagecnt', width: 50,},
|
||||||
|
{header: '위반내용', name: 'mmSgcont', width: 250,},
|
||||||
|
{header: '접수번호', name: 'asJsno', sortable: true, width: 150,},
|
||||||
|
{header: '차량번호', name: 'mmCarno', sortable: true, width: 150,},
|
||||||
|
{header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
|
||||||
|
];
|
||||||
|
let gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/minwon/init/list.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true, //초기화시 조회
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gridOptions = {
|
||||||
|
el: 'grid',
|
||||||
|
rowHeaders: ['checkbox'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "처리 할 초기자료가 없습니다.",
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징)
|
||||||
|
perPage: perPage,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
|
||||||
|
|
||||||
|
GRID.on("dblclick", (e) => {
|
||||||
|
var popUrl = '/minwon/init/init_popup.do';
|
||||||
|
var popTitle = "initPopup";
|
||||||
|
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
|
||||||
|
|
||||||
|
// 1) localStorage에 저장
|
||||||
|
console.log(e)
|
||||||
|
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
|
||||||
|
let mmCodes = e.instance.getData().map(row => row.mmCode);
|
||||||
|
|
||||||
|
const state = { cursor, mmCodes, savedAt: Date.now() };
|
||||||
|
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
|
||||||
|
|
||||||
|
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
|
||||||
|
if (!INIT_POPUP || INIT_POPUP.closed) {
|
||||||
|
INIT_POPUP = window.open(popUrl, popTitle, popOption);
|
||||||
|
} else {
|
||||||
|
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
|
||||||
|
INIT_POPUP.focus();
|
||||||
|
INIT_POPUP.INIT_POP_API.search();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 레디펑션
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
fnBiz.init();
|
||||||
|
fnBiz.eventListener();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,420 @@
|
|||||||
|
<%--
|
||||||
|
Created by IntelliJ IDEA.
|
||||||
|
User: moong
|
||||||
|
Date: 2025-11-27
|
||||||
|
Time: 오후 3:21
|
||||||
|
To change this template use File | Settings | File Templates.
|
||||||
|
--%>
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">등록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
<ul class="lef">
|
||||||
|
<li class="th">조회일자 지정</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button type="button" id="btnHwp" class="newbtnss bg1">한글파일출력</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="30" <c:if test="${empty param.perPage or param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
<option value="100" <c:if test="${param.perPage eq '100'}">selected</c:if>>페이지당 100</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><sapn id="totalPages"></sapn> Pages</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gs_booking">
|
||||||
|
<!-- 상단 3개 그리드 -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<!-- 연도별 경고/과태료/전체 -->
|
||||||
|
<div id="gridYear" class="stat-grid-top"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<!-- 자동단속기/안전신문고/합계 -->
|
||||||
|
<div id="gridDevice" class="stat-grid-top"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<!-- 위반유형별 경고/과태료/합계 -->
|
||||||
|
<div id="gridType" class="stat-grid-top"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 하단 1개 그리드 (상세 합계) -->
|
||||||
|
<div class="row stat-grid-bottom-row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<!-- 단계별(계도/사전/부과/독촉) 합계 -->
|
||||||
|
<div id="gridDetail" class="stat-grid-bottom"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
.stat-grid-top {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-grid-bottom {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-grid-row {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-grid-bottom-row {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
let SEARCH_COND = {};
|
||||||
|
|
||||||
|
let GRID_YEAR = null;
|
||||||
|
let GRID_DEVICE = null;
|
||||||
|
let GRID_TYPE = null;
|
||||||
|
let GRID_DETAIL = null;
|
||||||
|
|
||||||
|
|
||||||
|
let setSearchCond = function () {
|
||||||
|
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
|
||||||
|
SEARCH_COND = {}; // 항상 새로 만듦
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
initGridYear();
|
||||||
|
initGridDevice();
|
||||||
|
initGridType();
|
||||||
|
initGridDetail();
|
||||||
|
},
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
|
||||||
|
// 검색 버튼
|
||||||
|
$('#search_btn').on('click', function () {
|
||||||
|
let startDate = $("#searchStartDt").val();
|
||||||
|
let endDate = $("#searchEndDt").val();
|
||||||
|
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let startDateObj = new Date(startDate);
|
||||||
|
let endDateObj = new Date(endDate);
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[GRID_YEAR, GRID_DEVICE, GRID_TYPE, GRID_DETAIL].forEach(grid => {
|
||||||
|
if (grid) {
|
||||||
|
grid.readData(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#perPageSelect').on('change', () => {
|
||||||
|
const perPage = $('#perPageSelect').val();
|
||||||
|
|
||||||
|
[GRID_YEAR, GRID_DEVICE, GRID_TYPE, GRID_DETAIL].forEach(grid => {
|
||||||
|
if (!grid || !grid.getPagination) return;
|
||||||
|
|
||||||
|
const pagination = grid.getPagination();
|
||||||
|
if (!pagination) return;
|
||||||
|
|
||||||
|
pagination.setItemsPerPage(perPage);
|
||||||
|
pagination.reset(grid.getRowCount());
|
||||||
|
pagination.movePageTo(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btnHwp').on('click', function () {
|
||||||
|
setSearchCond();
|
||||||
|
|
||||||
|
if (!SEARCH_COND.searchStartDt || !SEARCH_COND.searchEndDt) {
|
||||||
|
alert("조회일자를 먼저 선택해 주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const queryString = $.param({
|
||||||
|
searchStartDt: SEARCH_COND.searchStartDt,
|
||||||
|
searchEndDt: SEARCH_COND.searchEndDt
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = '<c:url value="/search/caution/caution-hwp-download.do"/>' + '?' + queryString;
|
||||||
|
window.open(url, '_blank');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initGridYear = () => {
|
||||||
|
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
const gridColumns = [
|
||||||
|
{ header: '구분', name: 'year', width: 80, align: 'center' },
|
||||||
|
{ header: '경고', name: 'insCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '과태료', name: 'violCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '전체', name: 'totalCnt', width: 80, align: 'right' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const gridOptions = {
|
||||||
|
el: 'gridYear',
|
||||||
|
rowHeaders: ['rowNum'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "자료가 없습니다.",
|
||||||
|
height: 100,
|
||||||
|
bodyHeight: 80,
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true, // 통계는 클라이언트 페이징이 편함
|
||||||
|
perPage: perPage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/search/caution/caution-select.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true,
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
SEARCH_COND.gridId = 'YEAR';
|
||||||
|
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID_YEAR = TuiGrid.of(gridOptions, gridDatasource, (res) => {});
|
||||||
|
GRID_YEAR.readData(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const initGridDevice = () => {
|
||||||
|
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
const gridColumns = [
|
||||||
|
{ header: '구분', name: 'year', width: 80, align: 'center' },
|
||||||
|
{ header: '자동단속기', name: 'cctvCnt', width: 100, align: 'right' },
|
||||||
|
{ header: '안전신문고', name: 'smgCnt', width: 100, align: 'right' },
|
||||||
|
{ header: '합계', name: 'totalCnt', width: 80, align: 'right' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const gridOptions = {
|
||||||
|
el: 'gridDevice',
|
||||||
|
rowHeaders: ['rowNum'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "자료가 없습니다.",
|
||||||
|
height: 100,
|
||||||
|
bodyHeight: 80,
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true,
|
||||||
|
perPage: perPage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/search/caution/caution-select.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true,
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
SEARCH_COND.gridId = 'DEVICE';
|
||||||
|
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID_DEVICE = TuiGrid.of(gridOptions, gridDatasource, (res) => {});
|
||||||
|
GRID_DEVICE.readData(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const initGridType = () => {
|
||||||
|
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
const gridColumns = [
|
||||||
|
{ header: '위반유형', name: 'vlId', width: 120, align: 'left' },
|
||||||
|
{ header: '경고', name: 'insCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '과태료', name: 'violCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '합계', name: 'totalCnt', width: 80, align: 'right' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const gridOptions = {
|
||||||
|
el: 'gridType',
|
||||||
|
rowHeaders: ['rowNum'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "자료가 없습니다.",
|
||||||
|
height: 100,
|
||||||
|
bodyHeight: 80,
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true,
|
||||||
|
perPage: perPage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/search/caution/caution-select.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true,
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
SEARCH_COND.gridId = 'TYPE';
|
||||||
|
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID_TYPE = TuiGrid.of(gridOptions, gridDatasource, (res) => {});
|
||||||
|
GRID_TYPE.readData(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const initGridDetail = () => {
|
||||||
|
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
const gridColumns = [
|
||||||
|
{ header: '구분', name: 'year', width: 80, align: 'center' },
|
||||||
|
{ header: '계도-일반', name: 'instructNormalCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '계도-등기', name: 'instructRegistCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '사전-일반', name: 'sajunNormalCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '사전-등기', name: 'sajunRegistCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '부과-일반', name: 'bugwaNormalCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '부과-등기', name: 'bugwaRegistCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '독촉-일반', name: 'dokNormalCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '독촉-등기', name: 'dokRegistCnt', width: 80, align: 'right' },
|
||||||
|
{ header: '합계', name: 'totalCnt', width: 80, align: 'right' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const gridOptions = {
|
||||||
|
el: 'gridDetail',
|
||||||
|
rowHeaders: ['rowNum'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "자료가 없습니다.",
|
||||||
|
height: 150,
|
||||||
|
bodyHeight: 100,
|
||||||
|
pageOptions: {
|
||||||
|
useClient: true,
|
||||||
|
perPage: perPage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/search/caution/caution-select.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true,
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
SEARCH_COND.gridId = 'DETAIL';
|
||||||
|
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GRID_DETAIL = TuiGrid.of(gridOptions, gridDatasource, (res) => {});
|
||||||
|
GRID_DETAIL.readData(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
const startInput = $("#searchStartDt");
|
||||||
|
const endInput = $("#searchEndDt");
|
||||||
|
|
||||||
|
if (!startInput.val() || !endInput.val()) {
|
||||||
|
const today = new Date();
|
||||||
|
const yyyy = today.getFullYear();
|
||||||
|
const mm = String(today.getMonth() + 1).padStart(2, '0');
|
||||||
|
const dd = String(today.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
const todayStr = yyyy + "-" + mm + "-" + dd;
|
||||||
|
const firstDayOfYear = yyyy + "-01-01";
|
||||||
|
|
||||||
|
startInput.val(firstDayOfYear);
|
||||||
|
endInput.val(todayStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fnBiz.init();
|
||||||
|
fnBiz.eventListener();
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -0,0 +1,493 @@
|
|||||||
|
<%--
|
||||||
|
Created by IntelliJ IDEA.
|
||||||
|
User: moong
|
||||||
|
Date: 2025-11-25
|
||||||
|
Time: 오후 5:13
|
||||||
|
To change this template use File | Settings | File Templates.
|
||||||
|
--%>
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
|
||||||
|
<div class="main_body">
|
||||||
|
<section id="section8" class="main_bars">
|
||||||
|
<div class="bgs-main">
|
||||||
|
<section id="section5">
|
||||||
|
<div class="sub_title"></div>
|
||||||
|
<button type="button" onclick="location.href='<c:url value='/template/noticeSample/register.do'/>'" class="newbtn bg1">등록</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="contants_body">
|
||||||
|
<div class="gs_b_top">
|
||||||
|
|
||||||
|
<ul class="lef lef-row1">
|
||||||
|
<li class="th">위반일</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchStartDt" name="searchStartDt" class="input calender datepicker" value="${param.searchStartDt}" /> ~
|
||||||
|
<input type="text" id="searchEndDt" name="searchEndDt" class="input calender datepicker" value="${param.searchEndDt}" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="th">위반시간</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" id="searchTime1" name="searchTime1" class="input" maxlength="4" placeholder="0000" />
|
||||||
|
<input type="text" id="searchTime2" name="searchTime2" class="input" maxlength="4" placeholder="2359" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="th">위반내용</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition" name="searchCondition" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="code1" <c:if test="${paramVO.searchCondition eq 'code1'}">selected</c:if>>주차위반</option>
|
||||||
|
<option value="code2" <c:if test="${paramVO.searchCondition eq 'code2'}">selected</c:if>>주차방해</option>
|
||||||
|
<option value="code3" <c:if test="${paramVO.searchCondition eq 'code3'}">selected</c:if>>시설훼손</option>
|
||||||
|
<option value="code4" <c:if test="${paramVO.searchCondition eq 'code4'}">selected</c:if>>완속충전위반</option>
|
||||||
|
<option value="code5" <c:if test="${paramVO.searchCondition eq 'code5'}">selected</c:if>>급속충전위반</option>
|
||||||
|
<option value="code6" <c:if test="${paramVO.searchCondition eq 'code6'}">selected</c:if>>전용주차구역</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="th">처리상태</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition1" name="searchCondition1" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="00" <c:if test="${paramVO.searchCondition1 eq 'code1'}">selected</c:if>>보류자료</option>
|
||||||
|
<option value="01" <c:if test="${paramVO.searchCondition1 eq 'code2'}">selected</c:if>>초기상태</option>
|
||||||
|
<option value="11" <c:if test="${paramVO.searchCondition1 eq 'code3'}">selected</c:if>>임차인조회대상</option>
|
||||||
|
<option value="21" <c:if test="${paramVO.searchCondition1 eq 'code4'}">selected</c:if>>차적조회완료</option>
|
||||||
|
<option value="31" <c:if test="${paramVO.searchCondition1 eq 'code5'}">selected</c:if>>의견진술중</option>
|
||||||
|
<option value="42" <c:if test="${paramVO.searchCondition1 eq 'code6'}">selected</c:if>>사전통보중</option>
|
||||||
|
<option value="51" <c:if test="${paramVO.searchCondition1 eq 'code7'}">selected</c:if>>사전통보완료</option>
|
||||||
|
<option value="52" <c:if test="${paramVO.searchCondition1 eq 'code8'}">selected</c:if>>독촉</option>
|
||||||
|
<option value="53" <c:if test="${paramVO.searchCondition1 eq 'code9'}">selected</c:if>>압류예고</option>
|
||||||
|
<option value="54" <c:if test="${paramVO.searchCondition1 eq 'code10'}">selected</c:if>>압류대상</option>
|
||||||
|
<option value="55" <c:if test="${paramVO.searchCondition1 eq 'code11'}">selected</c:if>>압류</option>
|
||||||
|
<option value="code12" <c:if test="${paramVO.searchCondition1 eq 'code12'}">selected</c:if>>의견진술 미수용</option>
|
||||||
|
<option value="code13" <c:if test="${paramVO.searchCondition1 eq 'code13'}">selected</c:if>>의견진술 자진취하</option>
|
||||||
|
<option value="71" <c:if test="${paramVO.searchCondition1 eq 'code14'}">selected</c:if>>사전통보수납</option>
|
||||||
|
<option value="72" <c:if test="${paramVO.searchCondition1 eq 'code15'}">selected</c:if>>부과수납</option>
|
||||||
|
<option value="73" <c:if test="${paramVO.searchCondition1 eq 'code16'}">selected</c:if>>독촉수납</option>
|
||||||
|
<option value="74" <c:if test="${paramVO.searchCondition1 eq 'code17'}">selected</c:if>>압류예정수납</option>
|
||||||
|
<option value="75" <c:if test="${paramVO.searchCondition1 eq 'code18'}">selected</c:if>>압류수납</option>
|
||||||
|
<option value="76" <c:if test="${paramVO.searchCondition1 eq 'code19'}">selected</c:if>>시효결손</option>
|
||||||
|
<option value="80" <c:if test="${paramVO.searchCondition1 eq 'code20'}">selected</c:if>>부과취소</option>
|
||||||
|
<option value="81" <c:if test="${paramVO.searchCondition1 eq 'code21'}">selected</c:if>>미부과처리</option>
|
||||||
|
<option value="82" <c:if test="${paramVO.searchCondition1 eq 'code22'}">selected</c:if>>의견진술수용</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="th">등록구분</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition2" name="searchCondition2" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="code1" <c:if test="${paramVO.searchCondition2 eq 'code1'}">selected</c:if>>변환등록</option>
|
||||||
|
<option value="code2" <c:if test="${paramVO.searchCondition2 eq 'code2'}">selected</c:if>>수기등록</option>
|
||||||
|
<option value="code3" <c:if test="${paramVO.searchCondition2 eq 'code3'}">selected</c:if>>자동등록</option>
|
||||||
|
<option value="code4" <c:if test="${paramVO.searchCondition2 eq 'code4'}">selected</c:if>>재등록</option>
|
||||||
|
<option value="code5" <c:if test="${paramVO.searchCondition2 eq 'code5'}">selected</c:if>>복사등록</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="th">자료출처</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition3" name="searchCondition3" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="code1" <c:if test="${paramVO.searchCondition3 eq 'code1'}">selected</c:if>>생활불편</option>
|
||||||
|
<option value="code2" <c:if test="${paramVO.searchCondition3 eq 'code2'}">selected</c:if>>구청단속</option>
|
||||||
|
<option value="code3" <c:if test="${paramVO.searchCondition3 eq 'code3'}">selected</c:if>>시청단속</option>
|
||||||
|
<option value="code4" <c:if test="${paramVO.searchCondition3 eq 'code4'}">selected</c:if>>기타</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="th">법정동</li>
|
||||||
|
<li>
|
||||||
|
<select id="searchCondition4" name="searchCondition4" class="input">
|
||||||
|
<option value="">전체</option>
|
||||||
|
<option value="code1" <c:if test="${paramVO.searchCondition4 eq 'code1'}">selected</c:if>>생활불편</option>
|
||||||
|
<option value="code2" <c:if test="${paramVO.searchCondition4 eq 'code2'}">selected</c:if>>구청단속</option>
|
||||||
|
<option value="code3" <c:if test="${paramVO.searchCondition4 eq 'code3'}">selected</c:if>>시청단속</option>
|
||||||
|
<option value="code4" <c:if test="${paramVO.searchCondition4 eq 'code4'}">selected</c:if>>기타</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="lef lef-row2">
|
||||||
|
<li class="cond">
|
||||||
|
<span class="th">차량번호</span>
|
||||||
|
<input type="text" id="searchCarno" name="searchCarno" class="input" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="cond">
|
||||||
|
<span class="th">소유자성명</span>
|
||||||
|
<input type="text" id="searchName" name="searchName" class="input" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="cond">
|
||||||
|
<span class="th">주민번호</span>
|
||||||
|
<input type="text" id="searchJno" name="searchJno" class="input" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="cond">
|
||||||
|
<span class="th">신고자</span>
|
||||||
|
<input type="text" id="searchUser" name="searchUser" class="input" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="cond">
|
||||||
|
<span class="th">신고자 전화번호</span>
|
||||||
|
<input type="text" id="searchTel" name="searchTel" class="input" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="cond">
|
||||||
|
<span class="th">목록번호</span>
|
||||||
|
<input type="text" id="searchBbsno" name="searchBbsno" class="input" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="cond">
|
||||||
|
<span class="th">위반장소</span>
|
||||||
|
<input type="text" id="searchPos" name="searchPos" class="input" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="cond">
|
||||||
|
<span class="th">상세주소</span>
|
||||||
|
<input type="text" id="searchAddr" name="searchAddr" class="input" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="cond cond-button">
|
||||||
|
<span class="th"> </span>
|
||||||
|
<button type="button" id="search_btn" class="newbtnss bg1">검색</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="rig2">
|
||||||
|
<li>
|
||||||
|
<select id="perPageSelect" class="input">
|
||||||
|
<option value="10" <c:if test="${param.perPage eq '10'}">selected</c:if>>페이지당 10</option>
|
||||||
|
<option value="30" <c:if test="${empty param.perPage or param.perPage eq '30'}">selected</c:if>>페이지당 30</option>
|
||||||
|
<option value="100" <c:if test="${param.perPage eq '100'}">selected</c:if>>페이지당 100</option>
|
||||||
|
</select>
|
||||||
|
<span class="page_number">
|
||||||
|
<span id="currentPage"></span><span class="bar">/</span><span id="totalPages"></span> Pages
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="gs_booking">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="box_column">
|
||||||
|
<div class="containers">
|
||||||
|
<div id="grid"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.gs_b_top ul.lef-row1 {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gs_b_top ul.lef-row2 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr)); /* 4열 */
|
||||||
|
column-gap: 16px; /* 좌우 간격 */
|
||||||
|
row-gap: 6px; /* 위/아래 간격 */
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gs_b_top ul.lef-row2 li.cond {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gs_b_top ul.lef-row2 li.cond .th {
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-right: 4px;
|
||||||
|
min-width: 100px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gs_b_top ul.lef-row2 li.cond .input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.gs_b_top {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search_btn {
|
||||||
|
position: absolute;
|
||||||
|
right: 500px;
|
||||||
|
top: 65px;
|
||||||
|
z-index: 10;
|
||||||
|
height: 34px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gs_b_top {
|
||||||
|
padding-bottom: 6px !important;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gs_b_top ul.lef-row2 {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gs_booking {
|
||||||
|
margin-top: 30px !important;
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
let INIT_POPUP = null;
|
||||||
|
let SEARCH_COND = {};
|
||||||
|
let GRID = null;
|
||||||
|
|
||||||
|
function isTimeHHmm(value) {
|
||||||
|
const timeRegex = /^([01][0-9]|2[0-3])[0-5][0-9]$/;
|
||||||
|
return timeRegex.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 검색조건 세팅
|
||||||
|
let setSearchCond = function () {
|
||||||
|
let searchCondition = $.trim(nvl($("#searchCondition").val(), ""));
|
||||||
|
let searchKeyword = $.trim(nvl($("#searchKeyword").val(), ""));
|
||||||
|
let searchStartDt = $.trim(nvl($("#searchStartDt").val(), ""));
|
||||||
|
let searchEndDt = $.trim(nvl($("#searchEndDt").val(), ""));
|
||||||
|
let searchCondition1 = $.trim(nvl($("#searchCondition1").val(), ""));
|
||||||
|
let searchCondition2 = $.trim(nvl($("#searchCondition2").val(), ""));
|
||||||
|
let searchCondition3 = $.trim(nvl($("#searchCondition3").val(), ""));
|
||||||
|
let searchCondition4 = $.trim(nvl($("#searchCondition4").val(), ""));
|
||||||
|
let searchCarno = $.trim(nvl($("#searchCarno").val(), ""));
|
||||||
|
let searchName = $.trim(nvl($("#searchName").val(), ""));
|
||||||
|
let searchJno = $.trim(nvl($("#searchJno").val(), ""));
|
||||||
|
let searchUser = $.trim(nvl($("#searchUser").val(), ""));
|
||||||
|
let searchTel = $.trim(nvl($("#searchTel").val(), ""));
|
||||||
|
let searchBbsno = $.trim(nvl($("#searchBbsno").val(), ""));
|
||||||
|
let searchPos = $.trim(nvl($("#searchPos").val(), ""));
|
||||||
|
let searchAddr = $.trim(nvl($("#searchAddr").val(), ""));
|
||||||
|
let searchTime1 = $.trim(nvl($("#searchTime1").val(), ""));
|
||||||
|
let searchTime2 = $.trim(nvl($("#searchTime2").val(), ""));
|
||||||
|
|
||||||
|
SEARCH_COND.searchCondition = searchCondition;
|
||||||
|
SEARCH_COND.searchKeyword = searchKeyword;
|
||||||
|
SEARCH_COND.searchStartDt = searchStartDt;
|
||||||
|
SEARCH_COND.searchEndDt = searchEndDt;
|
||||||
|
SEARCH_COND.searchCondition1 = searchCondition1;
|
||||||
|
SEARCH_COND.searchCondition2 = searchCondition2;
|
||||||
|
SEARCH_COND.searchCondition3 = searchCondition3;
|
||||||
|
SEARCH_COND.searchCondition4 = searchCondition4;
|
||||||
|
SEARCH_COND.searchCarno = searchCarno;
|
||||||
|
SEARCH_COND.searchName = searchName;
|
||||||
|
SEARCH_COND.searchJno = searchJno;
|
||||||
|
SEARCH_COND.searchUser = searchUser;
|
||||||
|
SEARCH_COND.searchTel = searchTel;
|
||||||
|
SEARCH_COND.searchBbsno = searchBbsno;
|
||||||
|
SEARCH_COND.searchPos = searchPos;
|
||||||
|
SEARCH_COND.searchAddr = searchAddr;
|
||||||
|
SEARCH_COND.searchTime1 = searchTime1;
|
||||||
|
SEARCH_COND.searchTime2 = searchTime2;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const fnBiz = {
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
initGrid();
|
||||||
|
},
|
||||||
|
|
||||||
|
eventListener: () => {
|
||||||
|
|
||||||
|
// 검색 버튼
|
||||||
|
$('#search_btn').on('click', function () {
|
||||||
|
let startDate = $("#searchStartDt").val();
|
||||||
|
let endDate = $("#searchEndDt").val();
|
||||||
|
let startTime = $("#searchTime1").val();
|
||||||
|
let endTime = $("#searchTime2").val();
|
||||||
|
|
||||||
|
if ((startDate && !endDate) || (!startDate && endDate)) {
|
||||||
|
alert("등록일 검색 시 시작일과 종료일을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (startDate && endDate) {
|
||||||
|
if (!isDate(startDate) || !isDate(endDate)) {
|
||||||
|
alert("유효한 날짜 형식이 아닙니다. (YYYY-MM-DD)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let startDateObj = new Date(startDate);
|
||||||
|
let endDateObj = new Date(endDate);
|
||||||
|
if (startDateObj > endDateObj) {
|
||||||
|
alert("시작일은 종료일보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if ((startTime && !endTime) || (!startTime && endTime)) {
|
||||||
|
alert("위반시간 검색 시 시작시간과 종료시간을 모두 입력해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startTime && endTime) {
|
||||||
|
|
||||||
|
if (!isTimeHHmm(startTime) || !isTimeHHmm(endTime)) {
|
||||||
|
alert("시간은 0000 ~ 2359 형식으로 입력해주세요. (예: 0930)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseInt(startTime) > parseInt(endTime)) {
|
||||||
|
alert("시작시간은 종료시간보다 이후일 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$("#page").val(1);
|
||||||
|
GRID.readData(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 검색어 엔터
|
||||||
|
$('#searchKeyword').on('keypress', function (e) {
|
||||||
|
if (e.which === 13) {
|
||||||
|
e.preventDefault();
|
||||||
|
$('#search_btn').trigger('click');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// perPage 변경 이벤트 추가
|
||||||
|
$('#perPageSelect').on('change', () => {
|
||||||
|
const pagination = TuiGrid.instance.getPagination();
|
||||||
|
if (!pagination) return;
|
||||||
|
|
||||||
|
pagination.setItemsPerPage($('#perPageSelect').val());
|
||||||
|
pagination.reset(TuiGrid.instance.getRowCount());
|
||||||
|
pagination.movePageTo(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 상태 탭 클릭
|
||||||
|
$('.state-tabs li').on('click', function () {
|
||||||
|
$('.state-tabs li').removeClass('on');
|
||||||
|
$(this).addClass('on');
|
||||||
|
|
||||||
|
const state = $(this).data('state') || '';
|
||||||
|
$('#tabState').val(state);
|
||||||
|
|
||||||
|
SEARCH_COND = {};
|
||||||
|
GRID.readData(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** tui-grid Set */
|
||||||
|
const initGrid = () => {
|
||||||
|
|
||||||
|
const gridColumns = [
|
||||||
|
{ header: '자료출처', name: 'mmIngb', width: 150, align: 'center' },
|
||||||
|
{ header: '접수(위반)일시', name: 'mmDate', width: 150, align: 'center' },
|
||||||
|
{ header: '차량번호', name: 'mmCarno', width: 150, align: 'center' },
|
||||||
|
{ header: '신고자', name: 'asUser', width: 150, align: 'center' },
|
||||||
|
{ header: '접수번호', name: 'asJsno', width: 150, align: 'center' },
|
||||||
|
{ header: '접수일자', name: 'asJsdate', width: 150, align: 'center' },
|
||||||
|
{ header: '목록번호', name: 'asBbsNo', width: 150, align: 'center' },
|
||||||
|
{ header: '주민번호', name: 'omJno', width: 150, align: 'center' },
|
||||||
|
{ header: '소유자', name: 'omName', width: 150, align: 'center' },
|
||||||
|
{ header: '잔액', name: 'mmKeum2', width: 150, align: 'center' },
|
||||||
|
{ header: '영상매체', name: 'mmImageGb', width: 150, align: 'center' },
|
||||||
|
{ header: '사진', name: 'mmImageCnt', width: 150, align: 'center' },
|
||||||
|
{ header: '차량확인', name: 'mmCarcheck', width: 150, align: 'center' },
|
||||||
|
{ header: '처리상태', name: 'mmState', width: 150, align: 'center' },
|
||||||
|
{ header: '제외사유', name: 'ccCause', width: 150, align: 'center' },
|
||||||
|
{ header: '제외일자', name: 'ccDate', width: 150, align: 'center' },
|
||||||
|
{ header: '제외기타사항', name: 'ccEtc', width: 150, align: 'center' },
|
||||||
|
{ header: 'mmCode', name: 'mmCode', sortable: true, width: 150, align: 'center', hidden: true}
|
||||||
|
];
|
||||||
|
|
||||||
|
const gridDatasource = {
|
||||||
|
api: {
|
||||||
|
readData: {
|
||||||
|
url: '<c:url value="/search/filtersearch/filtersearch-select.ajax"/>',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
processData: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initialRequest: true,
|
||||||
|
serializer: function (params) {
|
||||||
|
setSearchCond();
|
||||||
|
SEARCH_COND.perPage = params.perPage;
|
||||||
|
SEARCH_COND.page = params.page;
|
||||||
|
|
||||||
|
return $.param(SEARCH_COND);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const perPage = parseInt($('#perPageSelect').val() || 10, 10);
|
||||||
|
|
||||||
|
const gridOptions = {
|
||||||
|
el: 'grid',
|
||||||
|
rowHeaders: ['checkbox'],
|
||||||
|
columns: gridColumns,
|
||||||
|
noData: "처리 할 초기자료가 없습니다.",
|
||||||
|
pageOptions: {
|
||||||
|
useClient: false,
|
||||||
|
perPage: perPage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 실제 GRID 생성
|
||||||
|
GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => {
|
||||||
|
// 서버 응답 후 페이지 정보 세팅
|
||||||
|
const data = res.data || {};
|
||||||
|
if (data.pagination) {
|
||||||
|
$("#currentPage").text(data.pagination.page || '');
|
||||||
|
$("#totalPages").text(data.pagination.totalPages || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 더블 클릭 이벤트
|
||||||
|
GRID.on("dblclick", (e) => {
|
||||||
|
var popUrl = '/minwon/init/init_popup.do';
|
||||||
|
var popTitle = "initPopup";
|
||||||
|
var popOption = "width=1400px, height=900px, resizable=yes, scrollbars=yes, location=no, top=100px, left=100px";
|
||||||
|
|
||||||
|
// 1) localStorage에 저장
|
||||||
|
console.log(e)
|
||||||
|
|
||||||
|
let cursor = e.instance.getValue(e.rowKey, 'mmCode');
|
||||||
|
let mmCodes = e.instance.getData().map(row => row.mmCode);
|
||||||
|
|
||||||
|
console.log(cursor);
|
||||||
|
|
||||||
|
const state = { cursor, mmCodes, savedAt: Date.now() };
|
||||||
|
localStorage.setItem('TOTAL_INFO_STATE', JSON.stringify(state));
|
||||||
|
|
||||||
|
// 2) 팝업이 없거나 닫혀 있으면 새로 열기
|
||||||
|
if (!INIT_POPUP || INIT_POPUP.closed) {
|
||||||
|
INIT_POPUP = window.open(popUrl, popTitle, popOption);
|
||||||
|
} else {
|
||||||
|
// 이미 떠 있으면 새로 안 만들고, 그 창에 포커스만 줌
|
||||||
|
INIT_POPUP.focus();
|
||||||
|
INIT_POPUP.INIT_POP_API.search();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 최초 1페이지 조회
|
||||||
|
GRID.readData(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 레디펑션
|
||||||
|
$(function () {
|
||||||
|
fnBiz.init();
|
||||||
|
fnBiz.eventListener();
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
.ui-dialog .ui-dialog-titlebar {
|
||||||
|
background: #202342;
|
||||||
|
color: #fff;
|
||||||
|
border-bottom: 1px solid #444;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-dialog .ui-dialog-title {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 닫기 버튼 기본 버튼 스타일 제거 */
|
||||||
|
.ui-dialog .ui-dialog-titlebar-close {
|
||||||
|
background: transparent !important;
|
||||||
|
border: none !important;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
right: 6px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 기존 jQuery UI 아이콘 완전히 숨김 */
|
||||||
|
.ui-dialog .ui-dialog-titlebar-close .ui-icon {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 텍스트 X 직접 그리기 */
|
||||||
|
.ui-dialog .ui-dialog-titlebar-close::before {
|
||||||
|
content: "✕";
|
||||||
|
color: #fff;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 45px;
|
||||||
|
text-align: center;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disdoc-btn-area {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disdoc-btn {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
@ -0,0 +1,374 @@
|
|||||||
|
|
||||||
|
/** totalInfo Start */
|
||||||
|
/* 팝업 기본 스타일 */
|
||||||
|
.popup_wrap {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_inner {
|
||||||
|
position: relative;
|
||||||
|
width: 97%;
|
||||||
|
max-width: 1200px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 1001;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 팝업 헤더 */
|
||||||
|
.popup_tit {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
background-color: #0d1342;
|
||||||
|
color: rgba(255, 255, 255, .9);
|
||||||
|
font-size: 15px;
|
||||||
|
padding: 15px 20px;
|
||||||
|
line-height: 1em;
|
||||||
|
position: relative;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_tit .tit {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: rgba(255, 255, 255, .9);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 팝업 컨텐츠 */
|
||||||
|
.popup_con {
|
||||||
|
padding: 15px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 팝업 내 테이블 셀 */
|
||||||
|
.popup_con td,
|
||||||
|
.popup_con th {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 팝업 내 힌트 메시지 */
|
||||||
|
.popup_con .hint-message {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 팝업 푸터 */
|
||||||
|
.popup_foot {
|
||||||
|
padding: 12px 15px;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid #e5e5e5;
|
||||||
|
background: #f9f9f9;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_foot .newbtn,
|
||||||
|
.popup_foot .newbtns {
|
||||||
|
min-width: 80px;
|
||||||
|
margin: 0 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 팝업 컨테이너 */
|
||||||
|
.auth-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
height: calc(100vh - 180px);
|
||||||
|
min-height: 450px;
|
||||||
|
max-height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 섹션 영역 공통 스타일 */
|
||||||
|
.group-selection-area,
|
||||||
|
.role-list-area,
|
||||||
|
.menu-tree-area {
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #e5e5e5;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
padding: 10px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
background: #f9f9f9;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 검색 영역 */
|
||||||
|
.search-box {
|
||||||
|
padding: 10px 12px;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box .input {
|
||||||
|
flex: 1;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 테이블 영역 */
|
||||||
|
.table_area {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 12px 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 메뉴 트리 영역 */
|
||||||
|
.menu-tree-container {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 12px 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-tree-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-tree-wrapper::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-tree-wrapper::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-tree-wrapper::-webkit-scrollbar-thumb {
|
||||||
|
background: #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-tree-wrapper::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 선택된 항목 스타일 */
|
||||||
|
#selectedGroupName,
|
||||||
|
#selectedRoleName {
|
||||||
|
color: #327fc8;
|
||||||
|
margin-left: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DataTables 커스텀 스타일 */
|
||||||
|
.dataTables_wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper .dataTables_scroll {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper .dataTables_scrollBody {
|
||||||
|
overflow-y: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper table.dataTable {
|
||||||
|
width: 100% !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper table.dataTable thead th {
|
||||||
|
background: #f9f9f9;
|
||||||
|
padding: 8px 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper table.dataTable tbody td {
|
||||||
|
padding: 6px 10px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper table.dataTable tbody tr {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper table.dataTable tbody tr:hover,
|
||||||
|
.dataTables_wrapper table.dataTable tbody tr.selected {
|
||||||
|
background-color: #ddedfd !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 메시지 스타일 */
|
||||||
|
.no-data-message {
|
||||||
|
padding: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #666;
|
||||||
|
background: #f9f9f9;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 8px 0;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
:root{
|
||||||
|
--green:#8bc34a; --border:#d9d9d9; --muted:#6b7280; --text:#111827;
|
||||||
|
--panel:#f7f7f7; --focus:rgba(37,99,235,.35); --warn:#fff3cd; --ok:#10b981;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 카드/헤더 */
|
||||||
|
.detail-card{border:1px solid var(--border); border-radius:10px; overflow:hidden; background:#fff;}
|
||||||
|
.detail-card .card-header{display:flex; justify-content:space-between; align-items:center; background:#202342; color:#fff; padding:10px 12px;}
|
||||||
|
.card-header .title{font-weight:700}
|
||||||
|
.card-header .actions{display:flex; gap:6px; align-items:center}
|
||||||
|
.pill{font-size:12px; background:rgba(255,255,255,.25); padding:3px 8px; border-radius:999px}
|
||||||
|
.btn,.nav-btn,.close-btn{border:1px solid rgba(0,0,0,.15); background:#fff; color:#333; padding:3px 8px; border-radius:6px; cursor:pointer; font-size:12px}
|
||||||
|
.btn:focus,.nav-btn:focus,.close-btn:focus{outline:none; box-shadow:0 0 0 3px var(--focus)}
|
||||||
|
|
||||||
|
/* 본문 레이아웃 */
|
||||||
|
.detail-body{display:grid; grid-template-columns: 3fr 1fr; gap:16px; padding:16px; background:var(--panel)}
|
||||||
|
.left,.right{background:#fff; border:1px solid var(--border); border-radius:8px; padding:12px}
|
||||||
|
.section-title{font-weight:700; margin-bottom:8px}
|
||||||
|
.subnote{font-size:12px; color:#888; text-align:right; margin-top:-4px; margin-bottom:8px}
|
||||||
|
|
||||||
|
/* 폼 그리드 */
|
||||||
|
/*.form-grid{display:grid; grid-template-columns: 110px 1fr 110px 1fr; gap:8px 10px}*/
|
||||||
|
/*.lbl{align-self:center; color:#444; font-size:13px}*/
|
||||||
|
/*.fld input,.fld textarea,.fld select{width:100%; padding:6px 8px; border:1px solid var(--border); border-radius:6px; font-size:13px; background:#fff}*/
|
||||||
|
/*.fld input[readonly],.fld textarea[readonly]{background:#fafafa}*/
|
||||||
|
/*.fld textarea{height:80px; resize:vertical}*/
|
||||||
|
/*.badge{display:inline-block; background:#eef2ff; color:#1d4ed8; border:1px solid #c7d2fe; padding:3px 8px; border-radius:999px; font-size:12px}*/
|
||||||
|
/*.hl{background:var(--warn)}*/
|
||||||
|
/*.block{grid-column: 1 / -1}*/
|
||||||
|
|
||||||
|
/** 플렉스 폼 start */
|
||||||
|
.form-grid {display: flex;flex-direction: column; row-gap: 8px;}
|
||||||
|
.form-row {display: flex;column-gap: 10px;}
|
||||||
|
.field-group {display: flex;align-items: center;flex: 1 1 0;min-width: 0;gap: 6px;}
|
||||||
|
.field-group .lbl {flex: 0 0 110px;color: #444;font-size: 13px;align-self: center;white-space: nowrap;font-weight: 400;}
|
||||||
|
.field-group .fld {flex: 1 1 0;}
|
||||||
|
.field-group .fld input, .field-group .fld textarea, .field-group .fld select {width: 100%;padding: 6px 8px;border: 1px solid var(--border);border-radius: 6px;font-size: 13px;background: #fff;box-sizing: border-box;}
|
||||||
|
.field-group .fld input[readonly], .field-group .fld textarea[readonly] {background: #fafafa;} .field-group .fld textarea {height: 80px;resize: vertical;} .form-row.block .field-group.full {flex: 1 1 100%;display: flex;align-items: flex-start;}
|
||||||
|
.form-row.block .field-group.full .lbl {margin-top: 4px;}
|
||||||
|
.field-group.empty {flex: 1 1 0;}
|
||||||
|
.badge {display: inline-block;background: #eef2ff;color: #1d4ed8;border: 1px solid #c7d2fe;padding: 3px 8px;border-radius: 999px;font-size: 12px;}
|
||||||
|
.hl {background: var(--warn);}
|
||||||
|
@media (max-width: 1200px) { .form-row {flex-direction: column;} }
|
||||||
|
/* 플렉스 폼 end */
|
||||||
|
|
||||||
|
.bar{height:1px; background:var(--border); margin:8px 0}
|
||||||
|
|
||||||
|
|
||||||
|
/* 하단 상태바 */
|
||||||
|
.statusbar{display:flex; align-items:center; justify-content:space-between; padding:8px 12px; border-top:1px solid var(--border); background:#fff}
|
||||||
|
.status-left{color:#0a7f2e; font-weight:700}
|
||||||
|
.status-right{display:flex; gap:14px; align-items:center; color:#333}
|
||||||
|
.count-dot{display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:999px; background:var(--ok); color:#fff; font-size:12px}
|
||||||
|
|
||||||
|
|
||||||
|
/* 우측 썸네일/지도/미리보기 */
|
||||||
|
.right .thumbs {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
max-height: 600px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 개별 썸네일 박스 */
|
||||||
|
.thumbs .thumb {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #f8f8f8;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 이미지 스타일 */
|
||||||
|
.thumbs .thumb img {
|
||||||
|
width: 100%;
|
||||||
|
height: 400%;
|
||||||
|
object-fit: cover; /* 비율 유지하며 꽉 채움 */
|
||||||
|
object-position: center;/* 중앙 기준 크롭 */
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.mapbox {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 8px
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapbox img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
border: 1px dashed var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
height: 220px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
background: #fafafa
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** totalInfo End */
|
||||||
|
|
||||||
@ -1,376 +1,57 @@
|
|||||||
|
/** dayanswer start */
|
||||||
|
|
||||||
/** totalInfo Start */
|
.state-tab-wrap {
|
||||||
/* 팝업 기본 스타일 */
|
margin: 10px 0;
|
||||||
.popup_wrap {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 1000;
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: center;
|
|
||||||
padding-top: 20px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup_inner {
|
|
||||||
position: relative;
|
|
||||||
width: 97%;
|
|
||||||
max-width: 1200px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
||||||
z-index: 1001;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 팝업 헤더 */
|
|
||||||
.popup_tit {
|
|
||||||
display: flex;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
background-color: #0d1342;
|
|
||||||
color: rgba(255, 255, 255, .9);
|
|
||||||
font-size: 15px;
|
|
||||||
padding: 15px 20px;
|
|
||||||
line-height: 1em;
|
|
||||||
position: relative;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup_tit .tit {
|
.state-tabs {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: rgba(255, 255, 255, .9);
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 팝업 컨텐츠 */
|
|
||||||
.popup_con {
|
|
||||||
padding: 15px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 팝업 내 테이블 셀 */
|
|
||||||
.popup_con td,
|
|
||||||
.popup_con th {
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 팝업 내 힌트 메시지 */
|
|
||||||
.popup_con .hint-message {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #666;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 팝업 푸터 */
|
|
||||||
.popup_foot {
|
|
||||||
padding: 12px 15px;
|
|
||||||
text-align: center;
|
|
||||||
border-top: 1px solid #e5e5e5;
|
|
||||||
background: #f9f9f9;
|
|
||||||
border-radius: 0 0 4px 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup_foot .newbtn,
|
|
||||||
.popup_foot .newbtns {
|
|
||||||
min-width: 80px;
|
|
||||||
margin: 0 4px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 팝업 컨테이너 */
|
|
||||||
.auth-container {
|
|
||||||
display: flex;
|
|
||||||
gap: 15px;
|
|
||||||
height: calc(100vh - 180px);
|
|
||||||
min-height: 450px;
|
|
||||||
max-height: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 섹션 영역 공통 스타일 */
|
|
||||||
.group-selection-area,
|
|
||||||
.role-list-area,
|
|
||||||
.menu-tree-area {
|
|
||||||
flex: 1;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #e5e5e5;
|
|
||||||
border-radius: 4px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
min-width: 0;
|
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title {
|
.state-tabs li {
|
||||||
padding: 10px 12px;
|
padding: 6px 14px;
|
||||||
font-size: 13px;
|
border: 1px solid #ccc;
|
||||||
font-weight: 500;
|
border-bottom: none;
|
||||||
color: #333;
|
background: #f5f5f5;
|
||||||
border-bottom: 1px solid #e5e5e5;
|
|
||||||
background: #f9f9f9;
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 검색 영역 */
|
|
||||||
.search-box {
|
|
||||||
padding: 10px 12px;
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box .input {
|
|
||||||
flex: 1;
|
|
||||||
height: 32px;
|
|
||||||
padding: 0 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 테이블 영역 */
|
|
||||||
.table_area {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 12px 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 메뉴 트리 영역 */
|
|
||||||
.menu-tree-container {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 12px 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-tree-wrapper {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
padding: 0;
|
|
||||||
background: #fff;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-tree-wrapper::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-tree-wrapper::-webkit-scrollbar-track {
|
|
||||||
background: #f1f1f1;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-tree-wrapper::-webkit-scrollbar-thumb {
|
|
||||||
background: #ccc;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-tree-wrapper::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 선택된 항목 스타일 */
|
|
||||||
#selectedGroupName,
|
|
||||||
#selectedRoleName {
|
|
||||||
color: #327fc8;
|
|
||||||
margin-left: 6px;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
|
||||||
|
|
||||||
/* DataTables 커스텀 스타일 */
|
|
||||||
.dataTables_wrapper {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_wrapper .dataTables_scroll {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_wrapper .dataTables_scrollBody {
|
|
||||||
overflow-y: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_wrapper table.dataTable {
|
|
||||||
width: 100% !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_wrapper table.dataTable thead th {
|
|
||||||
background: #f9f9f9;
|
|
||||||
padding: 8px 10px;
|
|
||||||
font-weight: 500;
|
|
||||||
border-bottom: 1px solid #e5e5e5;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_wrapper table.dataTable tbody td {
|
|
||||||
padding: 6px 10px;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_wrapper table.dataTable tbody tr {
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_wrapper table.dataTable tbody tr:hover,
|
.state-tabs li.on {
|
||||||
.dataTables_wrapper table.dataTable tbody tr.selected {
|
background: #ffffff;
|
||||||
background-color: #ddedfd !important;
|
font-weight: bold;
|
||||||
}
|
border-bottom: 1px solid #ffffff;
|
||||||
|
|
||||||
/* 메시지 스타일 */
|
|
||||||
.no-data-message {
|
|
||||||
padding: 15px;
|
|
||||||
text-align: center;
|
|
||||||
color: #666;
|
|
||||||
background: #f9f9f9;
|
|
||||||
border-radius: 3px;
|
|
||||||
margin: 8px 0;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
:root{
|
|
||||||
--green:#8bc34a; --border:#d9d9d9; --muted:#6b7280; --text:#111827;
|
|
||||||
--panel:#f7f7f7; --focus:rgba(37,99,235,.35); --warn:#fff3cd; --ok:#10b981;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 카드/헤더 */
|
|
||||||
.detail-card{border:1px solid var(--border); border-radius:10px; overflow:hidden; background:#fff;}
|
|
||||||
.detail-card .card-header{display:flex; justify-content:space-between; align-items:center; background:#202342; color:#fff; padding:10px 12px;}
|
|
||||||
.card-header .title{font-weight:700}
|
|
||||||
.card-header .actions{display:flex; gap:6px; align-items:center}
|
|
||||||
.pill{font-size:12px; background:rgba(255,255,255,.25); padding:3px 8px; border-radius:999px}
|
|
||||||
.btn,.nav-btn,.close-btn{border:1px solid rgba(0,0,0,.15); background:#fff; color:#333; padding:3px 8px; border-radius:6px; cursor:pointer; font-size:12px}
|
|
||||||
.btn:focus,.nav-btn:focus,.close-btn:focus{outline:none; box-shadow:0 0 0 3px var(--focus)}
|
|
||||||
|
|
||||||
/* 본문 레이아웃 */
|
|
||||||
.detail-body{display:grid; grid-template-columns: 3fr 1fr; gap:16px; padding:16px; background:var(--panel)}
|
|
||||||
.left,.right{background:#fff; border:1px solid var(--border); border-radius:8px; padding:12px}
|
|
||||||
.section-title{font-weight:700; margin-bottom:8px}
|
|
||||||
.subnote{font-size:12px; color:#888; text-align:right; margin-top:-4px; margin-bottom:8px}
|
|
||||||
|
|
||||||
/* 폼 그리드 */
|
|
||||||
/*.form-grid{display:grid; grid-template-columns: 110px 1fr 110px 1fr; gap:8px 10px}*/
|
|
||||||
/*.lbl{align-self:center; color:#444; font-size:13px}*/
|
|
||||||
/*.fld input,.fld textarea,.fld select{width:100%; padding:6px 8px; border:1px solid var(--border); border-radius:6px; font-size:13px; background:#fff}*/
|
|
||||||
/*.fld input[readonly],.fld textarea[readonly]{background:#fafafa}*/
|
|
||||||
/*.fld textarea{height:80px; resize:vertical}*/
|
|
||||||
/*.badge{display:inline-block; background:#eef2ff; color:#1d4ed8; border:1px solid #c7d2fe; padding:3px 8px; border-radius:999px; font-size:12px}*/
|
|
||||||
/*.hl{background:var(--warn)}*/
|
|
||||||
/*.block{grid-column: 1 / -1}*/
|
|
||||||
|
|
||||||
/** 플렉스 폼 start */
|
|
||||||
.form-grid {display: flex;flex-direction: column; row-gap: 8px;}
|
|
||||||
.form-row {display: flex;column-gap: 10px;}
|
|
||||||
.field-group {display: flex;align-items: center;flex: 1 1 0;min-width: 0;gap: 6px;}
|
|
||||||
.field-group .lbl {flex: 0 0 110px;color: #444;font-size: 13px;align-self: center;white-space: nowrap;font-weight: 400;}
|
|
||||||
.field-group .fld {flex: 1 1 0;}
|
|
||||||
.field-group .fld input, .field-group .fld textarea, .field-group .fld select {width: 100%;padding: 6px 8px;border: 1px solid var(--border);border-radius: 6px;font-size: 13px;background: #fff;box-sizing: border-box;}
|
|
||||||
.field-group .fld input[readonly], .field-group .fld textarea[readonly] {background: #fafafa;} .field-group .fld textarea {height: 80px;resize: vertical;} .form-row.block .field-group.full {flex: 1 1 100%;display: flex;align-items: flex-start;}
|
|
||||||
.form-row.block .field-group.full .lbl {margin-top: 4px;}
|
|
||||||
.field-group.empty {flex: 1 1 0;}
|
|
||||||
.badge {display: inline-block;background: #eef2ff;color: #1d4ed8;border: 1px solid #c7d2fe;padding: 3px 8px;border-radius: 999px;font-size: 12px;}
|
|
||||||
.hl {background: var(--warn);}
|
|
||||||
@media (max-width: 1200px) { .form-row {flex-direction: column;} }
|
|
||||||
/* 플렉스 폼 end */
|
|
||||||
|
|
||||||
.bar{height:1px; background:var(--border); margin:8px 0}
|
|
||||||
|
|
||||||
|
|
||||||
/* 하단 상태바 */
|
|
||||||
.statusbar{display:flex; align-items:center; justify-content:space-between; padding:8px 12px; border-top:1px solid var(--border); background:#fff}
|
|
||||||
.status-left{color:#0a7f2e; font-weight:700}
|
|
||||||
.status-right{display:flex; gap:14px; align-items:center; color:#333}
|
|
||||||
.count-dot{display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:999px; background:var(--ok); color:#fff; font-size:12px}
|
|
||||||
|
|
||||||
|
|
||||||
/* 우측 썸네일/지도/미리보기 */
|
|
||||||
.right .thumbs {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
max-height: 600px;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding-right: 8px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
|
.state-area {
|
||||||
/* 개별 썸네일 박스 */
|
margin-top: 10px;
|
||||||
.thumbs .thumb {
|
padding: 10px 0;
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 8px;
|
|
||||||
width: 100%;
|
|
||||||
height: 200px;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #f8f8f8;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 이미지 스타일 */
|
.state-label {
|
||||||
.thumbs .thumb img {
|
font-weight: bold;
|
||||||
width: 100%;
|
margin-right: 5px;
|
||||||
height: 400%;
|
white-space: nowrap;
|
||||||
object-fit: cover; /* 비율 유지하며 꽉 채움 */
|
|
||||||
object-position: center;/* 중앙 기준 크롭 */
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.state-input {
|
||||||
.mapbox {
|
width: 120px;
|
||||||
border: 1px solid var(--border);
|
height: 28px;
|
||||||
border-radius: 6px;
|
padding: 4px;
|
||||||
overflow: hidden;
|
border: 1px solid #ccc;
|
||||||
margin-top: 8px
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapbox img {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: auto
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview {
|
.state-area button {
|
||||||
border: 1px dashed var(--border);
|
height: 32px;
|
||||||
border-radius: 6px;
|
padding: 0 12px;
|
||||||
height: 220px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
background: #fafafa
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview img {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
display: block
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** dayanswer end */
|
||||||
|
|
||||||
/** totalInfo End */
|
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package go.kr.project.domain.entity;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.EmbeddedId;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "cp_cancel_answer")
|
||||||
|
@Getter
|
||||||
|
public class CpCancelAnswer {
|
||||||
|
|
||||||
|
@EmbeddedId
|
||||||
|
private CpCancelAnswerId id;
|
||||||
|
|
||||||
|
@Column(name = "CA_ID", length = 50)
|
||||||
|
private String caId;
|
||||||
|
|
||||||
|
@Column(name = "CA_ISANSWER", length = 1)
|
||||||
|
private String caIsAnswer;
|
||||||
|
|
||||||
|
@Column(name = "CA_ANSWERTEXT", length = 50)
|
||||||
|
private String caAnswerText;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package go.kr.project.domain.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class CpCancelAnswerId implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Column(name = "CA_SGGCODE", length = 5, nullable = false)
|
||||||
|
private String caSggCode;
|
||||||
|
|
||||||
|
@Column(name = "CA_CODE", length = 3, nullable = false)
|
||||||
|
private String caCode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package go.kr.project.domain.entity;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.EmbeddedId;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "cp_cancel_answer")
|
||||||
|
@Getter
|
||||||
|
public class CpCancelAnswer {
|
||||||
|
|
||||||
|
@EmbeddedId
|
||||||
|
private CpCancelAnswerId id;
|
||||||
|
|
||||||
|
@Column(name = "nrcg_rsnnm", length = 50)
|
||||||
|
private String caId;
|
||||||
|
|
||||||
|
@Column(name = "nrcgans_yn", length = 1)
|
||||||
|
private String caIsAnswer;
|
||||||
|
|
||||||
|
@Column(name = "nrcgans_cn", length = 50)
|
||||||
|
private String caAnswerText;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package go.kr.project.domain.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class CpCancelAnswerId implements Serializable {
|
||||||
|
|
||||||
|
@Column(name = "sggcd", length = 5, nullable = false)
|
||||||
|
private String caSggCode;
|
||||||
|
|
||||||
|
@Column(name = "nrcgans_id", length = 3, nullable = false)
|
||||||
|
private String caCode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue