스팸단어 체크
This commit is contained in:
parent
7caaa99ae9
commit
b5c1cba2c3
4
pom.xml
4
pom.xml
@ -166,6 +166,10 @@
|
|||||||
<version>1.4.2</version>
|
<version>1.4.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.zaxxer</groupId>
|
||||||
|
<artifactId>HikariCP</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@ -23,9 +23,9 @@ class MjonAgentSDatabaseConfig {
|
|||||||
// A database DataSource
|
// A database DataSource
|
||||||
@Bean(AGENT_S_DATA_SOURCE)
|
@Bean(AGENT_S_DATA_SOURCE)
|
||||||
@ConfigurationProperties(prefix = "spring.mjagent.server.datasource")
|
@ConfigurationProperties(prefix = "spring.mjagent.server.datasource")
|
||||||
public DataSource CommuteDataSource() {
|
public DataSource MjagentServerSource() {
|
||||||
return DataSourceBuilder.create()
|
return DataSourceBuilder.create()
|
||||||
// .type(HikariDataSource.class)
|
.type(com.zaxxer.hikari.HikariDataSource.class) // HikariDataSource를 명시적으로 사용
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,8 +7,8 @@ import org.apache.ibatis.annotations.Mapper;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface CodeDetailMapper {
|
public interface CodeDetailMapper {
|
||||||
List<CodeDetailVO> findByGroupId(String codeGroupId);
|
List<CodeDetailVO> findByGroupId(String codeGroupId);
|
||||||
CodeDetailVO findById(String codeId);
|
CodeDetailVO findById(String codeGroupId, String codeId);
|
||||||
void insert(CodeDetailVO codeDetailVO);
|
void insert(CodeDetailVO codeDetailVO);
|
||||||
void update(CodeDetailVO codeDetailVO);
|
void update(CodeDetailVO codeDetailVO);
|
||||||
void delete(String codeId);
|
void delete(String codeGroupId, String codeId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
package com.itn.admin.itn.code.mapper.domain;
|
package com.itn.admin.itn.code.mapper.domain;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@ToString
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class CodeDetailVO {
|
public class CodeDetailVO {
|
||||||
|
|||||||
@ -12,14 +12,14 @@ public interface CodeDetailService {
|
|||||||
List<CodeDetailVO> getDetailsByGroupId(String codeGroupId);
|
List<CodeDetailVO> getDetailsByGroupId(String codeGroupId);
|
||||||
|
|
||||||
// 특정 코드 상세를 ID로 가져오는 메서드
|
// 특정 코드 상세를 ID로 가져오는 메서드
|
||||||
CodeDetailVO getCodeDetailById(String codeId);
|
CodeDetailVO getCodeDetailById(String codeGroupId, String codeId);
|
||||||
|
|
||||||
// 코드 상세 추가 메서드
|
// 코드 상세 추가 메서드
|
||||||
RestResponse addCodeDetail(CodeDetailVO codeDetail);
|
RestResponse addCodeDetail(CodeDetailVO codeDetail);
|
||||||
|
|
||||||
// 코드 상세 수정 메서드
|
// 코드 상세 수정 메서드
|
||||||
void updateCodeDetail(CodeDetailVO codeDetail);
|
RestResponse updateCodeDetail(CodeDetailVO codeDetail);
|
||||||
|
|
||||||
// 코드 상세 삭제 메서드
|
// 코드 상세 삭제 메서드
|
||||||
void deleteCodeDetail(String codeId);
|
void deleteCodeDetail(String codeGroupId, String codeId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,14 +2,17 @@ package com.itn.admin.itn.code.server.impl;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.config.SecurityUtil;
|
||||||
import com.itn.admin.cmn.msg.RestResponse;
|
import com.itn.admin.cmn.msg.RestResponse;
|
||||||
import com.itn.admin.itn.code.mapper.CodeDetailMapper;
|
import com.itn.admin.itn.code.mapper.CodeDetailMapper;
|
||||||
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||||
import com.itn.admin.itn.code.server.CodeDetailService;
|
import com.itn.admin.itn.code.server.CodeDetailService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class CodeDetailServiceImpl implements CodeDetailService {
|
public class CodeDetailServiceImpl implements CodeDetailService {
|
||||||
|
|
||||||
@ -22,23 +25,51 @@ public class CodeDetailServiceImpl implements CodeDetailService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CodeDetailVO getCodeDetailById(String codeId) {
|
public CodeDetailVO getCodeDetailById(String codeGroupId, String codeId) {
|
||||||
return codeDetailMapper.findById(codeId);
|
CodeDetailVO codeDetailVO = new CodeDetailVO();
|
||||||
|
return codeDetailMapper.findById(codeGroupId, codeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RestResponse addCodeDetail(CodeDetailVO codeDetail) {
|
public RestResponse addCodeDetail(CodeDetailVO codeDetail) {
|
||||||
codeDetailMapper.insert(codeDetail);
|
|
||||||
|
// 현재 인증된 사용자 정보 가져오기
|
||||||
|
String userId = SecurityUtil.getCurrentUserId();
|
||||||
|
if (userId == null) {
|
||||||
|
log.warn("Failed to retrieve current user ID.");
|
||||||
|
throw new IllegalStateException("Current user ID is not available");
|
||||||
|
}
|
||||||
|
log.info("Updating by user: [{}]", userId);
|
||||||
|
|
||||||
|
codeDetail.setFrstRegisterId(userId);
|
||||||
|
codeDetail.setLastUpdusrId(userId);
|
||||||
|
try {
|
||||||
|
codeDetailMapper.insert(codeDetail);
|
||||||
|
}catch (Exception e) {
|
||||||
|
return new RestResponse(HttpStatus.BAD_REQUEST, "코드 ID:"+ codeDetail.getCodeId() + " 를 확인해주세요. \n이미 등록되어 있을 수 있습니다." , codeDetail.getCodeName());
|
||||||
|
}
|
||||||
|
|
||||||
return new RestResponse(HttpStatus.OK, "등록되었습니다", codeDetail.getCodeName());
|
return new RestResponse(HttpStatus.OK, "등록되었습니다", codeDetail.getCodeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateCodeDetail(CodeDetailVO codeDetail) {
|
public RestResponse updateCodeDetail(CodeDetailVO codeDetail) {
|
||||||
|
|
||||||
|
// 현재 인증된 사용자 정보 가져오기
|
||||||
|
String userId = SecurityUtil.getCurrentUserId();
|
||||||
|
if (userId == null) {
|
||||||
|
log.warn("Failed to retrieve current user ID.");
|
||||||
|
throw new IllegalStateException("Current user ID is not available");
|
||||||
|
}
|
||||||
|
log.info("Updating by user: [{}]", userId);
|
||||||
|
|
||||||
|
codeDetail.setLastUpdusrId(userId);
|
||||||
codeDetailMapper.update(codeDetail);
|
codeDetailMapper.update(codeDetail);
|
||||||
|
return new RestResponse(HttpStatus.OK, "등록되었습니다", codeDetail.getCodeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteCodeDetail(String codeId) {
|
public void deleteCodeDetail(String codeGroupId, String codeId){
|
||||||
codeDetailMapper.delete(codeId);
|
codeDetailMapper.delete(codeGroupId, codeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,13 +3,16 @@ package com.itn.admin.itn.code.web;
|
|||||||
import com.itn.admin.cmn.msg.RestResponse;
|
import com.itn.admin.cmn.msg.RestResponse;
|
||||||
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||||
import com.itn.admin.itn.code.server.CodeDetailService;
|
import com.itn.admin.itn.code.server.CodeDetailService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/code-details") // URL 경로를 '/api/code-details'로 변경
|
@RequestMapping("/api/code-details") // URL 경로를 '/api/code-details'로 변경
|
||||||
public class CodeDetailRestController {
|
public class CodeDetailRestController {
|
||||||
@ -24,9 +27,9 @@ public class CodeDetailRestController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 특정 코드 상세를 ID로 가져오는 메서드
|
// 특정 코드 상세를 ID로 가져오는 메서드
|
||||||
@GetMapping("/detail/{codeId}")
|
@GetMapping("/detail/{codeGroupId}/{codeId}")
|
||||||
public CodeDetailVO getCodeDetailById(@PathVariable String codeId) {
|
public CodeDetailVO getCodeDetailById(@PathVariable String codeGroupId,@PathVariable String codeId) {
|
||||||
return codeDetailService.getCodeDetailById(codeId);
|
return codeDetailService.getCodeDetailById(codeGroupId, codeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 코드 상세 추가 메서드
|
// 코드 상세 추가 메서드
|
||||||
@ -37,14 +40,16 @@ public class CodeDetailRestController {
|
|||||||
|
|
||||||
// 코드 상세 수정 메서드
|
// 코드 상세 수정 메서드
|
||||||
@PutMapping("/detail/{codeId}")
|
@PutMapping("/detail/{codeId}")
|
||||||
public void updateCodeDetail(@PathVariable String codeId, @RequestBody CodeDetailVO codeDetail) {
|
public ResponseEntity<RestResponse> updateCodeDetail(@PathVariable String codeId, @RequestBody CodeDetailVO codeDetail) {
|
||||||
codeDetail.setCodeId(codeId);
|
// log.info("codeDetail :: [{}]", codeDetail.toString());
|
||||||
codeDetailService.updateCodeDetail(codeDetail);
|
|
||||||
|
return ResponseEntity.ok().body(codeDetailService.updateCodeDetail(codeDetail));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 코드 상세 삭제 메서드
|
// 코드 상세 삭제 메서드
|
||||||
@DeleteMapping("/detail/{codeId}")
|
@DeleteMapping("/detail/{codeGroupId}/{codeId}")
|
||||||
public void deleteCodeDetail(@PathVariable String codeId) {
|
public void deleteCodeDetail(@PathVariable String codeGroupId,@PathVariable String codeId) {
|
||||||
codeDetailService.deleteCodeDetail(codeId);
|
codeDetailService.deleteCodeDetail(codeGroupId, codeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,4 +20,8 @@ public interface SpamMapper {
|
|||||||
List<SpamVO> getSpamList(SpamVO spamVO);
|
List<SpamVO> getSpamList(SpamVO spamVO);
|
||||||
|
|
||||||
int getTotalRecordCount();
|
int getTotalRecordCount();
|
||||||
|
|
||||||
|
SpamVO findById(String spamId);
|
||||||
|
|
||||||
|
void updateByKeywordsAndChcKeywordsWhereSpamId(SpamVO spamVO);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.itn.admin.itn.mjon.spam.mapper.domain;
|
package com.itn.admin.itn.mjon.spam.mapper.domain;
|
||||||
|
|
||||||
import com.itn.admin.cmn.vo.CmnVO;
|
import com.itn.admin.cmn.vo.CmnVO;
|
||||||
|
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -30,9 +31,9 @@ public class SpamVO extends CmnVO implements Serializable {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private int spamId; // 스팸 ID
|
private int spamId; // 스팸 ID
|
||||||
private String msgGroupId; // 문자그룹ID
|
|
||||||
private String smsTxt; // 문자내용
|
private String smsTxt; // 문자내용
|
||||||
private String spamRsn; // 스팸사유
|
private String spamRsnCode01; // 스팸코드01
|
||||||
|
private String spamRsnCode02; // 스팸코드02
|
||||||
private String keywords; // 문자에 포함된 단어
|
private String keywords; // 문자에 포함된 단어
|
||||||
private String chcKeywords; // 스팸에 해당하는 단어
|
private String chcKeywords; // 스팸에 해당하는 단어
|
||||||
private LocalDateTime timestamp; // 요청 시간
|
private LocalDateTime timestamp; // 요청 시간
|
||||||
@ -43,6 +44,11 @@ public class SpamVO extends CmnVO implements Serializable {
|
|||||||
private LocalDateTime lastUpdtPnttm; // 최종수정일자
|
private LocalDateTime lastUpdtPnttm; // 최종수정일자
|
||||||
|
|
||||||
|
|
||||||
|
private List<CodeDetailVO> CodeDetailList; // 최종수정일자
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// spam_keywords TB 외 필드들
|
// spam_keywords TB 외 필드들
|
||||||
private List<String> keywordList; // 키워드 리스트
|
private List<String> keywordList; // 키워드 리스트
|
||||||
|
private List<String> chcKeywordList; // 키워드 리스트
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
package com.itn.admin.itn.mjon.spam.service;
|
package com.itn.admin.itn.mjon.spam.service;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.msg.RestResponse;
|
||||||
|
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||||
import com.itn.admin.itn.mjon.spam.mapper.domain.SpamVO;
|
import com.itn.admin.itn.mjon.spam.mapper.domain.SpamVO;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -13,4 +15,8 @@ public interface SpamService {
|
|||||||
void analyze();
|
void analyze();
|
||||||
|
|
||||||
Map<String, Object> getSpamList(SpamVO spamVO);
|
Map<String, Object> getSpamList(SpamVO spamVO);
|
||||||
|
|
||||||
|
RestResponse updateKeyword(String spamId, String word);
|
||||||
|
|
||||||
|
RestResponse updateChcKeyword(String spamId, String word);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,13 @@
|
|||||||
package com.itn.admin.itn.mjon.spam.service.impl;
|
package com.itn.admin.itn.mjon.spam.service.impl;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.itn.admin.cmn.msg.RestResponse;
|
||||||
|
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||||
|
import com.itn.admin.itn.code.server.CodeDetailService;
|
||||||
import com.itn.admin.itn.mjon.spam.mapper.SpamMapper;
|
import com.itn.admin.itn.mjon.spam.mapper.SpamMapper;
|
||||||
import com.itn.admin.itn.mjon.spam.mapper.domain.SpamVO;
|
import com.itn.admin.itn.mjon.spam.mapper.domain.SpamVO;
|
||||||
import com.itn.admin.itn.mjon.spam.service.SpamService;
|
import com.itn.admin.itn.mjon.spam.service.SpamService;
|
||||||
|
import jakarta.servlet.ServletOutputStream;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.*;
|
import org.springframework.http.*;
|
||||||
@ -11,6 +15,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -20,11 +25,13 @@ public class SpamServiceImpl implements SpamService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
SpamMapper spamMapper;
|
SpamMapper spamMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CodeDetailService codeDetailService;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final static private String PYTHON_ANALYZE_URL= "http://192.168.0.78:5000/word_analyze";
|
final static private String PYTHON_ANALYZE_URL= "http://192.168.0.78:5000/word_analyze";
|
||||||
|
|
||||||
public SpamServiceImpl(RestTemplate restTemplate) {
|
public SpamServiceImpl(RestTemplate restTemplate) {
|
||||||
@ -40,7 +47,6 @@ public class SpamServiceImpl implements SpamService {
|
|||||||
|
|
||||||
map.put("spamList", spamList);
|
map.put("spamList", spamList);
|
||||||
|
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,19 +120,90 @@ public class SpamServiceImpl implements SpamService {
|
|||||||
|
|
||||||
List<SpamVO> spamList = spamMapper.getSpamList(spamVO);
|
List<SpamVO> spamList = spamMapper.getSpamList(spamVO);
|
||||||
|
|
||||||
|
|
||||||
// 키워드를 버튼용 배열로 변환
|
// 키워드를 버튼용 배열로 변환
|
||||||
for (SpamVO spam : spamList) {
|
for (SpamVO spam : spamList) {
|
||||||
if (spam.getKeywords() != null) {
|
if (spam.getKeywords() != null) {
|
||||||
spam.setKeywordList(Arrays.asList(spam.getKeywords().split(", ")));
|
spam.setKeywordList(Arrays.asList(spam.getKeywords().split(", ")));
|
||||||
}
|
}
|
||||||
|
if (spam.getChcKeywords() != null) {
|
||||||
|
spam.setChcKeywordList(Arrays.asList(spam.getChcKeywords().split(", ")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<CodeDetailVO> rsnCode02List = new ArrayList<>();
|
||||||
|
// 키워드를 버튼용 배열로 변환
|
||||||
|
for (SpamVO spam : spamList) {
|
||||||
|
if (spam.getSpamRsnCode01() != null) {
|
||||||
|
spam.setCodeDetailList(codeDetailService.getDetailsByGroupId("SPAM"+spam.getSpamRsnCode01()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CodeDetailVO> rsnCode01List = codeDetailService.getDetailsByGroupId("SPAM");
|
||||||
|
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
Map<String, Object> resultMap = new HashMap<>();
|
||||||
resultMap.put("spamList", spamList);
|
resultMap.put("spamList", spamList);
|
||||||
resultMap.put("totalRecordCount", totalRecordCount);
|
resultMap.put("totalRecordCount", totalRecordCount);
|
||||||
resultMap.put("totalPageCount", spamVO.getTotalPageCount());
|
resultMap.put("totalPageCount", spamVO.getTotalPageCount());
|
||||||
|
|
||||||
|
resultMap.put("rsnCode01List", rsnCode01List);
|
||||||
|
|
||||||
return resultMap;
|
return resultMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse updateChcKeyword(String spamId, String word) {
|
||||||
|
SpamVO spamVO = spamMapper.findById(spamId);
|
||||||
|
|
||||||
|
spamVO.setKeywords(removeString(spamVO.getKeywords(),word));
|
||||||
|
spamVO.setChcKeywords(addString(spamVO.getChcKeywords(),word));
|
||||||
|
|
||||||
|
spamMapper.updateByKeywordsAndChcKeywordsWhereSpamId(spamVO);
|
||||||
|
|
||||||
|
return new RestResponse(HttpStatus.OK, word+" 단어가 선택되었습니다.","");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse updateKeyword(String spamId, String word) {
|
||||||
|
SpamVO spamVO = spamMapper.findById(spamId);
|
||||||
|
|
||||||
|
spamVO.setChcKeywords(removeString(spamVO.getChcKeywords(),word));
|
||||||
|
spamVO.setKeywords(addString(spamVO.getKeywords(),word));
|
||||||
|
|
||||||
|
|
||||||
|
spamMapper.updateByKeywordsAndChcKeywordsWhereSpamId(spamVO);
|
||||||
|
|
||||||
|
return new RestResponse(HttpStatus.OK, word+" 단어가 취소되었습니다.","");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String removeString(String keywords, String word) {
|
||||||
|
String[] keywordArray = keywords.split(", ");
|
||||||
|
return Arrays.stream(keywordArray)
|
||||||
|
.filter(s -> !s.equals(word))
|
||||||
|
.collect(Collectors.joining(", "));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String addString(String keywords, String word) {
|
||||||
|
|
||||||
|
if (keywords == null) {
|
||||||
|
keywords = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] keywordArray = keywords.split(", ");
|
||||||
|
boolean wordExists = Arrays.stream(keywordArray).anyMatch(kw -> kw.equals(word));
|
||||||
|
if (!wordExists) {
|
||||||
|
// keywords 문자열이 비어있지 않은 경우, 쉼표를 추가한 후 새로운 단어를 추가합니다.
|
||||||
|
if (!keywords.isEmpty()) {
|
||||||
|
keywords += ", " + word;
|
||||||
|
} else {
|
||||||
|
// keywords가 비어있으면, 쉼표 없이 새로운 단어를 추가합니다.
|
||||||
|
keywords = word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keywords;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
package com.itn.admin.itn.mjon.spam.web;
|
package com.itn.admin.itn.mjon.spam.web;
|
||||||
|
|
||||||
|
import com.itn.admin.cmn.msg.RestResponse;
|
||||||
|
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||||
import com.itn.admin.itn.mjon.spam.service.SpamService;
|
import com.itn.admin.itn.mjon.spam.service.SpamService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -21,15 +26,21 @@ public class RestSpamController {
|
|||||||
|
|
||||||
@GetMapping(value = "/mjon/spam/analyze")
|
@GetMapping(value = "/mjon/spam/analyze")
|
||||||
public void analyze(Model model) {
|
public void analyze(Model model) {
|
||||||
|
|
||||||
|
|
||||||
spamService.analyze();
|
spamService.analyze();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 키워드 -> 핵심키워드 :: keywords -> chc_keywords
|
||||||
|
@PutMapping("/mjon/spam/chcKeyword/{spamId}/{word}")
|
||||||
|
public ResponseEntity<RestResponse> updateChcKeyword(@PathVariable String spamId, @PathVariable String word) {
|
||||||
|
return ResponseEntity.ok().body(spamService.updateChcKeyword(spamId, word));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 핵심키워드 -> 키워드 :: chc_keywords -> keywords
|
||||||
|
@PutMapping("/mjon/spam/keyword/{spamId}/{word}")
|
||||||
|
public ResponseEntity<RestResponse> updateKeyword(@PathVariable String spamId, @PathVariable String word) {
|
||||||
|
return ResponseEntity.ok().body(spamService.updateKeyword(spamId, word));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,9 +30,15 @@ public class SpamController {
|
|||||||
|
|
||||||
model.addAttribute("spamList", map.get("spamList"));
|
model.addAttribute("spamList", map.get("spamList"));
|
||||||
model.addAttribute("pagingVO", spamVO);
|
model.addAttribute("pagingVO", spamVO);
|
||||||
|
model.addAttribute("rsnCode01List", map.get("rsnCode01List"));
|
||||||
|
|
||||||
return "mjon/spam/select";
|
return "mjon/spam/select";
|
||||||
}
|
}
|
||||||
|
@GetMapping(value = "/mjon/spam/chk")
|
||||||
|
public String chk(@ModelAttribute("spamVO") SpamVO spamVO, Model model) {
|
||||||
|
|
||||||
|
return "mjon/spam/chk";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,7 @@ spring.main.datasource.password=itntest123
|
|||||||
#
|
#
|
||||||
spring.commute.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
|
spring.commute.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
|
||||||
spring.commute.datasource.jdbc-url=jdbc:log4jdbc:mysql://192.168.0.200:3312/biostar2_ac?serverTimezone=Asia/Seoul
|
spring.commute.datasource.jdbc-url=jdbc:log4jdbc:mysql://192.168.0.200:3312/biostar2_ac?serverTimezone=Asia/Seoul
|
||||||
|
#spring.commute.datasource.jdbc-url=jdbc:log4jdbc:mysql://192.168.0.30:3312/biostar2_ac?serverTimezone=Asia/Seoul
|
||||||
spring.commute.datasource.username=root
|
spring.commute.datasource.username=root
|
||||||
spring.commute.datasource.password=itntest!
|
spring.commute.datasource.password=itntest!
|
||||||
|
|
||||||
@ -54,7 +55,8 @@ spring.mjagent.server.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.Dri
|
|||||||
spring.mjagent.server.datasource.jdbc-url=jdbc:log4jdbc:mysql://119.193.215.98:3306/mjon_agent_back?serverTimezone=Asia/Seoul
|
spring.mjagent.server.datasource.jdbc-url=jdbc:log4jdbc:mysql://119.193.215.98:3306/mjon_agent_back?serverTimezone=Asia/Seoul
|
||||||
spring.mjagent.server.datasource.username=mjonUr_agent
|
spring.mjagent.server.datasource.username=mjonUr_agent
|
||||||
spring.mjagent.server.datasource.password=mjagent123$
|
spring.mjagent.server.datasource.password=mjagent123$
|
||||||
|
spring.mjagent.server.datasource.hikari.minimum-idle=2
|
||||||
|
spring.mjagent.server.datasource.hikari.maximum-pool-size=4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,7 @@
|
|||||||
MUNJAON_MSG
|
MUNJAON_MSG
|
||||||
WHERE SEND_STATUS != 1000
|
WHERE SEND_STATUS != 1000
|
||||||
and MSG_TYPE = #{msgType}
|
and MSG_TYPE = #{msgType}
|
||||||
|
and MESSAGE LIKE CONCAT(#{message}, '%')
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 리포트할때 현재 데이터가 LOG 테이블에 이동됐는지 확인 -->
|
<!-- 리포트할때 현재 데이터가 LOG 테이블에 이동됐는지 확인 -->
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<!-- 특정 코드 상세를 ID로 조회하는 쿼리 -->
|
<!-- 특정 코드 상세를 ID로 조회하는 쿼리 -->
|
||||||
<select id="findById" parameterType="String" resultType="codeDetailVO">
|
<select id="findById" parameterType="String" resultType="codeDetailVO">
|
||||||
SELECT * FROM common_code_detail WHERE code_id = #{codeId}
|
SELECT * FROM common_code_detail WHERE code_id = #{codeId} AND code_group_id = #{codeGroupId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 코드 상세를 추가하는 쿼리 -->
|
<!-- 코드 상세를 추가하는 쿼리 -->
|
||||||
@ -35,6 +35,6 @@
|
|||||||
|
|
||||||
<!-- 코드 상세를 삭제하는 쿼리 -->
|
<!-- 코드 상세를 삭제하는 쿼리 -->
|
||||||
<delete id="delete" parameterType="String">
|
<delete id="delete" parameterType="String">
|
||||||
DELETE FROM common_code_detail WHERE code_id = #{codeId}
|
DELETE FROM common_code_detail WHERE code_id = #{codeId} AND code_group_id = #{codeGroupId}
|
||||||
</delete>
|
</delete>
|
||||||
</mapper>
|
</mapper>
|
||||||
@ -12,9 +12,9 @@
|
|||||||
<select id="getSpamList" parameterType="spamVO" resultType="SpamVO">
|
<select id="getSpamList" parameterType="spamVO" resultType="SpamVO">
|
||||||
SELECT
|
SELECT
|
||||||
SPAM_ID,
|
SPAM_ID,
|
||||||
MSG_GROUP_ID,
|
|
||||||
SMS_TXT,
|
SMS_TXT,
|
||||||
SPAM_RSN,
|
SPAM_RSN_CODE_01,
|
||||||
|
SPAM_RSN_CODE_02,
|
||||||
KEYWORDS,
|
KEYWORDS,
|
||||||
CHC_KEYWORDS,
|
CHC_KEYWORDS,
|
||||||
TIMESTAMP,
|
TIMESTAMP,
|
||||||
@ -25,6 +25,7 @@
|
|||||||
LAST_UPDT_PNTTM
|
LAST_UPDT_PNTTM
|
||||||
FROM
|
FROM
|
||||||
spam_keywords
|
spam_keywords
|
||||||
|
/*where chc_keywords is null*/
|
||||||
ORDER BY
|
ORDER BY
|
||||||
SPAM_ID
|
SPAM_ID
|
||||||
LIMIT #{limit} OFFSET #{offset}
|
LIMIT #{limit} OFFSET #{offset}
|
||||||
@ -35,9 +36,9 @@
|
|||||||
<select id="getList" parameterType="spamVO" resultType="spamVO">
|
<select id="getList" parameterType="spamVO" resultType="spamVO">
|
||||||
SELECT
|
SELECT
|
||||||
SPAM_ID,
|
SPAM_ID,
|
||||||
MSG_GROUP_ID,
|
|
||||||
SMS_TXT,
|
SMS_TXT,
|
||||||
SPAM_RSN,
|
SPAM_RSN_CODE_01,
|
||||||
|
SPAM_RSN_CODE_02,
|
||||||
KEYWORDS,
|
KEYWORDS,
|
||||||
CHC_KEYWORDS,
|
CHC_KEYWORDS,
|
||||||
TIMESTAMP,
|
TIMESTAMP,
|
||||||
@ -73,9 +74,9 @@
|
|||||||
<select id="getListWhereKeywordsIsNull" parameterType="spamVO" resultType="spamVO">
|
<select id="getListWhereKeywordsIsNull" parameterType="spamVO" resultType="spamVO">
|
||||||
SELECT
|
SELECT
|
||||||
SPAM_ID,
|
SPAM_ID,
|
||||||
MSG_GROUP_ID,
|
|
||||||
SMS_TXT,
|
SMS_TXT,
|
||||||
SPAM_RSN,
|
SPAM_RSN_CODE_01,
|
||||||
|
SPAM_RSN_CODE_02,
|
||||||
KEYWORDS,
|
KEYWORDS,
|
||||||
CHC_KEYWORDS,
|
CHC_KEYWORDS,
|
||||||
TIMESTAMP,
|
TIMESTAMP,
|
||||||
@ -90,10 +91,52 @@
|
|||||||
KEYWORDS IS NULL
|
KEYWORDS IS NULL
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="findById" parameterType="String" resultType="spamVO">
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
spam_keywords
|
||||||
|
WHERE
|
||||||
|
spam_id = #{spamId}
|
||||||
|
</select>
|
||||||
|
|
||||||
<update id="update">
|
<update id="update">
|
||||||
UPDATE spam_keywords
|
UPDATE spam_keywords
|
||||||
SET keywords = #{keywords}
|
SET keywords = #{keywords}
|
||||||
WHERE spam_id = #{spamId}
|
WHERE spam_id = #{spamId}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<!-- 정확히 일치하는 단어와 그 개수를 검색하는 쿼리 -->
|
||||||
|
<select id="selectByExactWordsWithCount" resultType="map">
|
||||||
|
SELECT
|
||||||
|
*,
|
||||||
|
(
|
||||||
|
<foreach item="word" index="index" collection="words" separator="+">
|
||||||
|
CASE WHEN FIND_IN_SET(#{word}, REPLACE(chc_keywords, ', ', ',')) THEN 1 ELSE 0 END
|
||||||
|
</foreach>
|
||||||
|
) AS match_count,
|
||||||
|
CONCAT(
|
||||||
|
<foreach item="word" index="index" collection="words" separator=", ">
|
||||||
|
IF(FIND_IN_SET(#{word}, REPLACE(chc_keywords, ', ', ',')), #{word}, NULL)
|
||||||
|
</foreach>
|
||||||
|
) AS matched_words
|
||||||
|
FROM spam_keywords
|
||||||
|
WHERE
|
||||||
|
<foreach item="word" index="index" collection="words" separator=" OR ">
|
||||||
|
FIND_IN_SET(#{word}, REPLACE(chc_keywords, ', ', ',')) > 0
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="updateByKeywordsAndChcKeywordsWhereSpamId" parameterType="spamVO">
|
||||||
|
|
||||||
|
UPDATE spam_keywords
|
||||||
|
SET keywords = #{keywords},
|
||||||
|
chc_keywords = #{chcKeywords}
|
||||||
|
WHERE spam_id = #{spamId}
|
||||||
|
|
||||||
|
</update>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
@ -216,14 +216,16 @@ function oneStopReporingTimer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function fn_oneReportCntAndTime(){
|
function fn_oneReportCntAndTime(userId){
|
||||||
|
|
||||||
// 폼 데이터를 수집
|
// 폼 데이터를 수집
|
||||||
var formData = new FormData($("#divOneSms .sendForm")[0]);
|
var formData = new FormData($("#divOneSms .sendForm")[0]);
|
||||||
|
|
||||||
var jsonObject = {};
|
var jsonObject = {};
|
||||||
formData.forEach((value, key) => {
|
formData.forEach((value, key) => {
|
||||||
jsonObject[key] = value;
|
if (!(value instanceof File)) {
|
||||||
|
jsonObject[key] = value;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
jsonObject['userId'] = userId;
|
jsonObject['userId'] = userId;
|
||||||
|
|
||||||
@ -239,9 +241,15 @@ function fn_oneReportCntAndTime(){
|
|||||||
|
|
||||||
if (data.status == 'OK') {
|
if (data.status == 'OK') {
|
||||||
var cnt = data.data;
|
var cnt = data.data;
|
||||||
|
$('#divOneSmsCard .reportStartCnt').text(cnt);
|
||||||
|
|
||||||
$('#divOneSmsCard .reportSndCnt').text(cnt);
|
var transferCnt = $('#divOneSmsCard .insertCnt').text();
|
||||||
if(cnt == 0){
|
|
||||||
|
|
||||||
|
console.log('cnt : ', cnt);
|
||||||
|
console.log('reportStartCnt : ', transferCnt);
|
||||||
|
console.log('');
|
||||||
|
if(cnt >= Number(transferCnt)){
|
||||||
oneStopReporingTimer();
|
oneStopReporingTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -245,8 +245,9 @@ function fn_twoReportCntAndTime(userId){
|
|||||||
if (data.status == 'OK') {
|
if (data.status == 'OK') {
|
||||||
var cnt = data.data;
|
var cnt = data.data;
|
||||||
|
|
||||||
|
console.log('cnt : ', cnt);
|
||||||
// 리포트 영역에 cnt 추가
|
// 리포트 영역에 cnt 추가
|
||||||
$('#divTwoSmsCard .reportSndCnt').text(cnt);
|
$('#divTwoSmsCard .reportStartCnt').text(cnt);
|
||||||
// server DB에 update한 건수와 cnt비교
|
// server DB에 update한 건수와 cnt비교
|
||||||
var transferCnt = $('#divTwoSmsCard .insertCnt').text();
|
var transferCnt = $('#divTwoSmsCard .insertCnt').text();
|
||||||
|
|
||||||
|
|||||||
@ -117,7 +117,7 @@
|
|||||||
title: title,
|
title: title,
|
||||||
subtitle: '',
|
subtitle: '',
|
||||||
autohide : true,
|
autohide : true,
|
||||||
delay: 3000,
|
delay: 6000,
|
||||||
body: msg
|
body: msg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,6 +113,14 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<ul class="nav nav-treeview">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a th:href="@{/mjon/spam/chk}" class="nav-link">
|
||||||
|
<i class="fas fa-filter nav-icon"></i>
|
||||||
|
<p>스팸비교</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@ -150,7 +150,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
|
||||||
<button type="button" class="btn btn-primary" onclick="updateCodeGroup()">저장</button>
|
<button type="button" class="btn btn-primary" onclick="updateCodeGroup()">수정</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -239,6 +239,56 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 공통 코드 상세 수정 모달 -->
|
||||||
|
<div class="modal fade" id="editCodeDetailModal" tabindex="-1" role="dialog" aria-labelledby="editCodeDetailModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="editCodeDetailModalLabel">공통 코드 상세 수정</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="editCodeDetailForm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editDetailCodeId">코드 ID</label>
|
||||||
|
<input type="text" class="form-control" id="editDetailCodeId" name="codeId" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editDetailCodeGroupId">코드 그룹 ID</label>
|
||||||
|
<input type="text" class="form-control" id="editDetailCodeGroupId" name="codeGroupId" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editDetailCodeName">코드 이름</label>
|
||||||
|
<input type="text" class="form-control" id="editDetailCodeName" name="codeName" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editDetailCodeValue">코드 값</label>
|
||||||
|
<input type="text" class="form-control" id="editDetailCodeValue" name="codeValue" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editDetailSortOrder">정렬 순서</label>
|
||||||
|
<input type="number" class="form-control" id="editDetailSortOrder" name="sortOrder">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editDetailUseYn">사용 여부</label>
|
||||||
|
<select class="form-control" id="editDetailUseYn" name="useYn">
|
||||||
|
<option value="Y">Yes</option>
|
||||||
|
<option value="N">No</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="updateCodeDetail()">수정</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<footer class="main-footer" th:insert="~{fragments/footer :: footerFragment}"></footer>
|
<footer class="main-footer" th:insert="~{fragments/footer :: footerFragment}"></footer>
|
||||||
|
|
||||||
<!-- Control Sidebar -->
|
<!-- Control Sidebar -->
|
||||||
@ -373,8 +423,8 @@
|
|||||||
'<td>' + detail.codeValue + '</td>' +
|
'<td>' + detail.codeValue + '</td>' +
|
||||||
'<td>' + detail.sortOrder + '</td>' +
|
'<td>' + detail.sortOrder + '</td>' +
|
||||||
'<td>' + detail.useYn + '</td>' +
|
'<td>' + detail.useYn + '</td>' +
|
||||||
'<td><button class="btn btn-primary btn-sm" onclick="editCodeDetail(\'' + detail.codeId + '\')">수정</button></td>' +
|
'<td><button class="btn btn-primary btn-sm" onclick="editCodeDetail(\'' + codeGroupId + '\', \'' + detail.codeId + '\')">수정</button></td>' +
|
||||||
'<td><button class="btn btn-danger btn-sm" onclick="deleteCodeDetail(\'' + detail.codeId + '\')">삭제</button></td>' +
|
'<td><button class="btn btn-danger btn-sm" onclick="deleteCodeDetail(\'' + codeGroupId+'\', \'' + detail.codeId + '\')">삭제</button></td>' +
|
||||||
'</tr>');
|
'</tr>');
|
||||||
});
|
});
|
||||||
$('#commonCodeDetailModal').modal('show');
|
$('#commonCodeDetailModal').modal('show');
|
||||||
@ -425,9 +475,17 @@
|
|||||||
contentType: 'application/json; charset=utf-8',
|
contentType: 'application/json; charset=utf-8',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$('#addCodeDetailModal').modal('hide'); // 모달 닫기
|
|
||||||
showDetails(formData.codeGroupId); // 상세 보기 갱신
|
if(data.status === 'OK'){
|
||||||
fn_successAlert("성공", data.data +'가 '+data.msg);
|
|
||||||
|
$('#addCodeDetailForm')[0].reset(); // form reset
|
||||||
|
$('#addCodeDetailModal').modal('hide'); // 모달 닫기
|
||||||
|
showDetails(formData.codeGroupId); // 상세 보기 갱신
|
||||||
|
fn_successAlert("성공", data.data +'가 '+data.msg);
|
||||||
|
}else{
|
||||||
|
fn_failedAlert("실패", data.msg);
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
error: function(xhr) {
|
error: function(xhr) {
|
||||||
alert('공통 코드 상세 추가 중 오류가 발생했습니다.');
|
alert('공통 코드 상세 추가 중 오류가 발생했습니다.');
|
||||||
@ -435,29 +493,64 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 코드 상세 수정 모달을 표시하는 함수
|
||||||
|
window.editCodeDetail = function(codeGroupId, codeId) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/code-details/detail/' + codeGroupId + '/' + codeId, // API 엔드포인트
|
||||||
|
type: 'GET',
|
||||||
// 코드 상세 추가 함수
|
success: function(data) {
|
||||||
window.addCodeDetail = function() {
|
$('#editDetailCodeId').val(data.codeId);
|
||||||
// 코드 상세 추가 모달을 띄우거나, 필요한 로직 추가
|
$('#editDetailCodeGroupId').val(data.codeGroupId);
|
||||||
|
$('#editDetailCodeName').val(data.codeName);
|
||||||
|
$('#editDetailCodeValue').val(data.codeValue);
|
||||||
|
$('#editDetailSortOrder').val(data.sortOrder);
|
||||||
|
$('#editDetailUseYn').val(data.useYn);
|
||||||
|
$('#editCodeDetailModal').modal('show'); // 수정 모달 표시
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
alert('코드 상세 정보를 불러오는 데 실패했습니다.');
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 코드 상세 수정 함수
|
// 코드 상세 수정 함수
|
||||||
window.editCodeDetail = function(codeId) {
|
window.updateCodeDetail = function() {
|
||||||
// 코드 상세 수정 로직 추가
|
var formDataArray = $("#editCodeDetailForm").serializeArray();
|
||||||
|
var formData = {};
|
||||||
|
|
||||||
|
// 배열 데이터를 JSON 객체로 변환
|
||||||
|
$.each(formDataArray, function(_, field) {
|
||||||
|
formData[field.name] = field.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/code-details/detail/' + formData.codeId, // API 엔드포인트
|
||||||
|
type: 'PUT',
|
||||||
|
data: JSON.stringify(formData),
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json; charset=utf-8',
|
||||||
|
success: function(data) {
|
||||||
|
$('#editCodeDetailModal').modal('hide'); // 모달 닫기
|
||||||
|
showDetails(formData.codeGroupId); // 상세 보기 갱신
|
||||||
|
fn_successAlert("성공", data.data +'가 '+data.msg);
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
alert('코드 상세 수정 중 오류가 발생했습니다.');
|
||||||
|
console.log('xhr : ', xhr);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 코드 상세 삭제 함수
|
// 코드 상세 삭제 함수
|
||||||
window.deleteCodeDetail = function(codeId) {
|
window.deleteCodeDetail = function(codeGroupId, codeId) {
|
||||||
|
|
||||||
if(confirm('삭제하시겠습니까?')) {
|
if(confirm('삭제하시겠습니까?')) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/api/code-details/detail/' + codeId, // 변경된 URL
|
url: '/api/code-details/detail/' + codeGroupId + '/' + codeId, // 변경된 URL
|
||||||
type: 'DELETE',
|
type: 'DELETE',
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
showDetails($('#detailTableBody').data('group-id')); // 갱신을 위해 다시 로드
|
showDetails(codeGroupId); // 갱신을 위해 다시 로드
|
||||||
},
|
},
|
||||||
error: function(xhr) {
|
error: function(xhr) {
|
||||||
alert('오류가 발생했습니다.');
|
alert('오류가 발생했습니다.');
|
||||||
|
|||||||
199
src/main/resources/templates/mjon/spam/chk.html
Normal file
199
src/main/resources/templates/mjon/spam/chk.html
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="layout">
|
||||||
|
<head>
|
||||||
|
<title>스팸 단어 선택</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||||
|
<link rel="stylesheet" th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||||
|
<link rel="stylesheet" th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.table-fixed thead {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1020;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-fixed tbody td, .table-fixed thead th {
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 중앙 정렬을 위한 추가 스타일 */
|
||||||
|
.center-align {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 통계 정보 구분 */
|
||||||
|
.stats-info {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 메시지 입력과 버튼 정렬을 위한 스타일 */
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch; /* 세로 높이 맞추기 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group textarea {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group button {
|
||||||
|
align-self: stretch; /* 버튼 높이를 textarea에 맞춤 */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body layout:fragment="body">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div th:replace="~{fragments/top_nav :: topFragment}"></div>
|
||||||
|
|
||||||
|
<!-- Main Sidebar Container -->
|
||||||
|
<aside class="main-sidebar sidebar-dark-primary elevation-4"
|
||||||
|
th:insert="~{fragments/mainsidebar :: sidebarFragment}">
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<!-- Content Wrapper. Contains page content -->
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<!-- Content Header (Page header) -->
|
||||||
|
<div class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1 class="m-0">스팸 비교</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||||
|
<li class="breadcrumb-item active">스팸 비교</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.content-header -->
|
||||||
|
|
||||||
|
<!-- 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>
|
||||||
|
<!-- /.card-header -->
|
||||||
|
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- 메시지 입력과 버튼 영역 -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="input-group">
|
||||||
|
<textarea class="form-control" id="inputMessage" rows="3" placeholder="메시지를 입력하세요" style="width: 90%;"></textarea>
|
||||||
|
<button type="button" class="btn btn-primary" style="width: 10%;">조회</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 불법/성인 버튼 중앙 정렬 -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 d-flex justify-content-center flex-wrap">
|
||||||
|
<button type="button" class="btn btn-primary mx-2 my-2">불법 145건</button>
|
||||||
|
<button type="button" class="btn btn-secondary mx-2 my-2">성인 43건</button>
|
||||||
|
<button type="button" class="btn btn-success mx-2 my-2">광고 78건</button>
|
||||||
|
<button type="button" class="btn btn-danger mx-2 my-2">금융 20건</button>
|
||||||
|
<button type="button" class="btn btn-warning mx-2 my-2">스팸 30건</button>
|
||||||
|
<button type="button" class="btn btn-info mx-2 my-2">게임 15건</button>
|
||||||
|
<button type="button" class="btn btn-light mx-2 my-2">의료 9건</button>
|
||||||
|
<button type="button" class="btn btn-dark mx-2 my-2">기타 12건</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary mx-2 my-2">교육 5건</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary mx-2 my-2">이벤트 22건</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 통계 정보 영역 -->
|
||||||
|
<div class="row stats-info">
|
||||||
|
<div class="col-12">
|
||||||
|
<span>문자 개수 총 300건</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 스팸 비교 테이블 영역 -->
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-bordered table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>번호</th>
|
||||||
|
<th>스팸문자</th>
|
||||||
|
<th>핵심단어</th>
|
||||||
|
<th>매칭단어 개수</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>1</td>
|
||||||
|
<td>(광고)♥봄맞이 특별이벤트 진행중♥ ...</td>
|
||||||
|
<td>바다, 서비스, 갯수...</td>
|
||||||
|
<td>3</td>
|
||||||
|
</tr>
|
||||||
|
<!-- 추가 행들 필요 시 여기 추가 -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.card-body -->
|
||||||
|
</div>
|
||||||
|
<!-- /.card -->
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
</section>
|
||||||
|
<!-- /Main content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.content-wrapper -->
|
||||||
|
|
||||||
|
<footer class="main-footer"
|
||||||
|
th:insert="~{fragments/footer :: footerFragment}">
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Control Sidebar -->
|
||||||
|
<aside class="control-sidebar control-sidebar-dark">
|
||||||
|
<!-- Control sidebar content goes here -->
|
||||||
|
</aside>
|
||||||
|
<!-- /.control-sidebar -->
|
||||||
|
</div>
|
||||||
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
// 조회 버튼 클릭 시 이벤트 핸들러
|
||||||
|
$('button.btn-primary').on('click', function () {
|
||||||
|
var inputMessage = $('#inputMessage').val();
|
||||||
|
// AJAX 호출이나 데이터 처리 로직 추가 가능
|
||||||
|
alert('조회 버튼 클릭! 입력된 메시지: ' + inputMessage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -111,28 +111,30 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 5%;">번호</th>
|
<th style="width: 5%;">번호</th>
|
||||||
<th style="width: 25%;">스팸문자</th>
|
<th style="width: 20%;">스팸문자</th>
|
||||||
<th style="width: 35%;">복합명사</th>
|
<th style="width: 25%;">복합명사</th>
|
||||||
<th style="width: 25%;">핵심 단어</th>
|
<th style="width: 20%;">핵심 단어</th>
|
||||||
<th style="width: 10%;">스팸분류</th>
|
<th style="width: 10%;">스팸분류01</th>
|
||||||
|
<th style="width: 10%;">스팸분류02</th>
|
||||||
|
<!-- <th style="width: 10%;">확정</th>-->
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr th:each="spam, iterStat : ${spamList}">
|
<tr th:each="spam, iterStat : ${spamList}">
|
||||||
<td th:text="${iterStat.index + 1}"></td>
|
<td th:text="${(pagingVO.pageNum - 1) * pagingVO.pageSize + iterStat.index + 1}"></td>
|
||||||
<td th:text="${spam.smsTxt}">스팸문자 내용</td>
|
<td th:text="${spam.smsTxt}">스팸문자 내용</td>
|
||||||
<td>
|
<td>
|
||||||
<span th:each="word : ${spam.keywordList}">
|
<!--
|
||||||
<!--
|
- adminLTE3 css 참고
|
||||||
- adminLTE3 css 참고
|
btn: 버튼 스타일을 적용합니다.
|
||||||
btn: 버튼 스타일을 적용합니다.
|
btn-primary: 파란색 배경의 버튼을 만듭니다. 다른 색상은 btn-secondary, btn-success, btn-danger 등으로 변경할 수 있습니다.
|
||||||
btn-primary: 파란색 배경의 버튼을 만듭니다. 다른 색상은 btn-secondary, btn-success, btn-danger 등으로 변경할 수 있습니다.
|
btn-sm: 작은 크기의 버튼을 만듭니다.
|
||||||
btn-sm: 작은 크기의 버튼을 만듭니다.
|
rounded-pill: 모서리를 둥글게 처리하여 pill 형태의 버튼을 만듭니다.
|
||||||
rounded-pill: 모서리를 둥글게 처리하여 pill 형태의 버튼을 만듭니다.
|
|
||||||
|
|
||||||
mx-1: 좌우에 0.25rem(약 4px)의 여백 추가
|
mx-1: 좌우에 0.25rem(약 4px)의 여백 추가
|
||||||
my-1: 상하에 0.25rem(약 4px)의 여백 추가
|
my-1: 상하에 0.25rem(약 4px)의 여백 추가
|
||||||
-->
|
-->
|
||||||
|
<span th:each="word : ${spam.keywordList}">
|
||||||
<button class="btn btn-primary rounded-pill mx-1 my-1"
|
<button class="btn btn-primary rounded-pill mx-1 my-1"
|
||||||
th:text="${word}"
|
th:text="${word}"
|
||||||
th:data-spamid="${spam.spamId}"
|
th:data-spamid="${spam.spamId}"
|
||||||
@ -141,15 +143,43 @@
|
|||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<!-- <td th:text="${spam.keywords}">복합명사 목록</td>-->
|
<!-- <td th:text="${spam.keywords}">복합명사 목록</td>-->
|
||||||
<td th:text="${spam.chcKeywords}">핵심 단어 목록</td>
|
|
||||||
<td>
|
<td>
|
||||||
<select class="form-control" th:value="${spam.categ}">
|
<span th:each="word : ${spam.chcKeywordList}">
|
||||||
<option>선택</option>
|
<button class="btn btn-success rounded-pill mx-1 my-1"
|
||||||
<option value="성인">성인</option>
|
th:text="${word}"
|
||||||
<option value="불법">불법</option>
|
th:data-spamid="${spam.spamId}"
|
||||||
<option value="해당없음">해당없음</option>
|
th:data-word="${word}"
|
||||||
|
th:data-original-td="2"
|
||||||
|
th:data-current-td="3"
|
||||||
|
onclick="handleClick(this)"></button>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select class="form-control select2 rsnCode01"
|
||||||
|
onchange="updateCode02Options(this)">
|
||||||
|
<option value="">선택해주세요.</option>
|
||||||
|
<option th:each="code : ${rsnCode01List}"
|
||||||
|
th:value="${code.codeId}"
|
||||||
|
th:text="${code.codeName}"
|
||||||
|
th:selected="${code.codeId} == ${spam.spamRsnCode01}">
|
||||||
|
Code
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<select class="form-control select2 rsnCode02">
|
||||||
|
<option value="">선택해주세요.</option>
|
||||||
|
<option th:each="code : ${spam.codeDetailList}"
|
||||||
|
th:value="${code.codeId}"
|
||||||
|
th:text="${code.codeName}"
|
||||||
|
th:selected="${code.codeId} == ${spam.spamRsnCode02}">
|
||||||
|
Code
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<!-- <td>-->
|
||||||
|
<!-- <button class="btn btn-success btn-confirm" data-spamid="${spam.spamId}" onclick="confirmSpam(this)">확정</button>-->
|
||||||
|
<!-- </td>-->
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -209,34 +239,137 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- ./wrapper -->
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
<!-- <!– DataTables & Plugins –>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/jszip/jszip.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>-->
|
|
||||||
<!-- <script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>-->
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(document).ready(function() {
|
||||||
|
// 초기화 이후에 값을 출력
|
||||||
|
// $('.rsnCode01').each(function() {
|
||||||
|
// console.log($(this).val());
|
||||||
|
// });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function handleClick(button) {
|
function handleClick(button) {
|
||||||
var spamId = button.getAttribute('data-spamid');
|
var spamId = button.getAttribute('data-spamid');
|
||||||
var word = button.getAttribute('data-word');
|
var word = button.getAttribute('data-word');
|
||||||
console.log("Spam ID:", spamId, "Word:", word);
|
console.log("Spam ID:", spamId, "Word:", word);
|
||||||
// 여기에 추가적인 로직을 구현하세요.
|
// 여기에 추가적인 로직을 구현하세요.
|
||||||
|
var currentTd = button.parentElement.parentElement; // 현재 td 요소
|
||||||
|
var nextTd;
|
||||||
|
|
||||||
// 부모 요소인 span을 찾아서 제거
|
// 버튼이 처음 클릭된 상태인지 확인하기 위해 data-original-td 속성을 체크
|
||||||
var span = button.parentElement;
|
if (!button.hasAttribute('data-original-td')) {
|
||||||
span.remove();
|
// 초기 클릭 시, 원래의 td를 data-original-td 속성에 저장
|
||||||
|
button.setAttribute('data-original-td', currentTd.cellIndex);
|
||||||
|
button.setAttribute('data-current-td', currentTd.cellIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
var originalTdIndex = button.getAttribute('data-original-td'); // 원래 td의 인덱스
|
||||||
|
var currentTdIndex = button.getAttribute('data-current-td'); // 현재 td의 인덱스
|
||||||
|
|
||||||
|
if (currentTdIndex == originalTdIndex) {
|
||||||
|
// 버튼이 원래 위치에 있는 경우 다음 td로 이동
|
||||||
|
nextTd = currentTd.nextElementSibling;
|
||||||
|
button.setAttribute('data-current-td', nextTd.cellIndex);
|
||||||
|
} else {
|
||||||
|
// 버튼이 다음 위치에 있는 경우 원래 위치로 이동
|
||||||
|
nextTd = currentTd.previousElementSibling;
|
||||||
|
button.setAttribute('data-current-td', originalTdIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextTd) {
|
||||||
|
// 버튼을 새 span으로 감싸서 다음 또는 이전 td에 추가
|
||||||
|
var newSpan = document.createElement('span');
|
||||||
|
newSpan.appendChild(button);
|
||||||
|
|
||||||
|
// 버튼의 CSS 클래스 변경 (색상 변경)
|
||||||
|
if (currentTdIndex == originalTdIndex) {
|
||||||
|
button.classList.remove('btn-primary'); // 기존 색상 클래스 제거
|
||||||
|
button.classList.add('btn-success'); // 새 색상 클래스 추가
|
||||||
|
fn_chcKeywordUpdate(spamId, word);
|
||||||
|
} else {
|
||||||
|
button.classList.remove('btn-success'); // 기존 색상 클래스 제거
|
||||||
|
button.classList.add('btn-primary'); // 원래 색상 클래스 추가
|
||||||
|
fn_keywordUpdate(spamId, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 다음 또는 이전 td에 새로운 span 추가
|
||||||
|
nextTd.appendChild(newSpan);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//rsnCode01 onchange
|
||||||
|
function updateCode02Options(selectElement) {
|
||||||
|
var codeGroup = $(selectElement).val(); // 선택된 spam_rsn_code_01 값 가져오기
|
||||||
|
|
||||||
|
// selectElement의 부모 <td>의 다음 <td>를 찾고, 그 안의 .rsnCode02 클래스를 가진 <select> 요소를 선택
|
||||||
|
var code02Select = $(selectElement).closest('td').next('td').find('.rsnCode02');
|
||||||
|
|
||||||
|
if (codeGroup) {
|
||||||
|
// 서버에 AJAX 요청 보내기
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/code-details/' + "SPAM"+codeGroup,
|
||||||
|
method: 'GET',
|
||||||
|
success: function(data) {
|
||||||
|
// 현재의 옵션들을 제거하고 새로운 옵션으로 대체
|
||||||
|
code02Select.empty();
|
||||||
|
code02Select.append('<option value="">선택해주세요.</option>');
|
||||||
|
data.forEach(function(code) {
|
||||||
|
code02Select.append('<option value="' + code.codeId + '">' + code.codeName + '</option>');
|
||||||
|
});
|
||||||
|
|
||||||
|
// spam.spamRsnCode02에 대한 초기 선택 설정 (만약 필요한 경우)
|
||||||
|
var selectedCode02 = code02Select.data('selected-value');
|
||||||
|
if (selectedCode02) {
|
||||||
|
code02Select.val(selectedCode02);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
console.error("Failed to fetch code details.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
code02Select.empty();
|
||||||
|
code02Select.append('<option value="">선택해주세요.</option>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function fn_keywordUpdate(spamId, word){
|
||||||
|
|
||||||
|
// 한글이 포함된 word를 URL 인코딩합니다.
|
||||||
|
var encodedWord = encodeURIComponent(word);
|
||||||
|
$.ajax({
|
||||||
|
url: '/mjon/spam/keyword/' + spamId + '/' + encodedWord,
|
||||||
|
type: 'PUT',
|
||||||
|
success: function(data) {
|
||||||
|
fn_successAlert("성공", data.msg);
|
||||||
|
},
|
||||||
|
error: function(xhr, data) {
|
||||||
|
|
||||||
|
fn_failedAlert("실패", data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fn_chcKeywordUpdate(spamId, word){
|
||||||
|
|
||||||
|
// 한글이 포함된 word를 URL 인코딩합니다.
|
||||||
|
var encodedWord = encodeURIComponent(word);
|
||||||
|
$.ajax({
|
||||||
|
url: '/mjon/spam/chcKeyword/' + spamId + '/' + encodedWord,
|
||||||
|
type: 'PUT',
|
||||||
|
success: function(data) {
|
||||||
|
fn_successAlert("성공", data.msg);
|
||||||
|
},
|
||||||
|
error: function(xhr, data) {
|
||||||
|
|
||||||
|
fn_failedAlert("실패", data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// fn_failedAlert("실패", data.msg);
|
||||||
|
// fn_successAlert("성공", data.data +'가 '+data.msg);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user