문자온 스팸문자 필터링 기능 개발중
This commit is contained in:
parent
b5b34604e8
commit
3d417c7b09
7
pom.xml
7
pom.xml
@ -160,12 +160,13 @@
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring WebFlux 의존성 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>1.4.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
37
src/main/java/com/itn/admin/cmn/vo/CmnVO.java
Normal file
37
src/main/java/com/itn/admin/cmn/vo/CmnVO.java
Normal file
@ -0,0 +1,37 @@
|
||||
package com.itn.admin.cmn.vo;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class CmnVO {
|
||||
|
||||
private int pageNum = 1; // 현재 페이지 번호 기본값 설정
|
||||
private int pageSize = 10; // 한 페이지에 보여줄 데이터 개수 기본값 설정
|
||||
private int offset; // SQL 쿼리에서 사용할 OFFSET
|
||||
private int limit; // SQL 쿼리에서 사용할 LIMIT
|
||||
|
||||
private int totalCount; // 총 데이터 수
|
||||
private int totalPageCount; // 총 페이지 수
|
||||
private int startPage; // 페이지네이션의 시작 페이지 번호
|
||||
private int endPage; // 페이지네이션의 끝 페이지 번호
|
||||
|
||||
// 페이징을 위한 offset과 limit을 계산하는 메서드
|
||||
public void calculatePaging(int totalRecordCount) {
|
||||
this.totalCount = totalRecordCount;
|
||||
this.offset = (pageNum - 1) * pageSize;
|
||||
this.limit = pageSize;
|
||||
|
||||
// 총 페이지 수 계산
|
||||
this.totalPageCount = (int) Math.ceil((double) totalRecordCount / pageSize);
|
||||
|
||||
// 페이지네이션의 시작과 끝 페이지 계산
|
||||
int pageBlockSize = 10; // 한 블록에 표시할 페이지 수
|
||||
this.startPage = ((pageNum - 1) / pageBlockSize) * pageBlockSize + 1;
|
||||
this.endPage = Math.min(startPage + pageBlockSize - 1, totalPageCount);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -16,4 +16,8 @@ public interface SpamMapper {
|
||||
List<SpamVO> getListWhereKeywordsIsNull(SpamVO spamVO);
|
||||
|
||||
void update(SpamVO spamVO);
|
||||
|
||||
List<SpamVO> getSpamList(SpamVO spamVO);
|
||||
|
||||
int getTotalRecordCount();
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package com.itn.admin.itn.mjon.spam.mapper.domain;
|
||||
|
||||
import com.itn.admin.cmn.vo.CmnVO;
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* packageName : com.itn.admin.itn.mjon.spam.mapper.domain
|
||||
@ -23,7 +25,7 @@ import java.time.LocalDateTime;
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class SpamVO implements Serializable {
|
||||
public class SpamVO extends CmnVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -40,4 +42,7 @@ public class SpamVO implements Serializable {
|
||||
private String lastUpdusrId; // 최종수정자ID
|
||||
private LocalDateTime lastUpdtPnttm; // 최종수정일자
|
||||
|
||||
|
||||
// spam_keywords TB 외 필드들
|
||||
private List<String> keywordList; // 키워드 리스트
|
||||
}
|
||||
|
||||
@ -11,4 +11,6 @@ public interface SpamService {
|
||||
Map<String, Object> getList(SpamVO spamVO);
|
||||
|
||||
void analyze();
|
||||
|
||||
Map<String, Object> getSpamList(SpamVO spamVO);
|
||||
}
|
||||
|
||||
@ -9,13 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -57,7 +52,7 @@ public class SpamServiceImpl implements SpamService {
|
||||
|
||||
// for (SpamVO spamVO : spamList) {
|
||||
|
||||
// API 호출 및 데이터 수신
|
||||
// API 호출 및 데이터 수신
|
||||
|
||||
List<SpamVO> spamList = spamMapper.getListWhereKeywordsIsNull(new SpamVO());
|
||||
|
||||
@ -111,4 +106,27 @@ public class SpamServiceImpl implements SpamService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSpamList(SpamVO spamVO) {
|
||||
int totalRecordCount = spamMapper.getTotalRecordCount();
|
||||
spamVO.calculatePaging(totalRecordCount);
|
||||
|
||||
List<SpamVO> spamList = spamMapper.getSpamList(spamVO);
|
||||
|
||||
|
||||
// 키워드를 버튼용 배열로 변환
|
||||
for (SpamVO spam : spamList) {
|
||||
if (spam.getKeywords() != null) {
|
||||
spam.setKeywordList(Arrays.asList(spam.getKeywords().split(", ")));
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
resultMap.put("spamList", spamList);
|
||||
resultMap.put("totalRecordCount", totalRecordCount);
|
||||
resultMap.put("totalPageCount", spamVO.getTotalPageCount());
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,23 +1,11 @@
|
||||
package com.itn.admin.itn.mjon.spam.web;
|
||||
|
||||
import com.itn.admin.itn.mjon.spam.mapper.domain.SpamVO;
|
||||
import com.itn.admin.itn.mjon.spam.service.SpamService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
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.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
|
||||
@ -9,6 +9,8 @@ import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Controller
|
||||
@ -23,13 +25,11 @@ public class SpamController {
|
||||
|
||||
@GetMapping(value = "/mjon/spam/select")
|
||||
public String select(@ModelAttribute("spamVO") SpamVO spamVO, Model model) {
|
||||
//
|
||||
//
|
||||
// Map<String, Object> resultMap = spamService.getList(spamVO);
|
||||
|
||||
// model.addAttribute("spamList", resultMap.get("spamList"));
|
||||
//
|
||||
// model.addAttribute("list", resultMap.get("resultList"));
|
||||
Map<String, Object> map = spamService.getSpamList(spamVO);
|
||||
|
||||
model.addAttribute("spamList", map.get("spamList"));
|
||||
model.addAttribute("pagingVO", spamVO);
|
||||
|
||||
return "mjon/spam/select";
|
||||
}
|
||||
|
||||
@ -4,6 +4,33 @@
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.itn.admin.itn.mjon.spam.mapper.SpamMapper">
|
||||
<!-- 페이징 처리를 위해 전체 레코드 수를 구하는 쿼리 -->
|
||||
<select id="getTotalRecordCount" resultType="int">
|
||||
SELECT COUNT(*) FROM spam_keywords
|
||||
</select>
|
||||
|
||||
<select id="getSpamList" parameterType="spamVO" resultType="SpamVO">
|
||||
SELECT
|
||||
SPAM_ID,
|
||||
MSG_GROUP_ID,
|
||||
SMS_TXT,
|
||||
SPAM_RSN,
|
||||
KEYWORDS,
|
||||
CHC_KEYWORDS,
|
||||
TIMESTAMP,
|
||||
CATEG,
|
||||
FRST_REGISTER_ID,
|
||||
FRST_REGIST_PNTTM,
|
||||
LAST_UPDUSR_ID,
|
||||
LAST_UPDT_PNTTM
|
||||
FROM
|
||||
spam_keywords
|
||||
ORDER BY
|
||||
SPAM_ID
|
||||
LIMIT #{limit} OFFSET #{offset}
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
<select id="getList" parameterType="spamVO" resultType="spamVO">
|
||||
SELECT
|
||||
|
||||
@ -99,7 +99,7 @@
|
||||
</a>
|
||||
<ul class="nav nav-treeview">
|
||||
<li class="nav-item">
|
||||
<a th:href="@{/mjon/spam}" class="nav-link">
|
||||
<a th:href="@{/mjon/spam/select}" class="nav-link">
|
||||
<i class="fas fa-exclamation-triangle nav-icon"></i>
|
||||
<p>스팸문자</p>
|
||||
</a>
|
||||
|
||||
@ -38,6 +38,25 @@
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
/*단어 버튼 css*/
|
||||
/* .word-button {
|
||||
background-color: #007bff; !* 기본 배경색 *!
|
||||
color: white; !* 글자색 *!
|
||||
border: none; !* 테두리 없애기 *!
|
||||
border-radius: 15px; !* 둥근 모서리 *!
|
||||
padding: 5px 10px; !* 패딩 조절 *!
|
||||
margin: 3px; !* 버튼 사이 간격 *!
|
||||
cursor: pointer; !* 커서 모양 변경 *!
|
||||
font-size: 14px; !* 글자 크기 *!
|
||||
transition: background-color 0.3s ease; !* 배경색 전환 효과 *!
|
||||
}
|
||||
|
||||
.word-button:hover {
|
||||
background-color: #0056b3; !* 마우스 오버 시 배경색 *!
|
||||
}*/
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@ -83,55 +102,82 @@
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">스팸 단어 선택</h3>
|
||||
<h3 class="card-title" th:text="'Total '+${pagingVO.totalCount}+'건'">스팸 단어 선택</h3>
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<div class="card-body p-0">
|
||||
|
||||
<table class="table table-hover table-fixed">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">번호</th>
|
||||
<th style="width: 25%;">스팸문자</th>
|
||||
<th style="width: 25%;">복합명사</th>
|
||||
<th style="width: 35%;">복합명사</th>
|
||||
<th style="width: 25%;">핵심 단어</th>
|
||||
<th style="width: 20%;">스팸분류</th>
|
||||
<th style="width: 10%;">스팸분류</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>(광고)♥봄맞이 특별이벤트 진행중♥ ...</td>
|
||||
<td>'바다', '서비스', '갯수', '이건조제한', ...</td>
|
||||
<td>'바다', '서비스', '갯수', '이건조제한', 'EVENT 1' ...</td>
|
||||
<td>
|
||||
<select class="form-control">
|
||||
<option>선택</option>
|
||||
<option>성인</option>
|
||||
<option>불법</option>
|
||||
<option>해당없음</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>[국민건강보험]...</td>
|
||||
<td>'바다', '서비스', '갯수'...</td>
|
||||
<td>'바다', '서비스'...</td>
|
||||
<td>
|
||||
<select class="form-control">
|
||||
<option>선택</option>
|
||||
<option>성인</option>
|
||||
<option>불법</option>
|
||||
<option>해당없음</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 추가 행을 여기에 추가 -->
|
||||
<tr th:each="spam, iterStat : ${spamList}">
|
||||
<td th:text="${iterStat.index + 1}"></td>
|
||||
<td th:text="${spam.smsTxt}">스팸문자 내용</td>
|
||||
<td>
|
||||
<span th:each="word : ${spam.keywordList}">
|
||||
<!--
|
||||
- adminLTE3 css 참고
|
||||
btn: 버튼 스타일을 적용합니다.
|
||||
btn-primary: 파란색 배경의 버튼을 만듭니다. 다른 색상은 btn-secondary, btn-success, btn-danger 등으로 변경할 수 있습니다.
|
||||
btn-sm: 작은 크기의 버튼을 만듭니다.
|
||||
rounded-pill: 모서리를 둥글게 처리하여 pill 형태의 버튼을 만듭니다.
|
||||
|
||||
mx-1: 좌우에 0.25rem(약 4px)의 여백 추가
|
||||
my-1: 상하에 0.25rem(약 4px)의 여백 추가
|
||||
-->
|
||||
<button class="btn btn-primary rounded-pill mx-1 my-1"
|
||||
th:text="${word}"
|
||||
th:data-spamid="${spam.spamId}"
|
||||
th:data-word="${word}"
|
||||
onclick="handleClick(this)"></button>
|
||||
</span>
|
||||
</td>
|
||||
<!-- <td th:text="${spam.keywords}">복합명사 목록</td>-->
|
||||
<td th:text="${spam.chcKeywords}">핵심 단어 목록</td>
|
||||
<td>
|
||||
<select class="form-control" th:value="${spam.categ}">
|
||||
<option>선택</option>
|
||||
<option value="성인">성인</option>
|
||||
<option value="불법">불법</option>
|
||||
<option value="해당없음">해당없음</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<!-- Pagination -->
|
||||
<nav aria-label="Page navigation example">
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item" th:classappend="${pagingVO.pageNum == 1} ? 'disabled'">
|
||||
<a class="page-link" th:href="@{/mjon/spam/select(pageNum=${pagingVO.pageNum - 1}, pageSize=${pagingVO.pageSize})}" aria-label="Previous">
|
||||
<span aria-hidden="true">«</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item" th:each="i : ${#numbers.sequence(pagingVO.startPage, pagingVO.endPage)}"
|
||||
th:classappend="${i == pagingVO.pageNum} ? 'active'">
|
||||
<a class="page-link" th:text="${i}"
|
||||
th:href="@{/mjon/spam/select(pageNum=${i}, pageSize=${pagingVO.pageSize})}"></a>
|
||||
</li>
|
||||
<li class="page-item" th:classappend="${pagingVO.pageNum == pagingVO.totalPageCount} ? 'disabled'">
|
||||
<a class="page-link" th:href="@{/mjon/spam/select(pageNum=${pagingVO.pageNum + 1}, pageSize=${pagingVO.pageSize})}" aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
@ -180,6 +226,16 @@
|
||||
$(function () {
|
||||
|
||||
});
|
||||
function handleClick(button) {
|
||||
var spamId = button.getAttribute('data-spamid');
|
||||
var word = button.getAttribute('data-word');
|
||||
console.log("Spam ID:", spamId, "Word:", word);
|
||||
// 여기에 추가적인 로직을 구현하세요.
|
||||
|
||||
// 부모 요소인 span을 찾아서 제거
|
||||
var span = button.parentElement;
|
||||
span.remove();
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user