Socket Echo 기능 추가
This commit is contained in:
@@ -26,7 +26,7 @@ public class ApiManageController {
|
||||
|
||||
@GetMapping("/manage/findAllApis")
|
||||
public String getAllApis(Pageable pageable, Model model) {
|
||||
model.addAttribute("apiInfoList", apiService.findAllApis(pageable));
|
||||
//model.addAttribute("apiInfoList", apiService.findAllApis(pageable));
|
||||
return "page/list-api";
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ public class ApiServiceImpl implements ApiService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
|
||||
public void delete(Long id) {
|
||||
apiDao.deleteById(id);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.eactive.httpmockserver.socket;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
@@ -14,7 +15,9 @@ import javax.persistence.JoinColumn;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OrderBy;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Positive;
|
||||
import javax.validation.constraints.PositiveOrZero;
|
||||
|
||||
@@ -36,6 +39,7 @@ public class BytesMessageSpec implements Serializable {
|
||||
private String llFieldLengthInclude;
|
||||
|
||||
@Positive
|
||||
@NotNull
|
||||
private Integer llFieldLength;
|
||||
|
||||
private Integer llFieldLengthAlpha;
|
||||
@@ -50,6 +54,7 @@ public class BytesMessageSpec implements Serializable {
|
||||
private String encode;
|
||||
|
||||
@Positive
|
||||
@NotNull
|
||||
private Integer port;
|
||||
|
||||
@Positive
|
||||
@@ -62,10 +67,11 @@ public class BytesMessageSpec implements Serializable {
|
||||
@Column(length = 1)
|
||||
private String useYn;
|
||||
|
||||
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
|
||||
@Valid
|
||||
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
@JoinColumn(name = "BYTE_MESSAGE_SPEC_ID")
|
||||
@OrderBy("position")
|
||||
private List<EchoReplaceString> EchoReplaceStringList;
|
||||
private List<EchoReplaceString> echoReplaceStringList = new ArrayList<EchoReplaceString>();
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
@@ -172,11 +178,11 @@ public class BytesMessageSpec implements Serializable {
|
||||
}
|
||||
|
||||
public List<EchoReplaceString> getEchoReplaceStringList() {
|
||||
return EchoReplaceStringList;
|
||||
return echoReplaceStringList;
|
||||
}
|
||||
|
||||
public void setEchoReplaceStringList(List<EchoReplaceString> echoReplaceStringList) {
|
||||
EchoReplaceStringList = echoReplaceStringList;
|
||||
this.echoReplaceStringList = echoReplaceStringList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -186,6 +192,6 @@ public class BytesMessageSpec implements Serializable {
|
||||
+ ", llFieldLengthAlpha=" + llFieldLengthAlpha + ", llFieldOffset=" + llFieldOffset + ", llFieldType="
|
||||
+ llFieldType + ", encode=" + encode + ", port=" + port + ", sleepSeconds=" + sleepSeconds
|
||||
+ ", responseBody=" + responseBody + ", useYn=" + useYn + ", EchoReplaceStringList="
|
||||
+ EchoReplaceStringList + "]";
|
||||
+ echoReplaceStringList + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package com.eactive.httpmockserver.socket;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface BytesMessageSpecDao extends JpaRepository<BytesMessageSpec, Long> {
|
||||
BytesMessageSpec findFirstByUseYn(String useYn);
|
||||
|
||||
@Modifying
|
||||
@Query(value = "update BytesMessageSpec b set b.useYn='N' where b.id <> ?1")
|
||||
void updateUnuseOthers(Long id);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
package com.eactive.httpmockserver.socket;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
public interface BytesMessageSpecService {
|
||||
public BytesMessageSpec findActiveBytesMessageSpec();
|
||||
|
||||
public List<BytesMessageSpec> findAllBytesMessageSpecs(Pageable pageable);
|
||||
|
||||
public List<BytesMessageSpec> findAllBytesMessageSpecs(Example<BytesMessageSpec> example, Pageable pageable);
|
||||
|
||||
public long getRecordsCount(Example<BytesMessageSpec> example);
|
||||
|
||||
public Optional<BytesMessageSpec> findById(Long id);
|
||||
|
||||
public BytesMessageSpec save(BytesMessageSpec spec);
|
||||
|
||||
public BytesMessageSpec update(BytesMessageSpec spec);
|
||||
|
||||
public void delete(Long id);
|
||||
|
||||
public void setUnuseOthers(Long id);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
package com.eactive.httpmockserver.socket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -15,4 +22,66 @@ public class BytesMessageSpecServiceImpl implements BytesMessageSpecService {
|
||||
public BytesMessageSpec findActiveBytesMessageSpec() {
|
||||
return dao.findFirstByUseYn("Y");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BytesMessageSpec> findAllBytesMessageSpecs(Pageable pageable) {
|
||||
Page<BytesMessageSpec> pagedResult = dao.findAll(pageable);
|
||||
if (pagedResult.hasContent()) {
|
||||
return pagedResult.getContent();
|
||||
} else {
|
||||
return new ArrayList<BytesMessageSpec>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BytesMessageSpec> findAllBytesMessageSpecs(Example<BytesMessageSpec> example, Pageable pageable) {
|
||||
if (example == null) {
|
||||
return findAllBytesMessageSpecs(pageable);
|
||||
}
|
||||
|
||||
Page<BytesMessageSpec> pagedResult = dao.findAll(example, pageable);
|
||||
if (pagedResult.hasContent()) {
|
||||
return pagedResult.getContent();
|
||||
} else {
|
||||
return new ArrayList<BytesMessageSpec>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BytesMessageSpec> findById(Long id) {
|
||||
return dao.findById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRecordsCount(Example<BytesMessageSpec> example) {
|
||||
if (example == null) {
|
||||
return dao.count();
|
||||
} else {
|
||||
return dao.count(example);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
|
||||
public BytesMessageSpec save(BytesMessageSpec spec) {
|
||||
return dao.save(spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
|
||||
public BytesMessageSpec update(BytesMessageSpec spec) {
|
||||
return dao.save(spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
|
||||
public void delete(Long id) {
|
||||
dao.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
|
||||
public void setUnuseOthers(Long id) {
|
||||
dao.updateUnuseOthers(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.PositiveOrZero;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@@ -17,8 +18,8 @@ public class EchoReplaceString implements Serializable {
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@NotBlank
|
||||
@PositiveOrZero
|
||||
@NotNull
|
||||
@Column(nullable = false)
|
||||
private Integer position;
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class EchoSocketServer {
|
||||
workerGroup.shutdownGracefully().sync();
|
||||
channelFuture.channel().closeFuture().sync();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,35 @@
|
||||
package com.eactive.httpmockserver.socket;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.ExampleMatcher;
|
||||
import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatcher;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.eactive.httpmockserver.ApiManageRestController;
|
||||
import com.eactive.httpmockserver.datatables.DataTablesRequest;
|
||||
import com.eactive.httpmockserver.datatables.DataTablesResponse;
|
||||
|
||||
@Controller
|
||||
public class SocketServerManageController {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@@ -20,6 +39,89 @@ public class SocketServerManageController {
|
||||
|
||||
private EchoSocketServer echoSocketServer;
|
||||
|
||||
@GetMapping("/manage/findAllBytesMessageSpecs")
|
||||
public String getAllBytesMessageSpecs(Pageable pageable, Model model) {
|
||||
return "page/list-bytes-message-spec";
|
||||
}
|
||||
|
||||
@GetMapping(path = { "/manage/getBytesMessageSpecForm", "/manage/getBytesMessageSpecForm/{id}" })
|
||||
public String getBytesMessageSpecForm(Model model, @PathVariable Optional<Long> id) {
|
||||
if (id.isPresent()) {
|
||||
Optional<BytesMessageSpec> optional = specService.findById(id.get());
|
||||
if (optional.isPresent()) {
|
||||
model.addAttribute("bytesMessageSpec", optional.get());
|
||||
} else {
|
||||
throw new IllegalArgumentException("No data, id: " + id.get());
|
||||
}
|
||||
} else {
|
||||
BytesMessageSpec spec = new BytesMessageSpec();
|
||||
model.addAttribute("bytesMessageSpec", spec);
|
||||
}
|
||||
|
||||
return "page/add-edit-bytes-message-spec";
|
||||
}
|
||||
|
||||
@PostMapping("/manage/saveBytesMessageSpec")
|
||||
public String saveBytesMessageSpec(@Valid BytesMessageSpec spec, BindingResult result, Model model) {
|
||||
if (result.hasErrors()) {
|
||||
return "page/add-edit-bytes-message-spec";
|
||||
}
|
||||
|
||||
if (spec.getId() == null) {
|
||||
specService.save(spec);
|
||||
} else {
|
||||
specService.update(spec);
|
||||
}
|
||||
|
||||
if (BooleanUtils.toBoolean(spec.getUseYn())) {
|
||||
// 기존서버 중지
|
||||
stop();
|
||||
|
||||
// 기존설정 useYn=N으로 수정
|
||||
specService.setUnuseOthers(spec.getId());
|
||||
|
||||
// 서버 기동
|
||||
start();
|
||||
}
|
||||
|
||||
return "redirect:/manage/findAllBytesMessageSpecs";
|
||||
}
|
||||
|
||||
@PostMapping("/manage/rest/bytesMessageSpecs")
|
||||
@ResponseBody
|
||||
public DataTablesResponse<BytesMessageSpec> getAllApisForDatatables(@RequestBody DataTablesRequest req) {
|
||||
Pageable pageable = ApiManageRestController.assignJpaPageable(req);
|
||||
|
||||
// search option
|
||||
Example<BytesMessageSpec> example = null;
|
||||
if (StringUtils.isNotBlank(req.getSearch().getValue())) {
|
||||
BytesMessageSpec spec = new BytesMessageSpec();
|
||||
spec.setSpecName(req.getSearch().getValue());
|
||||
|
||||
ExampleMatcher matcher = ExampleMatcher.matchingAny().withMatcher("specName",
|
||||
new GenericPropertyMatcher().contains().ignoreCase());
|
||||
example = Example.of(spec, matcher);
|
||||
}
|
||||
|
||||
DataTablesResponse<BytesMessageSpec> res = new DataTablesResponse<BytesMessageSpec>(
|
||||
specService.findAllBytesMessageSpecs(example, pageable));
|
||||
res.setRecordsFiltered(specService.getRecordsCount(example));
|
||||
res.setRecordsTotal(specService.getRecordsCount(null));
|
||||
res.setDraw(req.getDraw());
|
||||
return res;
|
||||
}
|
||||
|
||||
@RequestMapping("/manage/deleteBytesMessageSpec/{id}")
|
||||
public String deleteBytesMessageSpec(@PathVariable Long id) {
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("No data, id: " + id);
|
||||
}
|
||||
|
||||
specService.delete(id);
|
||||
|
||||
return "redirect:/manage/findAllBytesMessageSpecs";
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void start() {
|
||||
logger.info("EchoSocketServer starting..");
|
||||
|
||||
@@ -64,6 +64,23 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link">
|
||||
<i class="nav-icon fas fa-columns"></i>
|
||||
<p>
|
||||
Echo Socket <i class="fas fa-angle-left right"></i>
|
||||
</p>
|
||||
</a>
|
||||
<ul class="nav nav-treeview">
|
||||
<li class="nav-item">
|
||||
<a th:href="@{/manage/findAllBytesMessageSpecs}" class="nav-link">
|
||||
<i class="far fa-circle nav-icon"></i>
|
||||
<p>Bytes Message 관리</p>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- /.sidebar-menu -->
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1 th:if="${bytesMessageSpec.id == null}">Bytes Message 정보 등록</h1>
|
||||
<h1 th:unless="${bytesMessageSpec.id == null}">Bytes Message 정보 수정</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||
<li class="breadcrumb-item active">Echo Socket</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content" style="padding-bottom: 1rem;">
|
||||
<div class="container-fluid">
|
||||
<form id="bytesMessageSpecForm" name="bytesMessageSpecForm" class="inputForm" action="#" th:action="@{/manage/saveBytesMessageSpec}"
|
||||
th:object="${bytesMessageSpec}" method="post">
|
||||
<div class="card card-default">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Basic Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Message명<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{specName}"
|
||||
class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('specName')}"
|
||||
th:errors="*{specName}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Encode</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{encode}" class="form-control" placeholder="EUC-KR">
|
||||
<span th:if="${#fields.hasErrors('encode')}"
|
||||
th:errors="*{encode}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">LL길이<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{llFieldLength}" class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('llFieldLength')}" th:errors="*{llFieldLength}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">LL길이포함</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{llFieldLengthInclude}" class="form-check-input" value="Y">
|
||||
Y <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{llFieldLengthInclude}" class="form-check-input" value="N">
|
||||
N <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Port<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{port}" class="form-control" placeholder="38181"> <span
|
||||
th:if="${#fields.hasErrors('port')}" th:errors="*{port}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">사용여부</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{useYn}" class="form-check-input" value="Y">
|
||||
Y <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{useYn}" class="form-check-input" value="N">
|
||||
N <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-default">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Response Message Info</h3>
|
||||
<br>
|
||||
<small> <font color="blue">- 응답 메시지를 입력할 경우 아래 Acho Message Info 정보는 무시 됩니다.</font></small>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label for="url">응답 메시지</label>
|
||||
<textarea class="form-control" th:field="*{responseBody}" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-default">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Acho Message Info</h3>
|
||||
|
||||
<button type="button" id="addReplaceRule" class="btn btn-sm btn-success float-right">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="replaceRuleTable" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No.</th>
|
||||
<th>Replace 시작 Index</th>
|
||||
<th>Replace 스트링</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="dynamicTableContents">
|
||||
<tr th:fragment="echoReplaceString"
|
||||
th:each="echoReplaceString,rowStat : ${bytesMessageSpec.getEchoReplaceStringList()}">
|
||||
<td th:text="${rowStat.count}">1</td>
|
||||
<td>
|
||||
<input type="hidden" th:field="${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].id}">
|
||||
<input type="text" th:field="${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].position}" class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].position}')}"
|
||||
th:errors="${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].position}"
|
||||
class="text-danger"></span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" th:field="${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].replaceString}" class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('echoReplaceStringList[__${rowStat.index}__].replaceString')}"
|
||||
th:errors="*{echoReplaceStringList[__${rowStat.index}__].replaceString}"
|
||||
class="text-danger"></span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<button type="button" id="removeDynamicRow" class="btn btn-sm btn-danger">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" th:field="*{id}">
|
||||
<button type="button" id="submitButton" class="btn btn-primary mr-2">Submit</button>
|
||||
<button type="button" class="btn btn-secondary"
|
||||
onclick="history.go(-1);">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:inline="javascript">
|
||||
var urlForSidebar = "/manage/findAllBytesMessageSpecs";
|
||||
|
||||
$("#addReplaceRule").click(function() {
|
||||
var idx = $('#dynamicTableContents tr:last td:first').text();
|
||||
try {
|
||||
if (idx) {
|
||||
idx++;
|
||||
} else {
|
||||
idx = 1;
|
||||
}
|
||||
} catch (error) {}
|
||||
|
||||
var trStr = '<tr><td>' + idx + '</td>'
|
||||
+ '<td><input type="text" class="form-control"></td>'
|
||||
+ '<td><input type="text" class="form-control"></td>'
|
||||
+ '<td><div class="btn-group"><button type="button" id="removeDynamicRow" class="btn btn-sm btn-danger"><i class="far fa-trash-alt"></i></button></div></td></tr>';
|
||||
$("#dynamicTableContents").append(trStr);
|
||||
});
|
||||
|
||||
$("#replaceRuleTable").on("click", "#removeDynamicRow", function() {
|
||||
$(this).closest("tr").remove();
|
||||
});
|
||||
|
||||
$("#submitButton").click(function() {
|
||||
$('#dynamicTableContents > tr').each(function(index, tr) {
|
||||
var idValue = $(tr).find("td:eq(1) input[type=hidden]").val();
|
||||
if (idValue) {
|
||||
$(tr).find("td:eq(1) input[type=hidden]").attr('name', 'echoReplaceStringList[' + index + '].id');
|
||||
}
|
||||
$(tr).find("td:eq(1) input[type=text]").attr('name', 'echoReplaceStringList[' + index + '].position');
|
||||
|
||||
$(tr).find("td:eq(2) input[type=text]").attr('name', 'echoReplaceStringList[' + index + '].replaceString');
|
||||
});
|
||||
|
||||
$(this).css({'cursor':'wait'});
|
||||
$(this).attr('disabled', true);
|
||||
document.body.style.cursor = 'wait';
|
||||
document.bytesMessageSpecForm.submit();
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,160 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<th:block layout:fragment="css">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||
</th:block>
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>Bytes Message 관리</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||
<li class="breadcrumb-item active">Echo Socket</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">목록중 하나의 메세지만 사용할 수 있습니다.</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="listBytesMessageSpecTable"
|
||||
class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>메시지명</th>
|
||||
<th>LL길이</th>
|
||||
<th>LL길이포함</th>
|
||||
<th>Port</th>
|
||||
<th>사용여부</th>
|
||||
<th>수정</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
||||
|
||||
<script th:inline="javascript">
|
||||
$.fn.dataTable.ext.buttons.new = {
|
||||
text: 'New',
|
||||
action: function ( e, dt, node, config ) {
|
||||
location.href = "/manage/getBytesMessageSpecForm";
|
||||
}
|
||||
};
|
||||
|
||||
var listBytesMessageSpecTable = $("#listBytesMessageSpecTable").DataTable({
|
||||
"responsive": true, "lengthChange": false, "autoWidth": false,
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"searchDelay": 1200,
|
||||
"ajax": {
|
||||
"url": "/manage/rest/bytesMessageSpecs",
|
||||
"type": "POST",
|
||||
"dataType": "json",
|
||||
"contentType": "application/json",
|
||||
"data": function (d) {
|
||||
return JSON.stringify(d);
|
||||
}
|
||||
},
|
||||
"columns": [
|
||||
{"data": "specName"},
|
||||
{"data": "llFieldLength", "searchable": false, "orderable": false},
|
||||
{"data": "llFieldLengthInclude", "searchable": false, "orderable": false},
|
||||
{"data": "port", "searchable": false, "orderable": false},
|
||||
{"data": "useYn", "searchable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false}
|
||||
],
|
||||
"columnDefs": [
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getBytesMessageSpecForm/' + data + '" class="btn btn-primary"><i class="fas fa-edit"></i></a>';
|
||||
},
|
||||
"targets": -2
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
var msg = "'정말로 데이터를 삭제 하시겠습니까?'";
|
||||
return '<a href="/manage/deleteBytesMessageSpec/' + data + '" onclick="return confirm(' + msg +');" class="btn btn-primary"><i class="fas fa-trash"></i></a>';
|
||||
},
|
||||
"targets": -1
|
||||
}
|
||||
],
|
||||
"buttons": ["new", "excel", "colvis"],
|
||||
"initComplete": function() {
|
||||
listBytesMessageSpecTable.buttons().container().appendTo('#listBytesMessageSpecTable_wrapper .col-md-6:eq(0)');
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
$(".dataTables_filter input").unbind().bind("input", function(e) { // Bind our desired behavior
|
||||
// If the length is 3 or more characters, or the user pressed ENTER, search
|
||||
if(this.value.length >= 3 || e.keyCode == 13) {
|
||||
// Call the API search function
|
||||
listBytesMessageSpecTable.search(this.value).draw();
|
||||
}
|
||||
// Ensure we clear the search if they backspace far enough
|
||||
if(this.value == "") {
|
||||
listBytesMessageSpecTable.search("").draw();
|
||||
}
|
||||
return;
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
Reference in New Issue
Block a user