Compare commits

...

2 Commits

Author SHA1 Message Date
hehihoho3@gmail.com
ecb14325c9 api 관리자 테스트기능 진행중 2025-11-06 14:23:07 +09:00
hehihoho3@gmail.com
f902aeafb2 관리자 api 테스트 진행중 2025-11-05 12:35:16 +09:00
22 changed files with 2036 additions and 194 deletions

225
CLAUDE.md Normal file
View File

@ -0,0 +1,225 @@
# CLAUDE.md
이 파일은 Claude Code (claude.ai/code)가 이 저장소에서 작업할 때 참고할 가이드입니다.
## 프로젝트 개요
전자정부 표준프레임워크(eGovFramework) v3.9.0 기반의 Maven 빌드 Java 웹 애플리케이션입니다. 문자ON("MunjaON")이라는 SMS/MMS/카카오톡 메시징 서비스의 관리자 플랫폼입니다.
**기술 스택:**
- Java 8
- Spring Framework 4.3.22
- 전자정부 표준프레임워크 3.9.0
- iBATIS (전자정부프레임워크 경유)
- MySQL 5.1.31
- Maven 빌드 시스템
- JSP/JSTL 뷰 + SiteMesh 데코레이터
## 빌드 및 개발
### 빌드 명령어
```bash
# 컴파일 및 패키징 (WAR 파일 생성)
mvn clean install
# 컴파일만 수행
mvn compile
# 내장 톰캣 실행 (설정된 경우)
mvn tomcat7:run
```
### 환경 설정
애플리케이션은 Spring 프로파일 기반 설정을 사용합니다:
- 환경 프로파일: `dev`, `local`, `prod`
- 시스템 속성으로 설정: `-Dspring.profiles.active=dev`
- 설정 파일 위치: `src/main/resources/egovframework/egovProps/globals_{profile}.properties`
데이터베이스 설정은 활성 프로파일에 따라 `globals_{profile}.properties`에서 로드됩니다.
## 프로젝트 아키텍처
### 패키지 구조
```
src/main/java/
├── egovframework.com/ # 전자정부 커스텀 서비스
│ └── idgen/ # ID 생성 서비스
├── itn.com/ # 공통 프레임워크 컴포넌트
│ ├── api/ # REST API 컨트롤러
│ ├── cmm/ # 공통 유틸리티 & 기본 클래스
│ │ ├── aspect/ # AOP 로깅
│ │ ├── filter/ # XSS/보안 필터
│ │ ├── interceptor/ # 요청 인터셉터
│ │ └── service/ # 공통 서비스 (파일, 사용자)
│ ├── sym/ # 시스템 관리 (로깅)
│ ├── uss/ # 사용자 지원 서비스
│ │ ├── ion/ # 통합 (배너, 설정, API)
│ │ └── olh/ # 온라인 도움말
│ └── utl/ # 유틸리티
└── itn.let/ # 비즈니스 로직 모듈
├── kakao/ # 카카오톡 메시지 서비스
├── mail/ # 이메일 서비스
├── mjo/ # 핵심 메시징 (SMS/MMS)
├── cert/ # 본인인증
├── fax/ # 팩스 서비스
└── schdlr/ # 스케줄러 작업
```
### 계층형 아키텍처
표준 MVC 계층형 아키텍처를 따릅니다:
1. **컨트롤러 계층** (`*.web.*Controller`)
- 요청 처리 및 응답 생성
- URL 패턴: `*.do` (Spring DispatcherServlet 매핑)
- `*.web` 패키지에 위치
2. **서비스 계층** (`*.service.*Service`, `*ServiceImpl`)
- 비즈니스 로직 구현
- 트랜잭션 경계 정의
- 인터페이스-구현체 패턴
3. **DAO 계층** (`*.service.impl.*DAO`)
- iBATIS SqlMapClient를 사용한 데이터 접근
- 공통 작업을 위해 `EgovComAbstractDAO` 상속
- SQL 매핑: `src/main/resources/egovframework/sqlmap/`
4. **VO/DTO 계층** (`*VO`, `*DTO`)
- 데이터 전송 객체
- 페이징을 위해 `ComDefaultVO` 상속
### 주요 기본 클래스
- **EgovComAbstractDAO**: iBATIS 작업(`insert`, `update`, `delete`, `select`, `selectList`)을 포함한 기본 DAO
- **ComDefaultVO**: 페이징 지원 기본 VO (`pageIndex`, `pageUnit`, `pageSize`)
- **ComDefaultCodeVO**: 코드 기반 엔티티용 기본 VO
### 설정 파일
**Spring 설정:**
- `src/main/resources/egovframework/spring/com/context-*.xml` - 애플리케이션 컨텍스트
- `src/main/webapp/WEB-INF/config/egovframework/springmvc/*.xml` - MVC 설정
- 주요 컨텍스트:
- `context-datasource.xml` - 데이터베이스 연결 (프로파일 기반)
- `context-sqlMap.xml` - iBATIS SQL 매핑 설정
- `context-security.xml` - Spring Security 설정
- `context-aspect.xml` - AOP 로깅 설정
**SQL 매핑:**
- 위치: `src/main/resources/egovframework/sqlmap/config/mysql/`
- 패턴: `sql-map-config-mysql-{모듈명}.xml`
- SQL 정의: `src/main/resources/egovframework/sqlmap/com/**/*_SQL_Mysql.xml`
**뷰 설정:**
- JSP 위치: `src/main/webapp/WEB-INF/jsp/`
- SiteMesh 데코레이터: `src/main/webapp/WEB-INF/decorators.xml`
- 레이아웃 템플릿: `src/main/webapp/WEB-INF/jsp/layout/`
## 주요 기능
### 보안 및 필터
- **Spring Security**: `context-security.xml`을 통해 설정
- **XSS 필터**: `XssFilter`가 요청을 래핑하여 입력값 검증
- **문자 인코딩**: 기본 UTF-8, 특정 결제 엔드포인트는 EUC-KR
- **CORS**: `CORSFilter`를 통해 활성화
### 외부 연동
- **결제 게이트웨이**: KG 모빌리언스 (`globals.properties`에 설정)
- **본인인증**: NiceID, KMC, ARS 인증
- **메시징 API**: 카카오톡, SMS/MMS 서비스
- **파일 업로드**: Apache Commons FileUpload
- **PDF 처리**: Apache PDFBox
- **엑셀**: Apache POI
### 스케줄 작업
- Quartz 스케줄러 설정: `context-scheduling-*.xml`
- 작업 구현: `itn.let.schdlr` 패키지
- 분산 작업 잠금을 위해 ShedLock 사용 (JDBC 기반)
## 개발 가이드
### 신규 기능 추가 절차
1. **VO 생성**: `ComDefaultVO` 또는 `ComDefaultCodeVO` 상속
2. **SQL 매퍼 생성**: `src/main/resources/egovframework/sqlmap/`에 XML 추가
3. **SQL 설정 등록**: `sql-map-config-mysql-{모듈명}.xml`에 등록
4. **DAO 생성**: `EgovComAbstractDAO` 상속
5. **서비스 생성**: 인터페이스 + 구현체 패턴
6. **컨트롤러 생성**: `@Controller` 또는 `@RestController` 사용
7. **JSP 생성**: `src/main/webapp/WEB-INF/jsp/{모듈명}/`에 배치
### 코드 규칙
- 전자정부 프레임워크 표준과 네이밍 규칙을 따름
- 서비스 인터페이스는 `Service` 접미사
- 서비스 구현체는 `ServiceImpl` 접미사
- DAO 클래스는 `DAO` 접미사
- 컨트롤러 클래스는 `Controller` 접미사
- 의존성 주입은 `@Resource(name="빈이름")` 사용
### iBATIS SQL 매핑
SQL 구문은 네임스페이스.구문ID 패턴으로 참조:
```java
// EgovComAbstractDAO를 상속한 DAO에서
insert("모듈명.insertData", vo);
selectList("모듈명.selectDataList", searchVO);
```
### 주요 작업 패턴
**페이징:**
```java
// VO에서
ComDefaultVO를 상속하여 페이징 필드 사용
// PaginationInfo와 ImagePaginationRenderer 활용
```
**파일 업로드:**
```java
// 파일 작업은 EgovFileMngService 사용
// Globals.file.saveDir 속성 기반으로 파일 저장
```
**로깅:**
```java
// LoggerAspect를 통한 AOP 기반 로깅
// log4jdbc를 통한 SQL 로깅
```
## 테스트
현재 Maven 설정에서 테스트가 비활성화되어 있습니다(`pom.xml`의 `skipTests=true`). 활성화하려면:
```bash
# pom.xml의 surefire 플러그인 설정 수정 후 실행:
mvn test
```
## 배포
애플리케이션은 WAR 파일(`mjon.war`)로 빌드되어 Tomcat에 배포됩니다:
- 배포 경로: `/usr/local/tomcat` (운영)
- 포트: Tomcat server.xml에서 설정
- 세션 타임아웃: 600분 (10시간)
- 에러 페이지: `/common/error.jsp`
### 환경별 배포
1. 적절한 프로파일 설정: `-Dspring.profiles.active={dev|prod}`
2. `globals_{profile}.properties`에 데이터베이스 자격증명 확인
3. properties에 파일 경로(ckeditor, fax 등) 설정
4. WAR 파일을 Tomcat webapps 디렉토리에 배포
## 중요 사항
- **문자 인코딩**: 레거시 결제 시스템을 위한 UTF-8/EUC-KR 혼용
- **데이터베이스**: MySQL 5.x - 구버전 iBATIS 사용 (MyBatis 아님)
- **보안**: Spring Security 통합, `EgovUserDetailsService`를 통한 사용자 정보
- **프로파일 필수**: 애플리케이션 시작 시 `-Dspring.profiles.active` 필요
- **외부 라이브러리**: `WEB-INF/lib`에 일부 JAR 파일 (결제, 인증 모듈)

BIN
button_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -73,6 +73,13 @@ public class StatusResponse {
this.timestamp = timestamp;
}
public StatusResponse(HttpStatus status, String message, Object object, LocalDateTime timestamp) {
this.status = status;
this.message = message;
this.object = object;
this.timestamp = timestamp;
}
public StatusResponse(HttpStatus status, String message, LocalDateTime timestamp) {
this.status = status;
this.message = message;

View File

@ -0,0 +1,50 @@
package itn.let.mjo.api.sms.service;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* api key 관리
* @since 2025.11.05
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2025.11.05 이호영 최초 생성
*
* </pre>
*/
@Getter
@Setter
@ToString
public class ApiAccLogVO{
private String logId;
private String accessType;
private String accessKey;
private String accessToken;
private String reqUserId;
private String reqInfoMeth;
private String reqUrl;
private String resCode;
private String reqRegistPnttm;
private String reqRegisterId;
private String resUpdtPnttm;
private String resUpdusrId;
private String reqCnStr; // JSON 문자열 임시 저장
private String resCnStr; // JSON 문자열 임시 저장
private ReqCnVO reqCn; // JSON 객체 변환 세팅
private ResCnVO resCn;
}

View File

@ -0,0 +1,58 @@
package itn.let.mjo.api.sms.service;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import itn.let.mail.service.StatusResponse;
import itn.let.mjo.apikey.service.ApiKeyVO;
/**
* api key 관리
* @since 2009.04.10
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.04.10 조재영 최초 생성
* 2017.07.21 장동한 로그인인증제한 작업
*
* </pre>
*/
public interface ApiSmsTestMsgService {
StatusResponse findByApiInfoWhereMberIdAjax(String checkId);
Map<String, Object> selectSendHistry(ApiKeyVO searchVO) throws JsonParseException, JsonMappingException, IOException;
StatusResponse findByApiInfoWhereLogIdAjax(String logId) throws IOException;
// //api key list
// public List<ApiKeyVO> selectMberApiKeyList(ApiKeyVO apiKeyVO) throws Exception;
//
// //api key 사용상태 변경
// void deleteApiKey(ApiKeyVO apiKeyVO) throws Exception;
//
// //api key 중복키 확인
// public List<ApiKeyVO> selectCheckApiKeyDup(ApiKeyVO apiKeyVO) throws Exception;
//
// //api key 변경
// void updateApiKey(ApiKeyVO apiKeyVO) throws Exception;
//
// //api key 생성-초기생성
// int insertApiKey(ApiKeyVO apiKeyVO) throws Exception;
//
// //REST API 신청상태
// public List<ApiKeyVO> selectApiKeyApplyStatus(ApiKeyVO apiKeyVO) throws Exception;
//
// public int selectMberApiKeyChk(ApiKeyVO apiKeyVO) throws Exception;
}

View File

@ -0,0 +1,249 @@
package itn.let.mjo.api.sms.service;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* api key 관리
* @since 2025.11.05
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2025.11.05 이호영 최초 생성
*
* </pre>
*/
@Getter
@Setter
@ToString
public class ReqCnVO {
// === 조회/페이징 ===
private String page;
private String pageSize;
private String startDate;
private String endDate;
// === 카카오 템플릿 전송 관련 ===
private String bizId;
private String apiKey;
private String senderKey;
private String templateCode;
private Boolean hasTemplateTitle;
private String subMsgSendYn; // "Y"/"N"
private List<Map<String, Object>> varListMap;
// ===== 공통 인증 관련 =====
private String accessNo;
private String mberId;
private String accessKey;
private String useYn;
private String frstRegistPnttm;
private String frstRegisterId;
private String lastUpdtPnttm;
private String lastUpdusrId;
private String accessToken;
private String tokenObj;
private String expirePnttm;
private String callInfo;
private String remainMsgCnt;
// ===== 문자 발송 요청 관련 =====
private String smsTxt;
private String smsTxtArea;
private List<String> callToList;
private String callFrom;
private String eachPrice;
private String sPrice;
private String mPrice;
private String pPrice;
private String p2Price;
private String p3Price;
private String totPrice;
private String fileCnt;
private String msgType;
private double smsPrice;
private double mmsPrice;
private List<String> imgFilePath;
private String spamStatus;
private String txtReplYn;
private String nameStr;
private String rep1Str;
private String rep2Str;
private String rep3Str;
private String rep4Str;
private List<String> nameList;
private List<String> rep1List;
private List<String> rep2List;
private List<String> rep3List;
private List<String> rep4List;
private String reserveYn;
private String shortMsgCnt;
private String longMsgCnt;
private String msgKind;
private String test_yn;
private String sendKind;
private Object mjonMsgSendVOList; // 리스트형이지만 구조 미정이므로 Object로 처리
// ===== 응답 (result/data 구조) =====
private String resultCode;
private String msgGroupId;
private String successCnt;
private String blockCnt;
private String failCnt;
private String msgTypeList;
private String msgGroupIdList;
private String msg;
private String localDateTime;
private String data;
private String dataResultCode;
private String dataMsgGroupId;
private String dataSuccessCnt;
private String dataBlockCnt;
private String dataFailCnt;
private String dataMsgType;
private String dataTestYn;
// 수신번호/본문(고정 필드 1~100)
private String callTo_1; private String smsTxt_1;
private String callTo_2; private String smsTxt_2;
private String callTo_3; private String smsTxt_3;
private String callTo_4; private String smsTxt_4;
private String callTo_5; private String smsTxt_5;
private String callTo_6; private String smsTxt_6;
private String callTo_7; private String smsTxt_7;
private String callTo_8; private String smsTxt_8;
private String callTo_9; private String smsTxt_9;
private String callTo_10; private String smsTxt_10;
private String callTo_11; private String smsTxt_11;
private String callTo_12; private String smsTxt_12;
private String callTo_13; private String smsTxt_13;
private String callTo_14; private String smsTxt_14;
private String callTo_15; private String smsTxt_15;
private String callTo_16; private String smsTxt_16;
private String callTo_17; private String smsTxt_17;
private String callTo_18; private String smsTxt_18;
private String callTo_19; private String smsTxt_19;
private String callTo_20; private String smsTxt_20;
private String callTo_21; private String smsTxt_21;
private String callTo_22; private String smsTxt_22;
private String callTo_23; private String smsTxt_23;
private String callTo_24; private String smsTxt_24;
private String callTo_25; private String smsTxt_25;
private String callTo_26; private String smsTxt_26;
private String callTo_27; private String smsTxt_27;
private String callTo_28; private String smsTxt_28;
private String callTo_29; private String smsTxt_29;
private String callTo_30; private String smsTxt_30;
private String callTo_31; private String smsTxt_31;
private String callTo_32; private String smsTxt_32;
private String callTo_33; private String smsTxt_33;
private String callTo_34; private String smsTxt_34;
private String callTo_35; private String smsTxt_35;
private String callTo_36; private String smsTxt_36;
private String callTo_37; private String smsTxt_37;
private String callTo_38; private String smsTxt_38;
private String callTo_39; private String smsTxt_39;
private String callTo_40; private String smsTxt_40;
private String callTo_41; private String smsTxt_41;
private String callTo_42; private String smsTxt_42;
private String callTo_43; private String smsTxt_43;
private String callTo_44; private String smsTxt_44;
private String callTo_45; private String smsTxt_45;
private String callTo_46; private String smsTxt_46;
private String callTo_47; private String smsTxt_47;
private String callTo_48; private String smsTxt_48;
private String callTo_49; private String smsTxt_49;
private String callTo_50; private String smsTxt_50;
private String callTo_51; private String smsTxt_51;
private String callTo_52; private String smsTxt_52;
private String callTo_53; private String smsTxt_53;
private String callTo_54; private String smsTxt_54;
private String callTo_55; private String smsTxt_55;
private String callTo_56; private String smsTxt_56;
private String callTo_57; private String smsTxt_57;
private String callTo_58; private String smsTxt_58;
private String callTo_59; private String smsTxt_59;
private String callTo_60; private String smsTxt_60;
private String callTo_61; private String smsTxt_61;
private String callTo_62; private String smsTxt_62;
private String callTo_63; private String smsTxt_63;
private String callTo_64; private String smsTxt_64;
private String callTo_65; private String smsTxt_65;
private String callTo_66; private String smsTxt_66;
private String callTo_67; private String smsTxt_67;
private String callTo_68; private String smsTxt_68;
private String callTo_69; private String smsTxt_69;
private String callTo_70; private String smsTxt_70;
private String callTo_71; private String smsTxt_71;
private String callTo_72; private String smsTxt_72;
private String callTo_73; private String smsTxt_73;
private String callTo_74; private String smsTxt_74;
private String callTo_75; private String smsTxt_75;
private String callTo_76; private String smsTxt_76;
private String callTo_77; private String smsTxt_77;
private String callTo_78; private String smsTxt_78;
private String callTo_79; private String smsTxt_79;
private String callTo_80; private String smsTxt_80;
private String callTo_81; private String smsTxt_81;
private String callTo_82; private String smsTxt_82;
private String callTo_83; private String smsTxt_83;
private String callTo_84; private String smsTxt_84;
private String callTo_85; private String smsTxt_85;
private String callTo_86; private String smsTxt_86;
private String callTo_87; private String smsTxt_87;
private String callTo_88; private String smsTxt_88;
private String callTo_89; private String smsTxt_89;
private String callTo_90; private String smsTxt_90;
private String callTo_91; private String smsTxt_91;
private String callTo_92; private String smsTxt_92;
private String callTo_93; private String smsTxt_93;
private String callTo_94; private String smsTxt_94;
private String callTo_95; private String smsTxt_95;
private String callTo_96; private String smsTxt_96;
private String callTo_97; private String smsTxt_97;
private String callTo_98; private String smsTxt_98;
private String callTo_99; private String smsTxt_99;
private String callTo_100; private String smsTxt_100;
public String getsPrice() {
return sPrice;
}
public void setsPrice(String sPrice) {
this.sPrice = sPrice;
}
public String getmPrice() {
return mPrice;
}
public void setmPrice(String mPrice) {
this.mPrice = mPrice;
}
public String getpPrice() {
return pPrice;
}
public void setpPrice(String pPrice) {
this.pPrice = pPrice;
}
// getter/setter
}

View File

@ -0,0 +1,41 @@
package itn.let.mjo.api.sms.service;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* api key 관리
* @since 2025.11.05
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2025.11.05 이호영 최초 생성
*
* </pre>
*/
@Getter
@Setter
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class ResCnVO {
// ===== 최상위 응답 =====
private String resultCode;
private ResData data;
private List<Integer> localDateTime; // [2025,11,5,11,25,4,488000000] 형태
}

View File

@ -0,0 +1,49 @@
package itn.let.mjo.api.sms.service;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* api key 관리
* @since 2025.11.05
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2025.11.05 이호영 최초 생성
*
* </pre>
*/
@Getter
@Setter
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class ResData {
private String resultCode; // "1020"
private String msg; // 추가: "수신자 전화번호 오류"
private String msgGroupId;
private List<String> msgGroupIdList;
private Integer successCnt;
private Integer blockCnt;
private Integer failCnt;
private String msgType;
private List<String> msgTypeList;
@JsonProperty("test_yn")
private String testYn;
@JsonProperty("next_yn")
private String nextYn;
}

View File

@ -0,0 +1,52 @@
package itn.let.mjo.api.sms.service;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* api key 관리
* @since 2025.11.05
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2025.11.05 이호영 최초 생성
*
* </pre>
*/
@Getter
@Setter
@ToString
public class ResMsgObj {
// ===== 최상위 응답 =====
private String msgGroupId;
private String msgId;
private String totMsgCnt;
private String msgType;
private String msgTypeName;
private String msgResult;
private String msgGroupCnt;
private String smsTxt;
private String callFrom;
private String callTo;
private String curState;
private String userId;
private String remainMsgCnt;
private String reqdate;
private String regdate;
private String reserveCYn;
private String ttlCnt;
private String subject;
private String scnt;
private String fcnt;
private String wcnt;
}

View File

@ -0,0 +1,42 @@
package itn.let.mjo.api.sms.service.impl;
import java.util.List;
import org.springframework.stereotype.Repository;
import itn.com.cmm.service.impl.EgovComAbstractDAO;
import itn.let.mjo.api.sms.service.ApiAccLogVO;
import itn.let.mjo.apikey.service.ApiKeyVO;
/**
* 일반회원관리에 관한 데이터 접근 클래스를 정의한다.
* @author 공통서비스 개발팀 조재영
* @since 2009.04.10
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.04.10 조재영 최초 생성
* 2017.07.21 장동한 로그인인증제한 작업
*
* </pre>
*/
@Repository("apiSmsTestMsgDAO")
public class ApiSmsTestMsgDAO extends EgovComAbstractDAO{
public ApiKeyVO findByApiInfoWhereMberIdAjax(String checkId) {
return (ApiKeyVO) select("apiSmsTestMsgDAO.findByApiInfoWhereMberIdAjax", checkId);
}
public List<ApiAccLogVO> selectSendHistry(ApiKeyVO apiKeyVO) {
return (List<ApiAccLogVO>) list("apiSmsTestMsgDAO.selectSendHistry", apiKeyVO);
}
public ApiAccLogVO findByApiInfoWhereLogIdAjax(String logId) {
return (ApiAccLogVO) select("apiSmsTestMsgDAO.findByApiInfoWhereLogIdAjax", logId);
}
}

View File

@ -0,0 +1,139 @@
package itn.let.mjo.api.sms.service.impl;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import javax.annotation.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import itn.let.mail.service.StatusResponse;
import itn.let.mjo.api.sms.service.ApiAccLogVO;
import itn.let.mjo.api.sms.service.ApiSmsTestMsgService;
import itn.let.mjo.api.sms.service.ReqCnVO;
import itn.let.mjo.api.sms.service.ResCnVO;
import itn.let.mjo.apikey.service.ApiKeyVO;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* 일반회원관리에 관한비지니스클래스를 정의한다.
* @author 공통서비스 개발팀 조재영
* @since 2009.04.10
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.04.10 조재영 최초 생성
* 2014.12.08 이기하 암호화방식 변경(EgovFileScrty.encryptPassword)
* 2017.07.21 장동한 로그인인증제한 작업
*
* </pre>
*/
@Slf4j
@Service("apiSmsTestMsgService")
public class ApiSmsTestMsgServiceImpl extends EgovAbstractServiceImpl implements ApiSmsTestMsgService {
/*api call info */
@Resource(name = "apiSmsTestMsgDAO")
private ApiSmsTestMsgDAO apiSmsTestMsgDAO;
@Override
public StatusResponse findByApiInfoWhereMberIdAjax(String checkId) {
// TODO Auto-generated method stub
ApiKeyVO apiInfoListVO = apiSmsTestMsgDAO.findByApiInfoWhereMberIdAjax(checkId);
String msg = "";
if(apiInfoListVO == null) {
msg = checkId+" 회원에 API 정보가 없습니다.";
}
return new StatusResponse(HttpStatus.OK, msg, apiInfoListVO, LocalDateTime.now());
}
@Override
public Map<String, Object> selectSendHistry(ApiKeyVO apiKeyVO) throws JsonParseException, JsonMappingException, IOException {
Map<String, Object> resultMap = new HashMap<>();
String reqMeth = apiKeyVO.getReqMeth();
if (reqMeth != null && !reqMeth.trim().isEmpty()) {
List<String> reqMethList;
if (reqMeth.contains("|")) {
reqMethList = Arrays.asList(reqMeth.split("\\|"));
} else {
reqMethList = Collections.singletonList(reqMeth); // String을 List로 변환
}
apiKeyVO.setReqMethList(reqMethList);
log.info("reqMethList: {}", reqMethList);
}
List<ApiAccLogVO> apiInfoListVO = apiSmsTestMsgDAO.selectSendHistry(apiKeyVO);
apiInfoListVO = this.voListPreprocessing(apiInfoListVO);
resultMap.put("apiInfoListVO", apiInfoListVO);
resultMap.put("listSize", apiInfoListVO.size());
return resultMap;
}
@Override
public StatusResponse findByApiInfoWhereLogIdAjax(String logId) throws IOException {
ApiAccLogVO apiInfoVO = apiSmsTestMsgDAO.findByApiInfoWhereLogIdAjax(logId);
apiInfoVO = this.voPreprocessing(apiInfoVO);
return new StatusResponse(HttpStatus.OK, apiInfoVO, LocalDateTime.now());
}
public ApiAccLogVO voPreprocessing(ApiAccLogVO apiInfoVO) throws IOException {
List<ApiAccLogVO> list = new ArrayList<>();
list.add(apiInfoVO);
List<ApiAccLogVO> apiAccLogList = this.voListPreprocessing(list);
return apiAccLogList.get(0);
}
public List<ApiAccLogVO> voListPreprocessing(List<ApiAccLogVO> apiAccLogList) throws IOException {
ObjectMapper mapper = new ObjectMapper();
for (ApiAccLogVO vo : apiAccLogList) {
if (vo.getReqCnStr() != null) {
log.info("vo.getReqCnStr() : [{}]", vo.getReqCnStr());
vo.setReqCn(mapper.readValue(vo.getReqCnStr(), ReqCnVO.class));
}
if (vo.getResCnStr() != null) {
vo.setResCn(mapper.readValue(vo.getResCnStr(), ResCnVO.class));
}
}
apiAccLogList.stream().forEach(t->{
System.out.println(" t.toString() :: "+ t.getLogId());
});
return apiAccLogList;
}
}

View File

@ -1,14 +1,23 @@
package itn.let.mjo.api.sms.web;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import itn.let.mail.service.StatusResponse;
import itn.let.mjo.api.sms.service.ApiSmsTestMsgService;
import itn.let.mjo.apikey.service.ApiKeyMngService;
import itn.let.mjo.apikey.service.ApiKeyVO;
import lombok.extern.slf4j.Slf4j;
/**
*
@ -24,8 +33,14 @@ import itn.let.mjo.apikey.service.ApiKeyVO;
* </pre>
*/
@Slf4j
@Controller
public class ApiSmsTestMsgController {
//api key 정보
@Resource(name = "apiSmsTestMsgService")
private ApiSmsTestMsgService apiSmsTestMsgService;
/** xpedite 솔루션 ID*/
@ -57,6 +72,7 @@ public class ApiSmsTestMsgController {
HttpServletRequest request ,
ModelMap model) throws Exception{
model.addAttribute("reqMeth", "sendMsgData_advc|sendMsgData");
return "/uss/ion/api/test/sms/sendMsgForm";
}
@ -99,4 +115,42 @@ public class ApiSmsTestMsgController {
return "/uss/ion/api/test/sms/sendSelectPriceFrom";
}
// 금액 조회
@RequestMapping(value= {"/uss/ion/api/test/sms/selectSendHistryAjax.do"})
public String selectSendHistryAjax(@ModelAttribute("searchVO") ApiKeyVO searchVO,
HttpServletRequest request ,
ModelMap model) throws Exception{
Map<String,Object> resultMap = apiSmsTestMsgService.selectSendHistry(searchVO);
model.addAttribute("listSize", resultMap.get("listSize"));
model.addAttribute("resultList", resultMap.get("apiInfoListVO"));
return "/uss/ion/api/test/sms/popup/sendHistory";
}
@RequestMapping(value = "/uss/ion/api/test/sms/findByApiInfoWhereMberIdAjax.do")
public ResponseEntity<StatusResponse> selectMberIdAjax(@RequestParam String checkId) throws Exception {
return ResponseEntity.ok().body(apiSmsTestMsgService.findByApiInfoWhereMberIdAjax(checkId));
}
@RequestMapping(value = "/uss/ion/api/test/sms/findByApiInfoWhereLogIdAjax.do")
public ResponseEntity<StatusResponse> findByApiInfoWhereLogIdAjax(@RequestParam String logId) throws Exception {
return ResponseEntity.ok().body(apiSmsTestMsgService.findByApiInfoWhereLogIdAjax(logId));
}
}

View File

@ -1,6 +1,10 @@
package itn.let.mjo.apikey.service;
import itn.com.cmm.ComDefaultVO;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* api key 관리
@ -21,7 +25,8 @@ import itn.com.cmm.ComDefaultVO;
@Getter
@Setter
public class ApiKeyVO extends ComDefaultVO{
private static final long serialVersionUID = -7865729705175845268L;
@ -48,109 +53,10 @@ public class ApiKeyVO extends ComDefaultVO{
private String infoNo; //info 정보 순번
private String callType; //IP/URL
private String callInfo; //주소 또는 IP 정보(referer)
public String getAccessNo() {
return accessNo;
}
public void setAccessNo(String accessNo) {
this.accessNo = accessNo;
}
public String getMberId() {
return mberId;
}
public void setMberId(String mberId) {
this.mberId = mberId;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getUseYn() {
return useYn;
}
public void setUseYn(String useYn) {
this.useYn = useYn;
}
public String getFrstRegistPnttm() {
return frstRegistPnttm;
}
public void setFrstRegistPnttm(String frstRegistPnttm) {
this.frstRegistPnttm = frstRegistPnttm;
}
public String getFrstRegisterId() {
return frstRegisterId;
}
public void setFrstRegisterId(String frstRegisterId) {
this.frstRegisterId = frstRegisterId;
}
public String getLastUpdtPnttm() {
return lastUpdtPnttm;
}
public void setLastUpdtPnttm(String lastUpdtPnttm) {
this.lastUpdtPnttm = lastUpdtPnttm;
}
public String getLastUpdusrId() {
return lastUpdusrId;
}
public void setLastUpdusrId(String lastUpdusrId) {
this.lastUpdusrId = lastUpdusrId;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getTokenObj() {
return tokenObj;
}
public void setTokenObj(String tokenObj) {
this.tokenObj = tokenObj;
}
public String getExpirePnttm() {
return expirePnttm;
}
public void setExpirePnttm(String expirePnttm) {
this.expirePnttm = expirePnttm;
}
public String getMberNm() {
return mberNm;
}
public void setMberNm(String mberNm) {
this.mberNm = mberNm;
}
public String getMberSttus() {
return mberSttus;
}
public void setMberSttus(String mberSttus) {
this.mberSttus = mberSttus;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public String getInfoNo() {
return infoNo;
}
public void setInfoNo(String infoNo) {
this.infoNo = infoNo;
}
public String getCallType() {
return callType;
}
public void setCallType(String callType) {
this.callType = callType;
}
public String getCallInfo() {
return callInfo;
}
public void setCallInfo(String callInfo) {
this.callInfo = callInfo;
}
private String reqMeth; //검색 조건 메소드
private List<String> reqMethList; //검색 조건 메소드
}

View File

@ -168,9 +168,9 @@ public class MjonMsgController {
public String sendMsgList(@ModelAttribute("searchVO") MjonMsgVO searchVO,
HttpServletRequest request ,
ModelMap model) throws Exception{
//value 가져오기
//value 가져오기
// String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE) ;
/** pageing */
PaginationInfo paginationInfo = new PaginationInfo();
paginationInfo.setCurrentPageNo(searchVO.getPageIndex());

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<sqlMap resource="egovframework/sqlmap/let/mjo/apiSms/ApiSmsTestMsg_SQL_Mysql.xml"/> <!-- api call info -->
</sqlMapConfig>

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="ApiSmsTestMsg">
<typeAlias alias="apiKeyVO" type = "itn.let.mjo.apikey.service.ApiKeyVO"/>
<typeAlias alias="apiAccLogVO" type = "itn.let.mjo.api.sms.service.ApiAccLogVO"/>
<select id="apiSmsTestMsgDAO.findByApiInfoWhereMberIdAjax" parameterClass="String" resultClass="apiKeyVO" remapResults="true">
select
b.ACCESS_NO as accessNo,
b.ACCESS_KEY as accessKey,
b.USE_YN as accessUseYn,
a.MBER_NM as mberNm,
a.MBER_STTUS as mberSttus,
b.FRST_REGIST_PNTTM as frstRegistPnttm,
b.LAST_UPDT_PNTTM as lastUpdtPnttm,
b.MBER_ID as mberId,
b.USE_YN as useYn,
IFNULL(
GROUP_CONCAT(
CASE WHEN c.CALL_TYPE IN ('IP', 'URL') THEN c.CALL_INFO END
ORDER BY c.INFO_NO
SEPARATOR ' | '
),
''
) AS callInfo
from lettngnrlmber_access_key b
join lettngnrlmber a
on a.MBER_ID = b.MBER_ID
left join lettngnrlmber_access_call_info c
on c.ACCESS_NO = b.ACCESS_NO
where b.MBER_ID = #mberId#
group by
b.ACCESS_NO,
b.ACCESS_KEY,
b.USE_YN,
a.MBER_NM,
a.MBER_STTUS,
b.FRST_REGIST_PNTTM,
b.LAST_UPDT_PNTTM,
b.MBER_ID;
</select>
<select id="apiSmsTestMsgDAO.selectSendHistry" parameterClass="apiKeyVO" resultClass="apiAccLogVO">
SELECT
LOG_ID AS logId,
ACCESS_TYPE AS accessType,
ACCESS_KEY AS accessKey,
ACCESS_TOKEN AS accessToken,
REQ_USER_ID AS reqUserId,
REQ_CN AS reqCnStr,
REQ_INFO_METH AS reqInfoMeth,
REQ_URL AS reqUrl,
RES_CN AS resCnStr,
RES_CODE AS resCode,
DATE_FORMAT(REQ_REGIST_PNTTM, '%Y-%m-%d %H:%i:%s') AS reqRegistPnttm,
REQ_REGISTER_ID AS reqRegisterId,
DATE_FORMAT(RES_UPDT_PNTTM, '%Y-%m-%d %H:%i:%s') AS resUpdtPnttm,
RES_UPDUSR_ID AS resUpdusrId
FROM lettngnrlmber_access_log
WHERE REQ_USER_ID = #mberId#
and ACCESS_KEY = #accessKey#
<dynamic>
<isNotEmpty property="reqMethList">
AND (
<iterate property="reqMethList" conjunction="OR">
REQ_INFO_METH LIKE '%$reqMethList[]$%'
</iterate>
)
</isNotEmpty>
</dynamic>
ORDER BY REQ_REGIST_PNTTM DESC
</select>
<select id="apiSmsTestMsgDAO.findByApiInfoWhereLogIdAjax" parameterClass="String" resultClass="apiAccLogVO" remapResults="true">
SELECT
LOG_ID AS logId,
ACCESS_TYPE AS accessType,
ACCESS_KEY AS accessKey,
ACCESS_TOKEN AS accessToken,
REQ_USER_ID AS reqUserId,
REQ_CN AS reqCnStr,
REQ_INFO_METH AS reqInfoMeth,
REQ_URL AS reqUrl,
RES_CN AS resCnStr,
RES_CODE AS resCode,
DATE_FORMAT(REQ_REGIST_PNTTM, '%Y-%m-%d %H:%i:%s') AS reqRegistPnttm,
REQ_REGISTER_ID AS reqRegisterId,
DATE_FORMAT(RES_UPDT_PNTTM, '%Y-%m-%d %H:%i:%s') AS resUpdtPnttm,
RES_UPDUSR_ID AS resUpdusrId
FROM lettngnrlmber_access_log
where LOG_ID = #logId#
</select>
</sqlMap>

View File

@ -0,0 +1,23 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<div class="setDiv">
<div class="mask"></div>
<div class="window">
<div class="id_check1">
<input type="button" href="#" class="close">
<span>회원 아이디 검색</span>
</div>
<div class="id_check2">
<span>검색할 아이디</span><input type="text" id="checkIdModal">
</div>
<div class="id_check3">
<span>아이디를 검색하세요</span><button onclick="fn_searchUser(); return false;">검색</button>
</div>
</div>
</div>

View File

@ -57,6 +57,7 @@ $(document).ready(function() {
});
</script>
<div class="tabWrap">
<ul class="tabList">
<li><a href="/uss/ion/api/test/sms/sendMsgForm.do">문자발송</a></li>
@ -72,23 +73,23 @@ $(document).ready(function() {
<div class="subte" id="subteBox" style="display: none;">
<dl>
<dt>[mberId]</dt>
<dd>dudgusw</dd>
<dt>[apiKey]</dt>
<dd>3429312e6a2c732188d4cc7d15d8a1baa01d8d91</dd>
<dt>[공통 API URL]</dt>
<dd>http://119.193.215.98:8087/ -> 개발서버</dd>
<dt>[세부 엔드포인트]</dt>
<dd class="url-list">- 문자발송 : /api/send/sendMsg -> jsp_example_send_msg_r1.jsp</dd>
<dd class="url-list">- 대량문자발송 : /api/send/sendMsgs -> jsp_example_send_msgs_r1.jsp</dd>
<dd class="url-list">- 전체발송내역 : /api/send/sendHstry -> jsp_example_hstry_r1.jsp</dd>
<dd class="url-list">- 상세발송내역 : /api/send/sendHstryDetail -> jsp_example_hstry_detail_r1.jsp</dd>
<dd class="url-list">- 발송가능건수 : /api/send/sendSelectPrice -> jsp_example_select_price_r1.jsp</dd>
</dl>
<dl>
<dt>[mberId]</dt>
<dd>dudgusw</dd>
<dt>[apiKey]</dt>
<dd>3429312e6a2c732188d4cc7d15d8a1baa01d8d91</dd>
<dt>[공통 API URL]</dt>
<dd>http://119.193.215.98:8087/ -> 개발서버</dd>
<dt>[세부 엔드포인트]</dt>
<dd class="url-list">- 문자발송 : /api/send/sendMsg -> jsp_example_send_msg_r1.jsp</dd>
<dd class="url-list">- 대량문자발송 : /api/send/sendMsgs -> jsp_example_send_msgs_r1.jsp</dd>
<dd class="url-list">- 전체발송내역 : /api/send/sendHstry -> jsp_example_hstry_r1.jsp</dd>
<dd class="url-list">- 상세발송내역 : /api/send/sendHstryDetail -> jsp_example_hstry_detail_r1.jsp</dd>
<dd class="url-list">- 발송가능건수 : /api/send/sendSelectPrice -> jsp_example_select_price_r1.jsp</dd>
</dl>
</div>
<script>
@ -101,3 +102,45 @@ $(function() {
});
});
</script>
<div class="listTop maxWth" style="margin-top: 80px;">
<span class="tType4 c_456ded fwBold">
<p>사용자정보.</p>
</span>
</div>
<table class="tbType2" style="margin-bottom: 80px;">
<colgroup>
<col style="width: 20%">
<col style="width: 80%">
</colgroup>
<tbody>
<tr>
<th>사용자ID (mberId) <button type="button" id="showMask" class="fillBlue" style="display: inline-block; vertical-align: middle;">조회</button></th>
<td>
<input type="text" id="mberId" value="" disabled="disabled">
</td>
</tr>
<tr>
<th>API Key (apiKey)</th>
<td><input type="text" id="apiKey" value="" disabled="disabled"></td>
</tr>
<tr>
<th>API 상태 (useYn)</th>
<td><input type="text" id="useYn" value="" disabled="disabled"></td>
</tr>
<tr>
<th>등록 IP (callInfo)</th>
<td><input type="text" id="callInfo" value="" disabled="disabled"></td>
</tr>
</tbody>
</table>
<form id="apiInfoFomr">
<input type="hidden" name="mberId" value=""/>
<input type="hidden" name="accessKey" value=""/>
<input type="hidden" name="reqMeth" value=""/>
</form>

View File

@ -0,0 +1,582 @@
<%--
Class Name : EgovGnrlUserSelectMsgDataListPop.jsp
Description : 사용자 문자전송리스트(전체)
Modification Information
수정일 수정자 수정내용
------- -------- ---------------------------
2022.07.01 우영두 최초 생성
author : 우영두
since : 2022.07.01
Copyright (C) 2009 by MOPAS All right reserved.
--%>
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="ec" uri="/WEB-INF/tld/ecnet_tld.tld"%>
<% pageContext.setAttribute("newLineChar", "\r\n"); %>
<% pageContext.setAttribute("newLineChar2", "\n"); %>
<%
response.setHeader("Cache-Control","no-store");
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
if (request.getProtocol().equals("HTTP/1.1")) response.setHeader("Cache-Control", "no-cache");
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<title>사용자 문자전송 관리</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="/pb/css/reset.css">
<link rel="stylesheet" href="/pb/css/common.css">
<link rel="stylesheet" href="/pb/css/content.css">
<link rel="stylesheet" href="/pb/css/popup.css">
<style>
.pageCont .tbType1 tbody tr td.sms_detail {overflow:inherit;text-overflow:inherit;position:relative;}
.pageCont .tbType1 tbody tr td.sms_detail p {overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pageCont .tbType1 tbody tr td.sms_detail .sms_detail_hover {overflow:hidden;text-overflow:ellipsis;display:none;word-wrap:break-word;-webkit-line-clamp:20;-webkit-box-orient:vertical;position:absolute;left:-5px;top:45px;width:calc(100% + 150px);padding:15px;line-height:20px;white-space:normal;border:1px solid #e5e5e5;background:#fff;border-radius:5px;box-sizing:border-box;box-shadow:0px 3px 10px 0px rgb(0 0 0 / 0.2);z-index:1;font-size:14px;text-align:left;}
.pageCont .tbType1 tbody tr td.sms_detail .sms_detail_hover:after {content:'';position:absolute;left:0;bottom:0;width:100%;height:10px;background:#fff;border-radius:0 0 5px 5px;}
.pageCont .tbType1 tbody tr td.sms_detail:hover .sms_detail_hover {display:-webkit-box;}
</style>
<script type="text/javascript" src="/pb/js/jquery-3.5.0.js"></script>
<script type="text/javascript" src="/pb/js/common.js"></script>
<script type="text/javascript" src="<c:url value='/js/EgovMultiFile.js'/>"></script>
<script type="text/javascript" src="<c:url value='/js/EgovCalPopup.js'/>"></script>
<script type="text/javascript" src="<c:url value='/js/ncms_common.js' />"></script>
<script type="text/javaScript" language="javascript">
function fn_openerSendInfo(p_logId){
window.opener.fn_findBySendInfo(p_logId);
}
/*
function fn_search(){
var searchKeyword = $('input[name=searchKeyword]').val();
$('input[name=searchKeyword]').val(searchKeyword.replace(/(\s*)/g, ""));
linkPage(1);
}
function linkPage(pageNo){
var listForm = document.listForm ;
listForm.pageIndex.value = pageNo ;
if( $('#ntceBgndeYYYMMDD').val() != '' && $('#ntceEnddeYYYMMDD').val() != '' ){
var iChkBeginDe = Number($('#ntceBgndeYYYMMDD').val().replaceAll("-", ""));
var iChkEndDe = Number($('#ntceEnddeYYYMMDD').val().replaceAll("-", ""));
if(iChkBeginDe > iChkEndDe || iChkEndDe < iChkBeginDe ){
alert("검색시작일자는 종료일자 보다 클수 없습니다.");
return;
}
}
$('#ntceBgnde').val($('#ntceBgndeYYYMMDD').val()) ;
$('#ntceEndde').val($('#ntceEnddeYYYMMDD').val()) ;
listForm.action = "<c:url value='/uss/umt/user/EgovGnrlselectedUserMsgDataListAjax.do'/>";
listForm.submit();
}
function fnCheckAll() {
if( $("#checkAll").is(':checked') ){
$("input[name=del]").prop("checked", true);
}else{
$("input[name=del]").prop("checked", false);
}
}
function fn_delete(){
if($("input[name=del]:checked").length == 0){
alert("선택된 항목이 없습니다.");
return;
}
if (confirm("해당 문자를 삭제하시겠습니까?")){
frm = document.listForm;
frm.action = "<c:url value='/uss/ion/msg/SendMsgDelete.do' />";
frm.submit();
}
}
function fn_modify(msgId){
var frm = document.modiForm ;
frm.msgId.value = msgId ;
frm.submit();
}
function fn_detail_list(msgGroupId){
var frm = document.modiForm ;
frm.msgGroupId.value = msgGroupId ;
frm.submit();
}
function init_date(){
$('#ntceBgndeYYYMMDD').val('');
$('#ntceEnddeYYYMMDD').val('');
$('#ntceBgnde').val('');
$('#ntceEndde').val('');
$('#searchKeyword').val('');
$('#sendKind').val('').prop("selected",true);
$('#searchCondition').val('').prop("selected",true);
}
//엑셀 다운로드
function sendMsgExcelDownload(){
var frm = document.listForm;
$('#ntceBgnde').val($('#ntceBgndeYYYMMDD').val()) ;
$('#ntceEndde').val($('#ntceEnddeYYYMMDD').val()) ;
var ntceBgnde = $('#ntceBgndeYYYMMDD').val();
var ntceEndde = $('#ntceEnddeYYYMMDD').val();
frm.ntceBgnde.value = ntceBgnde;
frm.ntceEndde.value = ntceEndde;
frm.method = "post";
frm.action = "<c:url value='/uss/ion/msg/selectMberSendMsgExcelDownload.do'/>";
frm.submit();
}
function fn_updateMberSttus(msgGroupId){
var form = document.listForm;
if(confirm("이용자 정지를 진행하시겠습니까?")){
var data = new FormData(form);
url = "/uss/umt/user/updateMberSttusBlockAjax.do";
data.append("msgGroupId", msgGroupId);
data.append("smiMemo", "시스템 스팸 필터링에 의한 이용정지");
$.ajax({
type: "POST",
url: url,
data: data,
dataType:'json',
async: false,
processData: false,
contentType: false,
cache: false,
success: function (returnData, status) {
if(status == 'success'){ // status 확인 필요한가. 석세스 안뜨면 에러 가지 않나
if("fail"==returnData.result){
alert(returnData.message);
return false;
}else if("loginFail"==returnData.result){
alert(returnData.message);
return false;
}else{ //문자발송 성공시 처리
alert(returnData.message);
opener.parent.location.reload();
location.reload();
}
} else if(status== 'fail'){
alert("이용자 상태 변경에 실패하였습니다.");
}
},
beforeSend: function () {
//로딩창 show
$('.loading_layer').addClass('active');
},
complete: function () {
//로딩창 hide
$('.loading_layer').removeClass('active');
},
error: function (e) { alert("이용자 상태 변경에 실패하였습니다."); console.log("ERROR : ", e); }
});
}
}
function msgDetailView(obj, msgGroupId, index){
var form = document.modiForm;
form.msgGroupId.value = msgGroupId;
var sendData = $(form).serializeArray();
$(".msgSentDetailPopLoad"+index).load("/uss/umt/user/selectMberMsgDetailAjax.do", sendData ,function(response, status, xhr){
var target=$(obj);
$('.layer_msg_detail').hide();
target.next('.layer_msg_wrap').find('.layer_msg_detail').show();
});
}
function msgDetailClose(obj){
var target=$(obj);
target.closest('.layer_msg_detail').hide();
}
function fn_updateSendRealTime(userId, msgGroupId){
var msg = "";
var url = "/uss/ion/msg/updateMsgDirectSendAjax.do";
var json = {"msgGroupId" : msgGroupId, "userId" : userId};
if(confirm("해당 문자를 즉시 발송 하시겠습니까?\n 해당문자는 예약여부 상관없이 즉시 발송됩니다.")){
$.ajax({
type: "POST",
url: url,
data: json,
dataType:'json',
async: false,
success: function (data, status) {
var result = data.isStatus;
var msg = data.msg;
if (result == 'loginFail') {
alert(msg);
location.reload();
}else if(result == 'dateFail'){
alert(msg);
location.reload();
}else if(result == 'fail'){
alert(msg);
return false;
}else{
alert(msg);
location.reload();
}
},
beforeSend: function () {
//로딩창 show
$('.loading_layer').addClass('active');
},
complete: function () {
//로딩창 hide
$('.loading_layer').removeClass('active');
},
error: function (e) {
alert("에러가 발생했습니다."); console.log("ERROR : ", e);
}
});
}
}
function fnGoMsgGroupList(msgGroupId){
var form = document.msgGrpListForm;
form.msgGroupId.value = msgGroupId;
form.action="/uss/umt/user/EgovGnrlselectedUserMsgDataDetailListAjax.do";
form.submit();
} */
</script>
<style>
.pageCont {width:100%;padding:50px 30px;box-sizing:border-box;}
.tableWrapTotal {margin:0 0 20px;}
.tableWrapTotal .tbType1 thead tr:first-child {border-width:1px;}
.tableWrapTotal .tbType1 thead tr th {border-left:1px solid #e6e6e6;}
.tableWrapTotal .tbType1 thead tr th:first-child {border-left:0 none;}
.tableWrapTotal .tbType1 thead tr.content th {font-size:14px;}
.tableWrapTotal .tbType1 tbody tr td {border-left:1px solid #e6e6e6;}
.tableWrapTotal .tbType1 tbody tr td:first-child {border-left:0 none;}
.listSerch .select {height:42px;vertical-align:top;}
.pageCont .tbType1 tbody tr td.msg_detail {overflow:inherit;}
.pageCont .tbType1 tbody tr td.msg_detail a {overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;}
/* .layer_msg_wrap {position:relative;} */
.layer_msg_wrap .layer_msg_detail {overflow:hidden;display:none;position:absolute;left:50%;top:600px;width:400px;max-height:600px;background:#eee;transform:translateX(-50%);z-index:1;}
.layer_msg_wrap .layer_msg_detail button {position:absolute;right:0;top:0;width:35px;height:35px;}
.layer_msg_wrap .layer_msg_detail button:before {content:'';position:absolute;left:50%;top:50%;width:1px;height:14px;margin:-7px 0 0;background:#fff;transform:rotate(-45deg);}
.layer_msg_wrap .layer_msg_detail button:after {content:'';position:absolute;left:50%;top:50%;width:1px;height:14px;margin:-7px 0 0;background:#fff;transform:rotate(45deg);}
.layer_msg_wrap .layer_msg_detail .title {height:35px;padding:0 15px;font-size:16px;line-height:35px;text-align:left;color:#fff;background:#456ded;border-radius:5px 5px 0 0;}
.layer_msg_wrap .layer_msg_detail .content {overflow-y:auto;max-height:535px;margin:15px;padding:10px 15px;line-height:20px;white-space:normal;background:#fff;}
.layer_msg_wrap .layer_msg_detail .content .rev_cont {text-align:left;}
@media screen and (max-width:916px){
.pageCont .tableWrap table thead tr th {padding:15px 0;}
}
</style>
</head>
<body>
<div class="loading_layer">
<div class="loading_container">
<div class="bar"></div>
<div class="text">Loading</div>
</div>
</div>
<form name="listForm" action="" method="post">
<div class="contWrap" style="width:100%;position:relative;left:inherit;top:inherit;min-height:auto;padding:40px;">
<div class="pageTitle">
<!-- <div class="pageIcon"><img src="/pb/img/pageTitIcon4.png" alt=""></div> -->
<h2 class="titType1 c_222222 fwBold">'<c:out value="${searchVO.mberId}"/>'의 API전송 리스트</h2>
<!-- <p class="tType6 c_999999">문자전송리스트 현황을 파악할 수 있습니다.</p> -->
</div>
<div class="pageCont">
<div class="listTop">
<p class="tType5">총 <span class="tType4 c_456ded fwBold"><fmt:formatNumber value="${listSize}" pattern="#,###" /></span>건</p>
<%-- <p class="tType5">총 <span class="tType4 c_456ded fwBold"><fmt:formatNumber value="${paginationInfo.totalRecordCount}" pattern="#,###" /></span>건</p>
<div class="rightWrap">
<input type="button" class="excelBtn" onclick="javascript:sendMsgExcelDownload();">
<!-- <input type="button" class="printBtn"> -->
<select name="pageUnit" id="pageUnit" class="select" title="검색조건선택" onchange="linkPage(1);">
<option value='10' <c:if test="${searchVO.pageUnit == '10' or searchVO.pageUnit == ''}">selected</c:if>>10줄</option>
<option value='20' <c:if test="${searchVO.pageUnit == '20'}">selected</c:if>>20줄</option>
<option value='30' <c:if test="${searchVO.pageUnit == '30'}">selected</c:if>>30줄</option>
</select>
</div> --%>
</div>
<div class="tableWrap">
<table class="tbType1">
<colgroup>
<col style="width: 4%">
<col style="width: 9%">
<col style="width: 4%">
<col style="width: 11%">
<col style="width: 15%">
<col style="width: 7%">
<col style="width: 15%">
<col style="width: 7%">
</colgroup>
<thead>
<tr>
<th>번호</th>
<th>발신번호</th>
<th>발송건수</th>
<th>등록일시</th>
<th>내용</th>
<th>결과</th>
<th>실패사유</th>
<th>불러오기</th>
</tr>
</thead>
<tbody>
<c:forEach var="result" items="${resultList}" varStatus="status">
<tr>
<td>${status.count}</td>
<td>${result.reqCn.callFrom}</td>
<td>${empty result.resCn.data.msgGroupIdList ? 0 : fn:length(result.resCn.data.msgGroupIdList)}</td>
<td>${result.reqRegistPnttm}</td>
<td title="${result.reqCn.smsTxt}">${result.reqCn.smsTxt}</td>
<td>${result.resCn.data.resultCode == '0' ? '성공' : '실패'}</td>
<td>${result.resCn.data.msg}</td>
<td><input type="button" class="btnType1" value="선택" onclick="fn_openerSendInfo('${result.logId}'); return false;"></td>
</tr>
</c:forEach>
<%-- <c:forEach var="result" items="${resultList}" varStatus="status">
<tr>
<td>
<c:if test="${searchVO.searchSortOrd eq 'desc' }">
<c:out value="${ ( paginationInfo.totalRecordCount - ((paginationInfo.currentPageNo -1)*paginationInfo.recordCountPerPage) ) - status.index }"/>
</c:if>
<c:if test="${searchVO.searchSortOrd eq 'asc' }">
<c:out value="${(paginationInfo.currentPageNo - 1) * paginationInfo.recordCountPerPage + status.count}"/>
</c:if>
</td>
<td>
<c:out value="${result.callFrom}"/>
</td>
<td title="<c:out value="${result.regDate}"/>">
<fmt:parseDate value="${result.regDate}" var="regDateValue" pattern="yyyy-MM-dd HH:mm"/>
<fmt:formatDate value="${regDateValue}" pattern="MM-dd HH:mm"/>
</td>
<td>
<c:choose>
<c:when test="${result.reserveCYn eq 'Y'}">
<c:out value="${result.cancelDate}"/>
</c:when>
<c:when test="${result.reserveYn eq 'Y' && result.reserveCYn eq 'N'}">
<c:out value="${result.reqDate}"/>
</c:when>
<c:when test="${result.delayYn eq 'Y' && result.delayCompleteYn eq 'Y' && not empty result.cancelDate}">
<c:out value="${result.cancelDate}"/>
</c:when>
<c:otherwise>
<c:out value="${result.reqDate}"/>
</c:otherwise>
</c:choose>
</td>
<td>
<fmt:formatNumber value="${result.msgGroupSCnt}" pattern="#,###" />/<fmt:formatNumber value="${result.msgGroupFWCnt}" pattern="#,###" />(<fmt:formatNumber value="${(result.msgGroupSCnt / (result.msgGroupSCnt + result.msgGroupFWCnt)) * 100}" pattern="#,###" />%)
</td>
<td>
<c:choose>
<c:when test="${result.reserveCYn eq 'Y'}">
예약취소
</c:when>
<c:when test="${result.reserveYn eq 'Y' && result.reserveCYn eq 'N'}">
예약
</c:when>
<c:otherwise>
즉시
</c:otherwise>
</c:choose>
</td>
<td class="sms_detail left" onclick="fnGoMsgGroupList('<c:out value="${result.msgGroupId}"/>');" style="cursor:pointer;">
<c:choose>
<c:when test="${empty result.smsTxt}">
<c:choose>
<c:when test="${result.msgType eq '4'}">
내용없음
</c:when>
<c:otherwise>
그림문자
</c:otherwise>
</c:choose>
<div class="sms_detail_hover">
<c:if test="${not empty fn:split(result.atchFiles, '^')[0]}">
<img class="MyMsgImg1" src="/cmm/fms/getImage2.do?atchFileId=${fn:split(result.atchFiles, '^')[0]}&fileSn=0" style="width: 100px;">
</c:if>
<c:if test="${not empty fn:split(result.atchFiles, '^')[1]}">
<img class="MyMsgImg1" src="/cmm/fms/getImage2.do?atchFileId=${fn:split(result.atchFiles, '^')[1]}&fileSn=0" style="width: 100px;">
</c:if>
<c:if test="${not empty fn:split(result.atchFiles, '^')[2]}">
<img class="MyMsgImg1" src="/cmm/fms/getImage2.do?atchFileId=${fn:split(result.atchFiles, '^')[2]}&fileSn=0" style="width: 100px;">
</c:if>
</div>
</c:when>
<c:otherwise>
<p><c:out value="${result.smsTxt}"/></p>
<div class="sms_detail_hover">
<c:if test="${not empty fn:split(result.atchFiles, '^')[0]}">
<img class="MyMsgImg1" src="/cmm/fms/getImage2.do?atchFileId=${fn:split(result.atchFiles, '^')[0]}&fileSn=0" style="width: 100px;">
</c:if>
<c:if test="${not empty fn:split(result.atchFiles, '^')[1]}">
<img class="MyMsgImg1" src="/cmm/fms/getImage2.do?atchFileId=${fn:split(result.atchFiles, '^')[1]}&fileSn=0" style="width: 100px;">
</c:if>
<c:if test="${not empty fn:split(result.atchFiles, '^')[2]}">
<img class="MyMsgImg1" src="/cmm/fms/getImage2.do?atchFileId=${fn:split(result.atchFiles, '^')[2]}&fileSn=0" style="width: 100px;">
</c:if>
<c:if test="${not empty fn:split(result.atchFiles, '^')[0]}">
<br />
</c:if>
<c:out value="${fn:replace(fn:replace(result.smsTxt, newLineChar, '<br/>'), newLineChar2, '<br/>')}" escapeXml="false"/>
</div>
</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${result.msgType eq '4'}">
단문
</c:when>
<c:when test="${result.msgType eq '6' && result.fileCnt > 0}">
그림(<c:out value="${result.fileCnt}"/>장)
</c:when>
<c:otherwise>
장문
</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${result.sendKind eq 'A'}">
API
</c:when>
<c:when test="${result.sendKind eq 'H'}">
WEB
</c:when>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${result.delayYn eq 'Y'}">
<c:choose>
<c:when test="${result.delayCompleteYn eq 'Y' && not empty result.cancelDate}">
<span style="color: blue;">
[발송취소]<br/>
<c:out value="${result.cancelDate}"/>
</span>
</c:when>
<c:when test="${result.delayCompleteYn eq 'N'}">
[미처리]
</c:when>
<c:otherwise>
<span style="color: blue;">[승인]</span>
</c:otherwise>
</c:choose>
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${mberSttus eq 'B'}">
<c:if test="${not empty result.smiId}">
<button type="button" class="btnType btnType21">
정지
</button>
</c:if>
<c:if test="${empty result.smiId}">
-
</c:if>
</c:when>
<c:otherwise>
<button type="button" class="btnType btnType20" onclick="fn_updateMberSttus('<c:out value="${result.msgGroupId}"/>'); return false;">
정지
</button>
-
</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${result.reserveYn eq 'Y' && result.reserveCYn eq 'N'}">
<button type="button" class="btnType btnType20" onclick="fn_updateSendRealTime('<c:out value="${searchVO.userId}"/>','<c:out value="${result.msgGroupId}"/>'); return false;">
즉시발송
</button>
</c:when>
</c:choose>
</td>
</tr>
</c:forEach>
<c:if test="${empty resultList}">
<tr><td colspan="12"><spring:message code="common.nodata.msg" /></td></tr>
</c:if> --%>
</tbody>
</table>
</div>
<div class="btnWrap">
</div>
<!-- 페이지 네비게이션 시작 -->
<%-- <c:if test="${!empty resultList}">
<div class="page">
<ul class="inline">
<ui:pagination paginationInfo = "${paginationInfo}" type="image" jsFunction="linkPage" />
</ul>
</div>
</c:if> --%>
<!-- //페이지 네비게이션 끝 -->
</div>
</div>
</form>
<%-- <form name="msgGrpListForm" id="msgGrpListForm" method="post">
<input name="userId" type="hidden" value="<c:out value='${searchVO.userId}'/>"/>
<input name="msgGroupId" type="hidden" value=""/>
<input type="hidden" name="reserveType" id="reserveType1" value="${searchVO.reserveType}">
</form>
--%>
</body>
</html>

View File

@ -3,7 +3,65 @@
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<title>환불 등록</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="<c:url value='/js/web_common.js' />"></script>
<script type="text/javascript" src="<c:url value='/js/EgovMultiFile.js'/>"></script>
<script type="text/javascript" src="<c:url value='/js/uss/ion/api/test/sms/cmn.js'/>"></script>
<script>
function fn_findBySendInfo(p_logId){
console.log(p_logId);
$.ajax({
type:"POST",
url:"/uss/ion/api/test/sms/findByApiInfoWhereLogIdAjax.do",
data:{
"logId": p_logId
},
dataType:'json',
timeout:(1000*30),
success:function(data){
console.log('data ', data);
// if(data?.message)
// {
// alert(data.message);
// return false;
// }
// else
// {
//
// var object = data.object;
// console.log('object : ', object);
// console.log('object.accessKey : ', object.accessKey);
//
// $('#mberId').val(object.mberId);
// $('#apiKey').val(object.accessKey);
// $('#useYn').val(object.useYn);
// $('#callInfo').val(object.callInfo);
//
//
// $('.mask, .window').hide();
// }
},
error:function(request , status, error){
console.log(' error ?');
console.log('request : ', request);
console.log('status : ', status);
}
});
}
</script>
<!-- <meta http-equiv="content-type" content="text/html; charset=utf-8"> -->
@ -64,97 +122,118 @@
height: 55px;
}
/* 파란색 버튼 스타일 */
.fillBlue {
margin-top: 5px;
height: 25px;
padding: 3px 10px;
font-size: 13px;
text-align: center;
color: #ffffff !important;
background: #456ded;
border: none;
border-radius: 3px;
cursor: pointer;
}
.fillBlue:hover {
background: #3558d6;
}
</style>
<!-- <script type="text/javascript" src="/js/jquery-3.5.0.js"></script> -->
<script type="text/javaScript" language="javascript">
$(document).ready(
function() {
$(document).ready(function() {
var API_IP = "${API_IP}";
console.log("API_IP :: ", API_IP);
var API_IP = "${API_IP}";
console.log("API_IP :: ", API_IP);
//문자발송 함수
$("#ajax_select_price").click(
function() {
//문자발송 함수
$("#ajax_select_price").click(function() {
//문자발송 결과 데이터 수신 전 기존 데이터 초기화
$("#mgi").text("");
$("#sc").text("");
$("#fc").text("");
$("#bc").text("");
$("#mt").text("");
//문자발송 결과 데이터 수신 전 기존 데이터 초기화
$("#mgi").text("");
$("#sc").text("");
$("#fc").text("");
$("#bc").text("");
$("#mt").text("");
//문자발송 API로 전송할 데이터
var searchWebParam = {
'p_mberId' : $('#mberId').val() //회원 아이디
,
'p_apiKey' : $('#apiKey').val() //api 키
,
'p_callFrom' : $('#callFrom').val() //발신자 번호
,
'p_callToList' : $('#callToList').val()//수신자 번호
,
'p_smsTxt' : $('#smsTxt').val() //문자 내용
,
'p_nameStr' : $('#nameStr').val() //치환용 이름
,
'p_testYn' : $('#testYn').val()
,
'p_api_ip' : API_IP
//테스트 데이터 여부
};
//문자발송 API로 전송할 데이터
var searchWebParam = {
'p_mberId' : $('#mberId').val() //회원 아이디
,
'p_apiKey' : $('#apiKey').val() //api 키
,
'p_callFrom' : $('#callFrom').val() //발신자 번호
,
'p_callToList' : $('#callToList').val()//수신자 번호
,
'p_smsTxt' : $('#smsTxt').val() //문자 내용
,
'p_nameStr' : $('#nameStr').val() //치환용 이름
,
'p_testYn' : $('#testYn').val()
,
'p_api_ip' : API_IP
//테스트 데이터 여부
};
console.log('searchWebParam : ', searchWebParam);
console.table(searchWebParam);
console.log('searchWebParam : ', searchWebParam);
console.table(searchWebParam);
//문자발송 REST API를 Ajax로 이용하기 위한 호출
$.ajax({
url : "/sample_mjon/jsp_example_send_msg_r1.jsp", //요청 URL WEB-INF 아래 있으면 호출이 안됨
dataType : "json", //요청 값을 json으로 수신
async : false,
type : "POST", //POST 방식
//문자발송 REST API를 Ajax로 이용하기 위한 호출
$.ajax({
url : "/sample_mjon/jsp_example_send_msg_r1.jsp", //요청 URL WEB-INF 아래 있으면 호출이 안됨
dataType : "json", //요청 값을 json으로 수신
async : false,
type : "POST", //POST 방식
data : searchWebParam,
data : searchWebParam,
success : function(returnData, status) {
console.log('returnData :: ', returnData);
success : function(returnData, status) {
console.log('returnData :: ', returnData);
if (returnData.data.resultCode == "0") { //결과가 성공인 경우 결과값 노출
if (returnData.data.resultCode == "0") { //결과가 성공인 경우 결과값 노출
$("#mgi").val(
returnData.data.msgGroupId);
$("#sc").val(
returnData.data.successCnt);
$("#fc").val(
returnData.data.failCnt);
$("#bc").val(
returnData.data.blockCnt);
$("#mt").val(
returnData.data.msgType);
$("#mgi").val(
returnData.data.msgGroupId);
$("#sc").val(
returnData.data.successCnt);
$("#fc").val(
returnData.data.failCnt);
$("#bc").val(
returnData.data.blockCnt);
$("#mt").val(
returnData.data.msgType);
} else { //결과가 실패인 경우 원인 노출
alert(returnData.data.resultCode
+ " : " + returnData.data.msg);
}
} else { //결과가 실패인 경우 원인 노출
alert(returnData.data.resultCode
+ " : " + returnData.data.msg);
}
},
},
error : function(request, status, error) { //에러가 발생한 경우 에러 노출
alert(request + "///" + error + "///"
+ status + "///" + "AJAX_ERROR");
console.log("AJAX_ERROR");
}
});
});
error : function(request, status, error) { //에러가 발생한 경우 에러 노출
alert(request + "///" + error + "///"
+ status + "///" + "AJAX_ERROR");
console.log("AJAX_ERROR");
}
});
});
});
</script>
</head>
<!-- for validator #3 -->
<body>
<div class="contWrap">
<div class="pageTitle">
<div class="pageIcon">
@ -164,10 +243,13 @@
<p class="tType6 c_999999">발송 테스트</p>
</div>
<div class="pageCont">
<div class="pageCont">
<%@include file="/WEB-INF/jsp/uss/ion/api/test/sms/include/tab_include.jsp" %>
<div class="pageCont">
<div class="listTop maxWth">
<span class="tType4 c_456ded fwBold">
<p>발신정보.</p>
@ -204,8 +286,8 @@
</table>
<div class="btnWrap">
<input type="button" class="btnType1" value="발 송"
id="ajax_select_price">
<input type="button" class="btnType2" onclick="fnSelectSendHistry(); return false;" value="전송내역 불러오기">
<input type="button" class="btnType1" value="발 송" id="ajax_select_price">
</div>
<div class="listTop maxWth">
@ -255,3 +337,9 @@
</div>
</div>
</div>
<input type="hidden" id="reqMeth" value="${reqMeth}"/>
<%@include file="/WEB-INF/jsp/uss/ion/api/test/sms/include/popupCmn.jsp" %>
</body>
</html>

View File

@ -0,0 +1,120 @@
$(document).ready(function(){
$('#showMask').click(function(e){
// preventDefault는 href의 링크 기본 행동을 막는 기능입니다.
e.preventDefault();
// 화면의 높이와 너비를 변수로 만듭니다.
var maskHeight = $(document).height();
var maskWidth = $(window).width();
// 마스크의 높이와 너비를 화면의 높이와 너비 변수로 설정합니다.
$('.mask').css({'width':maskWidth,'height':maskHeight});
// fade 애니메이션 : 1초 동안 검게 됐다가 80%의 불투명으로 변합니다.
$('.mask').fadeIn(1000);
$('.mask').fadeTo("slow",0.8);
// 레이어 팝업을 가운데로 띄우기 위해 화면의 높이와 너비의 가운데 값과 스크롤 값을 더하여 변수로 만듭니다.
var left = ( $(window).scrollLeft() + ( $(window).width() - $('.window').width()) / 2 );
var top = ( $(window).scrollTop() + ( $(window).height() - $('.window').height()) / 2 );
// css 스타일을 변경합니다.
$('.window').css({'left':left,'top':top, 'position':'absolute'});
// 레이어 팝업을 띄웁니다.
$('.window').show();
$('#checkIdModal').focus();
});
// 닫기(close)를 눌렀을 때 작동합니다.
$('.window .close').click(function (e) {
e.preventDefault();
$('.mask, .window').hide();
$("input[name=emplyrId]").val("");
});
$('#checkIdModal').on('keydown', function(e) {
if (e.key === 'Enter' || e.keyCode === 13) {
e.preventDefault(); // 폼 submit 막기
fn_searchUser();
}
});
});
//회원 조회
function fn_searchUser(){
$.ajax({
type:"POST",
url:"/uss/ion/api/test/sms/findByApiInfoWhereMberIdAjax.do",
data:{
"checkId": $("#checkIdModal").val()
},
dataType:'json',
timeout:(1000*30),
success:function(data){
console.log('data ', data);
if(data?.message)
{
alert(data.message);
return false;
}
else
{
var object = data.object;
console.log('object : ', object);
console.log('object.accessKey : ', object.accessKey);
$('#mberId').val(object.mberId);
$('#apiKey').val(object.accessKey);
$('#useYn').val(object.useYn);
$('#callInfo').val(object.callInfo);
$('.mask, .window').hide();
}
},
error:function(request , status, error){
console.log(' error ?');
console.log('request : ', request);
console.log('status : ', status);
}
});
}
//최근 문자 전송내역 리스트 팝업 호출하기
function fnSelectSendHistry() {
var p_mberId = $('#mberId').val();
var p_apiKey = $('#apiKey').val();
var p_reqMeth = $('#reqMeth').val();
if (!p_mberId?.trim() || !p_apiKey?.trim()) {
alert("회원ID 또는 API Key가 비어있습니다.");
return;
}
$('#apiInfoFomr').find('input[name="mberId"]').val(p_mberId);
$('#apiInfoFomr').find('input[name="accessKey"]').val(p_apiKey);
$('#apiInfoFomr').find('input[name="reqMeth"]').val(p_reqMeth);
var url = "/uss/ion/api/test/sms/selectSendHistryAjax.do";
// window.open("_blank", 'popupSelectSendHistry', 'width=1600, height=800, top=50, left=0, fullscreen=no, menubar=no, status=no, toolbar=no, titlebar=yes, location=no, scrollbars=no');
window.open("", 'popupSelectSendHistry', 'width=1600, height=800, top=50, left=0, fullscreen=no, menubar=no, status=no, toolbar=no, titlebar=yes, location=no, scrollbars=no');
$('#apiInfoFomr')
.attr('action', url)
.attr('target', 'popupSelectSendHistry')
.submit();
}