이지우 - 관리자 > 청소년 > 교육신청관리 > 상세 > SMS 기능 추가

This commit is contained in:
jiwoo 2023-11-14 14:27:43 +09:00
parent 7f0273b84e
commit 2e6b5deb0f
7 changed files with 287 additions and 20 deletions

11
pom.xml
View File

@ -474,6 +474,17 @@
<artifactId>httpclient</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.4</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>

View File

@ -0,0 +1,156 @@
package kcc.ve.cmm;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import kcc.com.cmm.service.EgovFileMngUtil;
public class VeSendSMS {
private static final Logger LOGGER = LoggerFactory.getLogger(EgovFileMngUtil.class);
//================================================================
//찾교 관리자 SMS 발송 - 알리고 API
//사용자 ID : Identifier
//발급 : ny3v5te9d8131byxllc8c0v7cmx7jqo1
//*Request
// POST /send/ HTTP/1.1
// Host: apis.aligo.in
// Service Port: 443
//key |인증용 API Key |필수 |String
//user_id |사용자id |필수 |String
//sender |발신자 전화번호 (최대 16bytes) |필수 |String
//receiver |수신자 전화번호 - 컴마(,)분기 입력 |필수 |String
//msg |메시지 내용 |필수 |String (1~2,000Byte)
//msg_type |SMS(단문) , LMS(장문), MMS(그림문자) 구분 |X |String
//title |문자제목(LMS,MMS만 허용) |X |String (1~44Byte)
//destination |%고객명% 치환용 입력 |X |String
//rdate |예약일 (현재일이상) |X |YYYYMMDD
//rtime |예약시간 - 현재시간기준 10분이후 |X |HHII
//image1 |첨부이미지 (image 또는 image1) |X |JPEG,PNG,GIF
//image2 |첨부이미지 |X |JPEG,PNG,GIF
//image3 |첨부이미지 |X |JPEG,PNG,GIF
//testmode_yn |연동테스트시 Y 적용 |X |String
//*Response
//result_code |결과코드(API 수신유무) |Integer
//message |결과 메시지( result_code 0 보다 작은경우 실패사유 표기) |String
//msg_id |메시지 고유 ID |Integer
//success_cnt |요청성공 건수 |Integer
//error_cnt |요청실패 건수 |Integer
//msg_type |메시지 타입 (1. SMS, 2.LMS, 3. MMS) |String
//================================================================
public Map<String, Object> VeSendSMS(String receiver, String msg) throws Exception {
String result = "";
Map<String, Object> resultMap = new HashMap<>();
try{
final String encodingType = "utf-8";
final String boundary = "____boundary____";
/**************** 문자전송하기 예제 ******************/
/* "result_code":결과코드,"message":결과문구, */
/* "msg_id":메세지ID,"error_cnt":에러갯수,"success_cnt":성공갯수 */
/* 동일내용 > 전송용 입니다.
/******************** 인증정보 ********************/
String sms_url = "https://apis.aligo.in/send/"; // 전송요청 URL
Map<String, String> sms = new HashMap<String, String>();
sms.put("user_id", "copy0723"); // SMS 아이디
sms.put("key", "ny3v5te9d8131byxllc8c0v7cmx7jqo1"); //인증키
/******************** 인증정보 ********************/
/******************** 전송정보 ********************/
//msg_type - SMS, LMS, MMS 미지정 자동 전환
sms.put("msg", msg); // 메세지 내용
sms.put("receiver", receiver); // 수신번호
//sms.put("destination", "01111111111|담당자,01111111112|홍길동"); // 수신인 %고객명% 치환
sms.put("sender", "055-792-0233"); // 발신번호
//sms.put("rdate", ""); // 예약일자 - 20161004 : 2016-10-04일기준
//sms.put("rtime", ""); // 예약시간 - 1930 : 오후 7시30분
//sms.put("testmode_yn", "Y"); // Y 인경우 실제문자 전송X , 자동취소(환불) 처리
sms.put("title", "교육운영관리시스템"); // LMS, MMS 제목 (미입력시 본문중 44Byte 또는 엔터 구분자 첫라인)
String image = "";
//image = "/tmp/pic_57f358af08cf7_sms_.jpg"; // MMS 이미지 파일 위치
/******************** 전송정보 ********************/
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setBoundary(boundary);
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setCharset(Charset.forName(encodingType));
for(Iterator<String> i = sms.keySet().iterator(); i.hasNext();){
String key = i.next();
builder.addTextBody(key, sms.get(key)
, ContentType.create("Multipart/related", encodingType));
}
File imageFile = new File(image);
if(image!=null && image.length()>0 && imageFile.exists()){
builder.addPart("image",
new FileBody(imageFile, ContentType.create("application/octet-stream"),
URLEncoder.encode(imageFile.getName(), encodingType)));
}
HttpEntity entity = builder.build();
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(sms_url);
post.setEntity(entity);
HttpResponse res = client.execute(post);
if(res != null){
BufferedReader in = new BufferedReader(new InputStreamReader(res.getEntity().getContent(), encodingType));
String buffer = null;
while((buffer = in.readLine())!=null){
result += buffer;
}
in.close();
}
ObjectMapper objectMapper = new ObjectMapper();
resultMap = objectMapper.readValue(result, new HashMap<String, Object>().getClass());
System.out.println(result);
}catch(Exception e){
System.out.println(e.getMessage());
}
return resultMap;
}
}

View File

@ -110,6 +110,7 @@ public class VEEduAplctVO extends ComDefaultVO implements Serializable {
private String sndId; //발송자
private String sndCn; //발송내용
private String sndFlag; //메일발송 계정 구분
private String trgtId; //메일,SMS 대상 ID
//ve_edu_chasi
private int chasi; // 차시
@ -1694,6 +1695,12 @@ public class VEEduAplctVO extends ComDefaultVO implements Serializable {
public void setCnclCn(String cnclCn) {
this.cnclCn = cnclCn;
}
public String getTrgtId() {
return trgtId;
}
public void setTrgtId(String trgtId) {
this.trgtId = trgtId;
}
}

View File

@ -2,6 +2,7 @@ package kcc.ve.oprtn.pblc.sndMng.web;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.annotation.Resource;
@ -30,6 +31,7 @@ import kcc.let.uss.ion.cnt.service.CntManageVO;
import kcc.let.uss.ion.cnt.service.EgovCntManageService;
import kcc.let.utl.fcc.service.EgovCryptoUtil;
import kcc.ve.cmm.VeSendMail;
import kcc.ve.cmm.VeSendSMS;
import kcc.ve.instr.tngrVisitEdu.asgnmInfo.service.VEAsgnmMIXService;
import kcc.ve.instr.tngrVisitEdu.asgnmInfo.service.VEEduPnltyService;
import kcc.ve.instr.tngrVisitEdu.asgnmInfo.service.VEInstrFeeService;
@ -405,6 +407,70 @@ public class SndMngController {
}
//================================================================
//찾교 관리자 SMS 발송 - 알리고 API
//사용자 ID : Identifier
//발급 : ny3v5te9d8131byxllc8c0v7cmx7jqo1
//*Request
// POST /send/ HTTP/1.1
// Host: apis.aligo.in
// Service Port: 443
//key |인증용 API Key |필수 |String
//user_id |사용자id |필수 |String
//sender |발신자 전화번호 (최대 16bytes) |필수 |String
//receiver |수신자 전화번호 - 컴마(,)분기 입력 |필수 |String
//msg |메시지 내용 |필수 |String (1~2,000Byte)
//msg_type |SMS(단문) , LMS(장문), MMS(그림문자) 구분 |X |String
//title |문자제목(LMS,MMS만 허용) |X |String (1~44Byte)
//destination |%고객명% 치환용 입력 |X |String
//rdate |예약일 (현재일이상) |X |YYYYMMDD
//rtime |예약시간 - 현재시간기준 10분이후 |X |HHII
//image1 |첨부이미지 (image 또는 image1) |X |JPEG,PNG,GIF
//image2 |첨부이미지 |X |JPEG,PNG,GIF
//image3 |첨부이미지 |X |JPEG,PNG,GIF
//testmode_yn |연동테스트시 Y 적용 |X |String
//*Response
//result_code |결과코드(API 수신유무) |Integer
//message |결과 메시지( result_code 0 보다 작은경우 실패사유 표기) |String
//msg_id |메시지 고유 ID |Integer
//success_cnt |요청성공 건수 |Integer
//error_cnt |요청실패 건수 |Integer
//msg_type |메시지 타입 (1. SMS, 2.LMS, 3. MMS) |String
//================================================================
@RequestMapping(value="offeduSMSSndAjax.do")
public ModelAndView offeduSMSSndAjax(VEEduAplctVO vEEduAplctVO) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("jsonView");
String result = "success";
String message = "정상적으로 발송되었습니다.";
VeSendSMS sendSMS = new VeSendSMS();
Map<String, Object> resultMap = sendSMS.VeSendSMS(vEEduAplctVO.getClphone(), vEEduAplctVO.getSndCn());
LoginVO loginVO = checkLoginUtil.getAuthLoginVO();
//문자 발송 성공 로그
if("1".equals(resultMap.get("result_code"))){
String snd_ord = sndGnrService.getNextStringId();
vEEduAplctVO.setSndHstryOrd(snd_ord);
vEEduAplctVO.setSndId(loginVO.getUniqId());
vEEduAplctVO.setTrgt(vEEduAplctVO.getClphone());
vEEduAplctSndHstryService.insert(vEEduAplctVO);
}else {
result = "fail";
message = resultMap.get("message").toString();
}
modelAndView.addObject("result", result);
modelAndView.addObject("message", message);
return modelAndView;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//

View File

@ -19,7 +19,9 @@
snd_cd,
snd_pnttm,
snd_id,
snd_cn
snd_cn,
trgt_id,
trgt
</sql>
<!-- 조회용 공통 컬럼 명 -->
@ -61,8 +63,9 @@
#sndCd#,
SYSDATE,
#sndId#,
SUBSTR(#sndCn#,0,950)
SUBSTR(#sndCn#,0,950),
#trgtId#,
#trgt#
/*
sndCn
*/
@ -86,6 +89,10 @@
, snd_cn = sndCn
*/
, snd_cn = SUBSTR(#sndCn#,0,950)
</isNotEmpty><isNotEmpty property="trgtId">
, trgt_id = #trgtId#
</isNotEmpty><isNotEmpty property="trgt">
, trgt = #trgt#
</isNotEmpty>
</insert>

View File

@ -187,7 +187,7 @@
}
//sms 발송
function fncSndSms(){
/* function fncSndSms(){
var p_smsMsg = $("#smsMsg").val();
@ -203,6 +203,24 @@
p_smsMsg,
""
);
} */
function fncSndSms(){
var p_smsMsg = $("#smsMsg").val();
if (p_smsMsg==""){
alert("SMS 발송 내용은 필수값입니다.");
return false;
}
fncContent(
"${pageContext.request.contextPath}/kccadr/oprtn/pblc/offeduSMSSndAjax.do",
"10", //코드 10:sms 20:mail
p_smsMsg,
""
);
}
//이메일 발송
@ -237,7 +255,8 @@
"eduAplctOrd": $("#eduAplctOrd").val(),
"clphone": '<c:out value="${info.clphone}" />',
"email": '<c:out value="${info.email}" />',
"sndFlag": p_flag
"sndFlag": p_flag,
"trgtId" : '<c:out value="${info.userId}" />'
},
dataType:'json',
/*
@ -249,10 +268,9 @@
success:function(returnData){
if(returnData.result == "success"){
alert("정상적으로 발송되었습니다.");
alert(returnData.message);
}else{
alert("발송 중 오류가 발생하였습니다.");
alert(returnData.message);
}
},
error:function(request , status, error){
@ -682,10 +700,12 @@
</th>
<td class="tb_alram">
<div>
<textarea id="smsMsg" placeholder="* 메시지는 단문(90byte)으로만 작성 가능합니다." onkeyup="countBytes(this ,90 ,$('#byteSms')[0])"></textarea>
<!-- 231114 단문제한 삭제 -->
<!-- <textarea id="smsMsg" placeholder="* 메시지는 단문(90byte)으로만 작성 가능합니다." onkeyup="countBytes(this ,90 ,$('#byteSms')[0])"></textarea> -->
<textarea id="smsMsg"></textarea>
<button type="button" class="btn_type08" onclick="fncSndSms();return false;">SMS 발송</button>
</div>
<p><span id="byteSms">0</span>/90 byte</p>
<!-- <p><span id="byteSms">0</span>/90 byte</p> -->
</td>
</tr>
<tr>

View File

@ -188,7 +188,7 @@ function instrChk(){
<p class="sub_title">대국민 저작권 교육 서비스</p>
<p class="title">찾아가는 교육 청소년!</p>
<p class="summary">편리하고 안전한 저작권 이용환경 조성을 통해 올바른 저작권 문화 구축에 앞장서겠습니다.</p>
<a href="#none">교육신청 등록</a>
<a href="${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduAplct/eduAplctReg.do">교육신청 등록</a>
</div>
</div>
</div>
@ -198,7 +198,7 @@ function instrChk(){
<p class="sub_title">대국민 저작권 교육 서비스</p>
<p class="title">찾아가는 교육 성인!</p>
<p class="summary">편리하고 안전한 저작권 이용환경 조성을 통해 올바른 저작권 문화 구축에 앞장서겠습니다.</p>
<a href="#none">교육신청 등록</a>
<a href="${pageContext.request.contextPath}/web/ve/aplct/adultVisitEdu/eduAplct/eduAplctReg.do">교육신청 등록</a>
</div>
</div>
</div>
@ -208,7 +208,7 @@ function instrChk(){
<p class="sub_title">대국민 저작권 교육 서비스</p>
<p class="title">체험교실!</p>
<p class="summary">편리하고 안전한 저작권 이용환경 조성을 통해 올바른 저작권 문화 구축에 앞장서겠습니다.</p>
<a href="#none">교육신청 등록</a>
<a href="${pageContext.request.contextPath}/web/ve/aplct/cpyrgExprnClsrm/exprnClsrmInfo/exprnClsrmAplctGuide.do">교육신청 등록</a>
</div>
</div>
</div>
@ -218,7 +218,7 @@ function instrChk(){
<p class="sub_title">대국민 저작권 교육 서비스</p>
<p class="title">실무역량강화!</p>
<p class="summary">편리하고 안전한 저작권 이용환경 조성을 통해 올바른 저작권 문화 구축에 앞장서겠습니다.</p>
<a href="#none">교육신청 등록</a>
<a href="${pageContext.request.contextPath}/web/ve/aplct/fndtnEnhanceTrn/eduAplctList.do">교육신청 등록</a>
</div>
</div>
</div>
@ -228,7 +228,7 @@ function instrChk(){
<p class="sub_title">대국민 저작권 교육 서비스</p>
<p class="title">교육조건부 기소유예교육!</p>
<p class="summary">편리하고 안전한 저작권 이용환경 조성을 통해 올바른 저작권 문화 구축에 앞장서겠습니다.</p>
<a href="#none">교육신청 등록</a>
<a href="${pageContext.request.contextPath}/web/ve/aplct/sspnIdtmt/eduAplctList.do">교육신청 등록</a>
</div>
</div>
</div>
@ -244,31 +244,31 @@ function instrChk(){
<!-- main_banner -->
<ul class="main_banner_link inner">
<li class="banner_link_01">
<a href="#none">
<a href="${pageContext.request.contextPath}/web/ve/aplct/tngrVisitEdu/eduAplct/eduInfo.do">
<i></i>
<p>찾아가는 교육 <span>청소년</span></p>
</a>
</li>
<li class="banner_link_02">
<a href="#none">
<a href="${pageContext.request.contextPath}/web/ve/aplct/adultVisitEdu/eduAplct/eduInfo.do">
<i></i>
<p>찾아가는 교육 <span>성인</span></p>
</a>
</li>
<li class="banner_link_03">
<a href="#none">
<a href="${pageContext.request.contextPath}/web/ve/aplct/cpyrgExprnClsrm/exprnClsrmInfo/eduInfo.do">
<i></i>
<p>체험교실</p>
</a>
</li>
<li class="banner_link_04">
<a href="#none">
<a href="${pageContext.request.contextPath}/web/ve/aplct/fndtnEnhanceTrn/eduInfo.do">
<i></i>
<p>실무역량강화교육</p>
</a>
</li>
<li class="banner_link_05">
<a href="#none">
<a href="${pageContext.request.contextPath}/web/ve/aplct/sspnIdtmt/eduInfo.do">
<i></i>
<p>기소유예교육</p>
</a>