Compare commits

...
2 Commits
Author SHA1 Message Date
ChooSeongBin e047865657 소스정리 2026-07-29 14:25:05 +09:00
ChooSeongBin 290928a839 소스정리 2026-07-29 10:24:43 +09:00
23 changed files with 963 additions and 51 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,8 @@
package net.jwsi.jcms.vpp.api; package net.jwsi.jcms.vpp.api;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import net.jwsi.jcms.vpp.charger.Chgr; import net.jwsi.jcms.vpp.chgr.ChgrResponseDto;
import net.jwsi.jcms.vpp.chgrHist.ChgrHistResponseDto;
import net.jwsi.jcms.vpp.provider.ProviderDto; import net.jwsi.jcms.vpp.provider.ProviderDto;
import net.jwsi.jcms.vpp.station.StationDto; import net.jwsi.jcms.vpp.station.StationDto;
import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ParameterizedTypeReference;
@@ -12,6 +13,7 @@ import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI; import java.net.URI;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -46,16 +48,35 @@ public class ApiClient {
.body(new ParameterizedTypeReference<ApiResponse<List<ProviderDto>>>() {}); .body(new ParameterizedTypeReference<ApiResponse<List<ProviderDto>>>() {});
} }
public ApiResponse<List<Chgr>> fetchChgr(String baseUrl, String token) { public ApiResponse<List<ChgrResponseDto>> fetchChgr(String baseUrl, String token) {
URI uri = UriComponentsBuilder.fromUriString(baseUrl) URI uri = UriComponentsBuilder.fromUriString(baseUrl)
.path("/api/charge/list") .path("/api/charger/list")
.build() .build()
.toUri(); .toUri();
return restClient.post() return restClient.post()
.uri(uri) .uri(uri)
.header("Authorization", "Bearer " + token) .header("Authorization", "Bearer " + token)
.body(Collections.emptyMap())
.retrieve() .retrieve()
.body(new ParameterizedTypeReference<ApiResponse<List<Chgr>>>() {}); .body(new ParameterizedTypeReference<ApiResponse<List<ChgrResponseDto>>>() {});
}
public ApiResponse<List<ChgrHistResponseDto>> fetchChgrHist(String baseUrl, String token) {
URI uri = UriComponentsBuilder.fromUriString(baseUrl)
.path("/api/charge/hist")
.build()
.toUri();
Map<String, String> requestBody = Map.of(
"startDt", "2026-07-29",
"pageSize","50"
);
return restClient.post()
.uri(uri)
.header("Authorization", "Bearer " + token)
.body(requestBody)
.retrieve()
.body(new ParameterizedTypeReference<ApiResponse<List<ChgrHistResponseDto>>>() {});
} }
} }
@@ -14,7 +14,7 @@ public class RestClientConfig {
public RestClient restClient() { public RestClient restClient() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout((int) Duration.ofSeconds(5).toMillis()); factory.setConnectTimeout((int) Duration.ofSeconds(5).toMillis());
factory.setReadTimeout((int) Duration.ofSeconds(10).toMillis()); factory.setReadTimeout((int) Duration.ofSeconds(30).toMillis());
return RestClient.builder() return RestClient.builder()
.requestFactory(factory) .requestFactory(factory)
@@ -1,26 +0,0 @@
package net.jwsi.jcms.vpp.charger;
import net.jwsi.jcms.base.BaseController;
import net.jwsi.jcms.exception.JsonDataException;
import org.springframework.stereotype.Controller;
import java.util.List;
@Controller
public class ChgrController extends BaseController<Chgr,String,ChgrRepository,ChgrService> {
public ChgrController(ChgrService service) {
super(service);
}
@Override
protected void chkSelectList(List list) throws JsonDataException {
}
@Override
protected void chkSelect(Chgr data) throws JsonDataException {
}
}
@@ -1,5 +1,6 @@
package net.jwsi.jcms.vpp.charger; package net.jwsi.jcms.vpp.chgr;
import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import lombok.Getter; import lombok.Getter;
@@ -15,13 +16,15 @@ import net.jwsi.jcms.base.BaseStEntity;
@Entity(name = "vpp_chgr") @Entity(name = "vpp_chgr")
public class Chgr extends BaseStEntity { public class Chgr extends BaseStEntity {
@Id @Id
@Column(name = "CHGR_ID")
private String chgrId; //충전기 id(pk) private String chgrId; //충전기 id(pk)
@Column(name = "PROVIDER_ID")
private String providerId; //충전사업자 id(pk) @Id private String providerId; //충전사업자 id(pk) @Id
private String stId; //충전소 id(pk) @Id private String stId; //충전소 id(pk) @Id
private String stNm; //충전소 private String stNm; //충전소
private String chgrNm; //충전기 private String chgrNm; //충전기
private String speedTpCd; //충전기속도 코드 private String speedTp; //충전기속도 코드
private String chgrTypeCd; //충전기타입 코드 private String chgrTp; //충전기타입 코드
} }
@@ -0,0 +1,72 @@
package net.jwsi.jcms.vpp.chgr;
import lombok.extern.slf4j.Slf4j;
import net.jwsi.jcms.base.BaseController;
import net.jwsi.jcms.exception.JsonDataException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
@Controller
@Slf4j
@RequestMapping("/cms/chgr")
public class ChgrController extends BaseController<Chgr,String,ChgrRepository,ChgrService> {
private final String path = "/system/chgr/";
private final ChgrService chgrService;
public ChgrController(ChgrService service, ChgrService chgrService) {
super(service);
this.chgrService = chgrService;
}
@GetMapping("list")
public String list(){
return path+"list";
}
@PostMapping("list.json")
@ResponseBody
public Map<String,Object> list(Chgr chgr){
return svcSelectList(chgr);
}
@PostMapping("view.json")
@ResponseBody
public Map<String, Object> viewData(Chgr chgr) throws JsonDataException {
return svcSelectOne(chgr);
}
@PostMapping("insert.json")
@ResponseBody
public Map<String, Object> insert(Chgr chgr) throws JsonDataException {
return svcInsert(chgr);
}
@PostMapping("update.json")
@ResponseBody
public Map<String, Object> update(Chgr chgr) throws JsonDataException {
return svcUpdate(chgr);
}
@PostMapping("delete.json")
@ResponseBody
public Map<String, Object> delete(Chgr chgr) throws JsonDataException {
return svcDelete(chgr.getChgrId());
}
@Override
protected void chkSelectList(List list) throws JsonDataException {
}
@Override
protected void chkSelect(Chgr data) throws JsonDataException {
}
}
@@ -1,4 +1,4 @@
package net.jwsi.jcms.vpp.charger; package net.jwsi.jcms.vpp.chgr;
import net.jwsi.jcms.base.BaseRecStRepository; import net.jwsi.jcms.base.BaseRecStRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@@ -1,18 +1,18 @@
package net.jwsi.jcms.vpp.charger; package net.jwsi.jcms.vpp.chgr;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@Getter @Getter
@Setter @Setter
public class ResponseDto { public class ChgrResponseDto {
private String providerId; private String providerId;
private String stId; private String stId;
private String stNm; private String stNm;
private String chgrId; private String chgrId;
private String chgrNm; private String chgrNm;
private String speedTp; private String speedTp;
private String chgrType; private String chgrTp;
private double gpsXpos; private double gpsXpos;
private double gpsYpos; private double gpsYpos;
private String locInfo; private String locInfo;
@@ -24,11 +24,12 @@ public class ResponseDto {
public Chgr toEntity(){ public Chgr toEntity(){
Chgr chgr = new Chgr(); Chgr chgr = new Chgr();
chgr.setChgrId(this.chgrId); chgr.setChgrId(this.chgrId);
chgr.setProviderId(this.providerId);
chgr.setStId(this.stId); chgr.setStId(this.stId);
chgr.setStNm(this.stNm); chgr.setStNm(this.stNm);
chgr.setChgrNm(this.chgrNm); chgr.setChgrNm(this.chgrNm);
chgr.setSpeedTpCd(this.speedTp); chgr.setSpeedTp(this.speedTp);
chgr.setChgrTypeCd(this.chgrType); chgr.setChgrTp(this.chgrTp);
return chgr; return chgr;
} }
} }
@@ -1,17 +1,22 @@
package net.jwsi.jcms.vpp.charger; package net.jwsi.jcms.vpp.chgr;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.jwsi.jcms.base.BaseService; import net.jwsi.jcms.base.BaseService;
import net.jwsi.jcms.base.EnumSqlType; import net.jwsi.jcms.base.EnumSqlType;
import net.jwsi.jcms.utils.HttpUtil; import net.jwsi.jcms.utils.HttpUtil;
import net.jwsi.jcms.utils.LoginUtil; import net.jwsi.jcms.utils.LoginUtil;
import net.jwsi.jcms.vpp.api.ApiClient; import net.jwsi.jcms.vpp.api.ApiClient;
import net.jwsi.jcms.vpp.api.ApiResponse;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
@Service @Service
@Slf4j @Slf4j
public class ChgrService extends BaseService<Chgr,String,ChgrRepository> { public class ChgrService extends BaseService<Chgr,String,ChgrRepository> {
@@ -26,7 +31,30 @@ public class ChgrService extends BaseService<Chgr,String,ChgrRepository> {
super(repository); super(repository);
this.apiClient = apiClient; this.apiClient = apiClient;
} }
@Transactional
@Scheduled(cron = "0 0 0 * * *")
public void getCharger() {
ApiResponse<List<ChgrResponseDto>> response = apiClient.fetchChgr(baseUrl, apiToken);
if (response == null || !Integer.valueOf(200).equals(response.getCode())) {
String msg = (response != null) ? response.getMessage() : "응답 없음";
throw new RuntimeException("API 호출 실패: " + msg);
}
List<ChgrResponseDto> dtoList = response.getData();
if (dtoList == null || dtoList.isEmpty()) {
log.info("가져온 충전소 데이터가 없습니다.");
}
List<Chgr> entityList = dtoList.stream()
.map(ChgrResponseDto::toEntity)
.collect(Collectors.toList());
List<Chgr> savedStations = super.repository.saveAll(entityList);
log.info("총 {}건의 충전소 데이터가 DB에 동기화되었습니다.", savedStations.size());
}
@Override @Override
protected Integer getUserId() { protected Integer getUserId() {
@@ -1,4 +1,4 @@
package net.jwsi.jcms.vpp.charger; package net.jwsi.jcms.vpp.chgr;
public class ChgrSpecification { public class ChgrSpecification {
} }
@@ -0,0 +1,51 @@
package net.jwsi.jcms.vpp.chgrHist;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import net.jwsi.jcms.base.BaseStEntity;
@NoArgsConstructor
@Setter
@Getter
@ToString
@Entity(name="vpp_chgr_hist")
public class ChgrHist extends BaseStEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CHGR_HIST_ID")
private Integer chgrHistId; // 충전이력 id
@Column(name = "CHGR_ID", nullable = false)
private String chgrId; // 충전기 id
@Column(name = "ST_ID", nullable = false)
private String stId; // 충전소 id
@Column(name = "PAY_TP")
private String payTp; // 결제구분
@Column(name = "PLUG_TP")
private String plugTp; // 충전기타입 코드
@Column(name = "RECHG_S_DT")
private String rechgSDt; // 충전 시작일시 (rechgsdt -> RECHG_S_DT 매핑)
@Column(name = "RECHG_E_DT")
private String rechgEDt; // 충전 종료일시 (rechgedt -> RECHG_E_DT 매핑)
@Column(name = "RECHG_TIME")
private String rechgTime; // 충전시간
@Column(name = "RECH_GWH")
private Integer rechGwh; // 충전량
@Column(name = "RECHG_AMT")
private Integer rechgAmt; // 충전금액
@Column(name = "PAY_FNSH")
private String payFnsh; // 신용결제완료구분
}
@@ -0,0 +1,64 @@
package net.jwsi.jcms.vpp.chgrHist;
import lombok.extern.slf4j.Slf4j;
import net.jwsi.jcms.base.BaseController;
import net.jwsi.jcms.exception.JsonDataException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/cms/chgrHist")
@Slf4j
public class ChgrHistController extends BaseController<ChgrHist,Integer,ChgrHistRepository,ChgrHistService> {
private final String path = "/system/chgrHist/";
private final ChgrHistService chgrHistService;
public ChgrHistController(ChgrHistService service, ChgrHistService chgrHistService) {
super(service);
this.chgrHistService = chgrHistService;
}
@GetMapping("list")
public String list() throws IllegalAccessException {
return path+"list";
}
@PostMapping("list.json")
@ResponseBody
public Map<String,Object> list(ChgrHist chgrHist){
return svcSelectList(chgrHist);
}
@PostMapping("insert.json")
@ResponseBody
public Map<String,Object> insert(ChgrHist chgrHist){
return svcInsert(chgrHist);
}
@PostMapping("delete.json")
@ResponseBody
public Map<String,Object> delete(ChgrHist chgrHist){
return svcDelete(chgrHist.getChgrHistId());
}
@PostMapping("update.json")
@ResponseBody
public Map<String,Object> update(ChgrHist chgrHist){
return svcUpdate(chgrHist);
}
@PostMapping("view.json")
@ResponseBody
public Map<String,Object> view(ChgrHist chgrHist){
return svcSelectOne(chgrHist);
}
@Override
protected void chkSelectList(List<ChgrHist> list) throws JsonDataException {
}
@Override
protected void chkSelect(ChgrHist data) throws JsonDataException {
}
}
@@ -0,0 +1,8 @@
package net.jwsi.jcms.vpp.chgrHist;
import net.jwsi.jcms.base.BaseRecStRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ChgrHistRepository extends BaseRecStRepository<ChgrHist,Integer> {
}
@@ -0,0 +1,57 @@
package net.jwsi.jcms.vpp.chgrHist;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ChgrHistResponseDto {
private String providerId; // 충전사업자 ID (Length: 2)
private String stId; // 충전소 ID (Length: 6)
private String chgrId; // 충전기 ID (Length: 2)
private String speedTp; // 충전 속도 (급속, 완속)
private Integer chId; // 채널 ID
private String plugType; // 플러그 타입
private String memAuthInputNo; // 회원카드번호 (Length: 16)
private String creditPPayTrxNo; // 선결제 관련 신용카드 승인번호 (Length: 20)
private String creditPPayTrxDt; // 선결제 관련 신용카드 승인일시 (yyyy-MM-dd HH:mm:ss)
private String rechgSdt; // 충전 시작일시 (yyyy-MM-dd HH:mm:ss)
private String rechgEdt; // 충전 종료일시 (yyyy-MM-dd HH:mm:ss)
private String rechgTime; // 충전시간 (Length: 10)
private Integer rechgWh; // 충전량(wh)
private Integer rechgDemandAmt; // 선결제 금액
private Integer rechgAmt; // 충전 금액
private Integer cancelAmt; // 취소 금액
private String payType; // 결제 타입 (회원카드, 신용카드, 무과금)
private String rechgFnshTp; // 충전 완료 구분
private String payFnsh; // 결제 완료 구분 (결제완료, 결제실패, 기타결제, 알수없음)
@JsonProperty("IntegratedWh")
private JsonNode integratedWh;
private Double dcPowerWh; // DC 적산량(wh)
private Double acPowerWh; // AC 적산량(wh)
public ChgrHist toEntity() {
ChgrHist chgrHist = new ChgrHist();
chgrHist.setChgrId(this.chgrId);
chgrHist.setStId(this.stId);
chgrHist.setPayTp(this.payType);
chgrHist.setPlugTp(this.plugType);
chgrHist.setRechgSDt(this.rechgSdt);
chgrHist.setRechgEDt(this.rechgEdt);
chgrHist.setRechgTime(this.rechgTime);
chgrHist.setRechgAmt(this.rechgAmt);
chgrHist.setPayFnsh(this.payFnsh);
chgrHist.setRechGwh(this.rechgWh);
return chgrHist;
}
}
@@ -0,0 +1,103 @@
package net.jwsi.jcms.vpp.chgrHist;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import net.jwsi.jcms.base.BaseService;
import net.jwsi.jcms.base.EnumSqlType;
import net.jwsi.jcms.utils.HttpUtil;
import net.jwsi.jcms.utils.LoginUtil;
import net.jwsi.jcms.vpp.api.ApiClient;
import net.jwsi.jcms.vpp.api.ApiResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class ChgrHistService extends BaseService<ChgrHist, Integer, ChgrHistRepository> {
private final ApiClient apiClient;
@Value("${jcms.api.base-url}")
private String baseUrl;
@Value("${jcms.api.token}")
private String apiToken;
public ChgrHistService(ChgrHistRepository repository, ApiClient apiClient) {
super(repository);
this.apiClient = apiClient;
}
@Transactional
@Scheduled(cron = "0 */10 * * * *")
public void getChgrHist() throws IllegalAccessException {
ApiResponse<List<ChgrHistResponseDto>> response = apiClient.fetchChgrHist(baseUrl, apiToken);
if (response == null || !Integer.valueOf(200).equals(response.getCode())) {
String msg = (response != null) ? response.getMessage() : "응답 없음";
throw new RuntimeException("API 호출 실패: " + msg);
}
List<ChgrHistResponseDto> dtoList = response.getData();
if (dtoList == null || dtoList.isEmpty()) {
log.info("가져온 충전소 데이터가 없습니다.");
}
List<ChgrHist> entityList = dtoList.stream()
.map(ChgrHistResponseDto::toEntity)
.toList();
List<ChgrHist> updateList = new ArrayList<>();
for (ChgrHist h : entityList) {
update(h);
updateList.add(h);
}
log.info("총 {}건의 충전소 데이터가 DB에 동기화되었습니다.", updateList.size());
}
@Override
protected Integer getUserId() {
return HttpUtil.getUserId();
}
@Override
protected String getUserName(Integer id) {
return LoginUtil.getUserName(id);
}
@Override
protected ChgrHist newSearchParam(ChgrHist chgrHist) {
if (chgrHist == null) {
chgrHist = new ChgrHist();
}
return chgrHist;
}
@Override
protected EnumSqlType useSqlTyp() {
return EnumSqlType.SPECIFICATION;
}
@Override
protected Specification<ChgrHist> getSpecification(ChgrHist chgrHist) {
return null;
}
@Override
protected Page<ChgrHist> _selectPage(ChgrHist chgrHist) {
return null;
}
@Override
protected List<ChgrHist> _selectList(ChgrHist chgrHist) {
return null;
}
}
@@ -15,7 +15,7 @@ import net.jwsi.jcms.base.BaseStEntity;
public class Station extends BaseStEntity { public class Station extends BaseStEntity {
@Id @Id
@Column(name = "st_id") @Column(name = "ST_ID")
private String stationId; private String stationId;
@Column(name = "PROVIDER_ID") @Column(name = "PROVIDER_ID")
@@ -36,19 +36,19 @@ public class Station extends BaseStEntity {
@Column(name = "ADDR_LD_D") @Column(name = "ADDR_LD_D")
private String addrLdD; private String addrLdD;
@Column(name = "st_facil_tp_cd") @Column(name = "ST_FACIL_TP")
private String stFacilTpCd; private String stFacilTp;
@Column(name = "st_facil_d_tp_cd") @Column(name = "ST_FACIL_D_TP")
private String stFacilDTpCd; private String stFacilDTp;
@Column(name = "parking_fee_yn") @Column(name = "PARKING_FEE_YN")
private String parkingFeeYn; private String parkingFeeYn;
@Column(name = "PARKING_FEE_DETL") @Column(name = "PARKING_FEE_DETL")
private String parkingFeeDetl; private String parkingFeeDetl;
@Column(name = "pnu_no") @Column(name = "PNU_NO")
private String pnuNo; private String pnuNo;
@Column(name = "PNU_DO_NM") @Column(name = "PNU_DO_NM")
@@ -33,8 +33,8 @@ public class StationDto {
station.setAddrLdM(ldParts[0]); station.setAddrLdM(ldParts[0]);
station.setAddrLdD(ldParts[1]); station.setAddrLdD(ldParts[1]);
station.setStFacilTpCd(this.stFacilTp); station.setStFacilTp(this.stFacilTp);
station.setStFacilDTpCd(this.stFacilDTp); station.setStFacilDTp(this.stFacilDTp);
station.setParkingFeeYn(this.parkingFee); station.setParkingFeeYn(this.parkingFee);
station.setParkingFeeDetl(this.parkingFeeDetl != null ? this.parkingFeeDetl : ""); station.setParkingFeeDetl(this.parkingFeeDetl != null ? this.parkingFeeDetl : "");
@@ -0,0 +1,233 @@
<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/cmsLayout}">
<body>
<section layout:fragment="Content">
<div class="w-100" style="margin-bottom: .3rem;">
<div th:replace="~{common/fragments/searchBox :: SearchBoxFragment(~{ :: #searchBoxContent}, ~{ :: #searchBoxFooter})}">
<div id="searchBoxContent">
<div class="row px-2">
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:140px">충전사업자 ID</span>
<input type="text" id="providerIdLike" name="providerIdLike" class="form-control" placeholder="충전사업자 ID 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:140px">충전소 ID</span>
<input type="text" id="stIdLike" name="stIdLike" class="form-control" placeholder="충전소 ID 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:140px">충전기 ID</span>
<input type="text" id="chgrIdLike" name="chgrIdLike" class="form-control" placeholder="충전기 ID 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:140px">충전소 명</span>
<input type="text" id="stNmLike" name="stNmLike" class="form-control" placeholder="충전소 명 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:140px">충전기 명</span>
<input type="text" id="chgrNmLike" name="chgrNmLike" class="form-control" placeholder="충전기 명 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:140px">충전기속도</span>
<input type="text" id="speedTpLike" name="speedTpLike" class="form-control" placeholder="충전기속도 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:140px">충전기타입</span>
<input type="text" id="chgrTpLike" name="chgrTpLike" class="form-control" placeholder="충전기타입 입력" maxlength="50">
</div>
</div>
</div>
</div>
<div id="searchBoxFooter">
<div class="row float-end">
<div class="col-xs-12 ">
<button type="button" class="btn btn-sm btn-info" id="searchBtn">검색</button>
<button type="button" class="btn btn-sm btn-info" id="resetBtn">리셋</button>
<button type="button" class="btn btn-sm btn-primary pl-2" onclick="showModal(ModalMode.REGISTER, {}, '');">등록</button>
</th:block>
</div>
</div>
</div>
</div>
</div>
<div class="w-100">
<div class="box box-primary">
<div class="form">
<table id="datatable" class="table table-striped table-hover dataTable" style="width:100%;"></table>
</div>
</div>
</div>
<script th:inline="none">
const rootPath = "/cms/chgr/";
let datatable;
$(document).ready(function() {
const className = "dt-head-center dt-body-center";
datatable = newDataTable(
"#datatable",
rootPath + "list.json",
function(d) {
if (strUtil.isNotEmpty($('#providerIdLike').val())) {d.providerId = $('#providerIdLike').val();}
if (strUtil.isNotEmpty($('#stIdLike').val())) {d.stId = $('#stIdLike').val();}
if (strUtil.isNotEmpty($('#chgrIdLike').val())) {d.chgrId = $('#chgrIdLike').val();}
if (strUtil.isNotEmpty($('#stNmLike').val())) {d.stNm = $('#stNmLike').val();}
if (strUtil.isNotEmpty($('#chgrNmLike').val())) {d.chgrNm = $('#chgrNmLike').val();}
if (strUtil.isNotEmpty($('#speedTpLike').val())) {d.speedTp = $('#speedTpLike').val();}
if (strUtil.isNotEmpty($('#chgrTpLike').val())) {d.chgrTp = $('#chgrTpLike').val();}
return d;
},
{
order: [],
columns: [
{title: "충전사업자 ID", name: "provider_id", data: "providerId", className},
{title: "충전소 ID", name: "st_id", data: "stId", className},
{title: "충전기 ID", name: "chgr_id", data: "chgrId", className},
{title: "충전소 명", name: "st_nm", data: "stNm", className, orderable: false},
{title: "충전기 명", name: "chgr_nm", data: "chgrNm", className, orderable: false},
{title: "충전기속도", name: "speed_tp", data: "speedTp", className, orderable: false},
{title: "충전기타입", name: "chgr_tp", data: "chgrTp", className, orderable: false},
{title: "기능", orderable:false, width:"110px",
render: (data, type, row) => {
return mkRowDataFunctions({providerId: row['providerId'], stId: row['stId'], chgrId: row['chgrId']}, row['chgrNm'], true, menuRoleModify, menuRoleDel);
}
}
],
allCheck: false,
});
});
const showModal = (mode, ids, title) => {
if(!checkRole(mode)) { alert("권한이 없습니다."); return; }
let modalInputArray = [
new ModalInput({
inputType: ModalInputType.text,
inputId: "providerId",
inputName: "providerId",
hasOldPk: true,
inputLabel: "충전사업자 ID",
inputPlaceholder: "충전사업자 ID",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 20,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "stId",
inputName: "stId",
hasOldPk: true,
inputLabel: "충전소 ID",
inputPlaceholder: "충전소 ID",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 20,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "chgrId",
inputName: "chgrId",
hasOldPk: true,
inputLabel: "충전기 ID",
inputPlaceholder: "충전기 ID",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 20,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "stNm",
inputName: "stNm",
inputLabel: "충전소 명",
inputPlaceholder: "충전소 명",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 50,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "chgrNm",
inputName: "chgrNm",
inputLabel: "충전기 명",
inputPlaceholder: "충전기 명",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 50,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "speedTp",
inputName: "speedTp",
inputLabel: "충전기속도",
inputPlaceholder: "충전기속도",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 250,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "chgrTp",
inputName: "chgrTp",
inputLabel: "충전기타입",
inputPlaceholder: "충전기타입",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 250,
})
];
if(!rootPath){ alert("rootPath를 지정하십시요."); return; }
const insertUrl = rootPath+"insert.json";
const updateUrl = rootPath+"update.json";
const loadUrl = rootPath+"view.json";
const deleteUrl = rootPath+"delete.json";
const modalWidth = 500;
const labelWidth = '90px';
if(mode === ModalMode.REGISTER) {
newModal(new ModalInfo({modalTitle: "등록", inputArray: modalInputArray, modalWidth}), mode, 'main', {insertUrl, labelWidth, callBack: () => { defaultCallback(); }})
} else if(mode===ModalMode.VIEW || mode===ModalMode.VIEW_ONLY || mode===ModalMode.MODIFY) {
newModal(new ModalInfo({modalTitle: "상세정보", inputArray: modalInputArray, modalWidth}), mode, 'main', {loadUrl, updateUrl, ids, labelWidth, callBack: () => { defaultCallback(); }})
} else if(mode === ModalMode.DELETE) {
newDelete(deleteUrl, ids, title, () => { defaultCallback(); });
}
const defaultCallback = () => {
datatable.ajax.reload();
}
};
$("#searchBtn").click(function() {
datatable.ajax.reload();
});
$("#resetBtn").click(function() {
$("#providerIdLike").val("");
$("#stIdLike").val("");
$("#chgrIdLike").val("");
$("#stNmLike").val("");
$("#chgrNmLike").val("");
$("#speedTpLike").val("");
$("#chgrTpLike").val("");
datatable.ajax.reload();
});
</script>
</section>
</body>
</html>
@@ -0,0 +1,297 @@
<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/cmsLayout}">
<body>
<section layout:fragment="Content">
<div class="w-100" style="margin-bottom: .3rem;">
<div th:replace="~{common/fragments/searchBox :: SearchBoxFragment(~{ :: #searchBoxContent}, ~{ :: #searchBoxFooter})}">
<div id="searchBoxContent">
<div class="row px-2">
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:160px">충전소 명</span>
<input type="text" id="stIdLike" name="stIdLike" class="form-control" placeholder="충전소 명 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:160px">충전기 명</span>
<input type="text" id="chgrIdLike" name="chgrIdLike" class="form-control" placeholder="충전기 명 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:160px">결제구분</span>
<input type="text" id="payTpLike" name="payTpLike" class="form-control" placeholder="결제구분 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:160px">충전기타입 코드</span>
<input type="text" id="plugTpLike" name="plugTpLike" class="form-control" placeholder="충전기타입 코드 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:160px">충전 시작일시</span>
<input type="text" id="rechgSDtLike" name="rechgSDtLike" class="form-control" placeholder="충전 시작일시 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:160px">충전 종료일시</span>
<input type="text" id="rechgEDtLike" name="rechgEDtLike" class="form-control" placeholder="충전 종료일시 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:160px">충전시간</span>
<input type="text" id="rechgTimeLike" name="rechgTimeLike" class="form-control" placeholder="충전시간 입력" maxlength="50">
</div>
</div>
<div class="col-lg-4 col-sm-6 col-xs-12 pb-1">
<div class="input-group">
<span class="input-group-text" style="width:160px">신용결제완료구분</span>
<input type="text" id="payFnshLike" name="payFnshLike" class="form-control" placeholder="신용결제완료구분 입력" maxlength="50">
</div>
</div>
</div>
</div>
<div id="searchBoxFooter">
<div class="row float-end">
<div class="col-xs-12 ">
<button type="button" class="btn btn-sm btn-info" id="searchBtn">검색</button>
<button type="button" class="btn btn-sm btn-info" id="resetBtn">리셋</button>
<th:block th:if="${menuRole?.roleWrite eq true}">
<button type="button" class="btn btn-sm btn-primary pl-2" onclick="showModal(ModalMode.REGISTER, {}, '');">등록</button>
</th:block>
</div>
</div>
</div>
</div>
</div>
<div class="w-100">
<div class="box box-primary">
<div class="form">
<table id="datatable" class="table table-striped table-hover dataTable" style="width:100%;"></table>
</div>
</div>
</div>
<script th:inline="none">
const rootPath = "/system/chgrHist/";
let datatable;
$(document).ready(function() {
const className = "dt-head-center dt-body-center";
datatable = newDataTable(
"#datatable",
rootPath + "list.json",
function(d) {
if (strUtil.isNotEmpty($('#stIdLike').val())) {d.stId = $('#stIdLike').val();}
if (strUtil.isNotEmpty($('#chgrIdLike').val())) {d.chgrId = $('#chgrIdLike').val();}
if (strUtil.isNotEmpty($('#payTpLike').val())) {d.payTp = $('#payTpLike').val();}
if (strUtil.isNotEmpty($('#plugTpLike').val())) {d.plugTp = $('#plugTpLike').val();}
if (strUtil.isNotEmpty($('#rechgSDtLike').val())) {d.rechgSDt = $('#rechgSDtLike').val();}
if (strUtil.isNotEmpty($('#rechgEDtLike').val())) {d.rechgEDt = $('#rechgEDtLike').val();}
if (strUtil.isNotEmpty($('#rechgTimeLike').val())) {d.rechgTime = $('#rechgTimeLike').val();}
if (strUtil.isNotEmpty($('#payFnshLike').val())) {d.payFnsh = $('#payFnshLike').val();}
return d;
},
{
order: [],
columns: [
{title: "충전소 명", name: "ST_NM", data: "stId", className, orderable: false},
{title: "충전기 명", name: "CHGR_NM", data: "chgrId", className, orderable: false},
{title: "결제구분", name: "PAY_TP", data: "payTp", className, orderable: false},
{title: "충전기타입 코드", name: "CHGR_TP", data: "plugTp", className, orderable: false},
{title: "충전 시작일시", name: "RECHG_S_DT", data: "rechgSDt", className, orderable: false},
{title: "충전 종료일시", name: "RECHG_E_DT", data: "rechgEDt", className, orderable: false},
{title: "충전시간", name: "RECHG_TIME", data: "rechgTime", className, orderable: false},
{title: "충전량", name: "RECH_GWH", data: "rechGwh", className, orderable: false},
{title: "충전금액", name: "RECHG_AMT", data: "rechgAmt", className, orderable: false},
{title: "신용결제완료구분", name: "PAY_FNSH", data: "payFnsh", className, orderable: false},
],
allCheck: false,
});
});
const showModal = (mode, ids, title) => {
if(!checkRole(mode)) { alert("권한이 없습니다."); return; }
let modalInputArray = [
new ModalInput({
inputType: ModalInputType.hidden,
inputId: "chrgHistId",
inputName: "chrgHistId",
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "stId",
inputName: "stId",
inputLabel: "충전소 ID",
inputPlaceholder: "충전소 ID",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 20,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "chgrId",
inputName: "chgrId",
inputLabel: "충전기 ID",
inputPlaceholder: "충전기 ID",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 20,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "stId",
inputName: "stId",
inputLabel: "충전소 명",
inputPlaceholder: "충전소 명",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 50,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "chgrId",
inputName: "chgrId",
inputLabel: "충전기 명",
inputPlaceholder: "충전기 명",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 50,
}),
new ModalInput({
inputType: ModalInputType.textarea,
inputId: "payTp",
inputName: "payTp",
inputLabel: "결제구분",
inputPlaceholder: "결제구분",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 250,
}),
new ModalInput({
inputType: ModalInputType.textarea,
inputId: "plugTp",
inputName: "plugTp",
inputLabel: "충전기타입 코드",
inputPlaceholder: "충전기타입 코드",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 250,
}),
new ModalInput({
inputType: ModalInputType.textarea,
inputId: "rechgSDt",
inputName: "rechgSDt",
inputLabel: "충전 시작일시",
inputPlaceholder: "충전 시작일시",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 250,
}),
new ModalInput({
inputType: ModalInputType.textarea,
inputId: "rechgEDt",
inputName: "rechgEDt",
inputLabel: "충전 종료일시",
inputPlaceholder: "충전 종료일시",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 250,
}),
new ModalInput({
inputType: ModalInputType.textarea,
inputId: "rechgTime",
inputName: "rechgTime",
inputLabel: "충전시간",
inputPlaceholder: "충전시간",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 250,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "rechGwh",
inputName: "rechGwh",
inputLabel: "충전량",
inputPlaceholder: "충전량",
isReq: false,
isEnable: true,
}),
new ModalInput({
inputType: ModalInputType.text,
inputId: "rechgAmt",
inputName: "rechgAmt",
inputLabel: "충전금액",
inputPlaceholder: "충전금액",
isReq: false,
isEnable: true,
}),
new ModalInput({
inputType: ModalInputType.textarea,
inputId: "payFnsh",
inputName: "payFnsh",
inputLabel: "신용결제완료구분",
inputPlaceholder: "신용결제완료구분",
isReq: false,
isEnable: true,
minLen: 0,
maxLen: 250,
})
];
if(!rootPath){ alert("rootPath를 지정하십시요."); return; }
const insertUrl = rootPath+"insert.json";
const updateUrl = rootPath+"update.json";
const loadUrl = rootPath+"view.json";
const deleteUrl = rootPath+"delete.json";
const modalWidth = 500;
const labelWidth = '90px';
if(mode === ModalMode.REGISTER) {
newModal(new ModalInfo({modalTitle: "등록", inputArray: modalInputArray, modalWidth}), mode, 'main', {insertUrl, labelWidth, callBack: () => { defaultCallback(); }})
} else if(mode===ModalMode.VIEW || mode===ModalMode.VIEW_ONLY || mode===ModalMode.MODIFY) {
newModal(new ModalInfo({modalTitle: "상세정보", inputArray: modalInputArray, modalWidth}), mode, 'main', {loadUrl, updateUrl, ids, labelWidth, callBack: () => { defaultCallback(); }})
} else if(mode === ModalMode.DELETE) {
newDelete(deleteUrl, ids, title, () => { defaultCallback(); });
}
const defaultCallback = () => {
datatable.ajax.reload();
}
};
$("#searchBtn").click(function() {
datatable.ajax.reload();
});
$("#resetBtn").click(function() {
$("#stIdLike").val("");
$("#chgrIdLike").val("");
$("#payTpLike").val("");
$("#plugTpLike").val("");
$("#rechgSDtLike").val("");
$("#rechgEDtLike").val("");
$("#rechgTimeLike").val("");
$("#payFnshLike").val("");
datatable.ajax.reload();
});
</script>
</section>
</body>
</html>