--- src/main/java/itn/let/mjo/addr/service/AddrService.java
+++ src/main/java/itn/let/mjo/addr/service/AddrService.java
... | ... | @@ -109,4 +109,8 @@ |
| 109 | 109 |
void deleteAddr_advc(AddrGroupVO addrGroupVO) throws Exception; |
| 110 | 110 |
|
| 111 | 111 |
int getAddrCount(AddrGroupVO addrGroupVO) throws Exception; |
| 112 |
+ |
|
| 113 |
+ StatusResponse insertByAddrGrpDataAndAddrDataAjax(AddrVO addrVO) throws Exception; |
|
| 114 |
+ |
|
| 115 |
+ StatusResponse deleteAddrNoDataAjax(AddrVO addrVO) throws Exception; |
|
| 112 | 116 |
} |
--- src/main/java/itn/let/mjo/addr/service/impl/AddrDAO.java
+++ src/main/java/itn/let/mjo/addr/service/impl/AddrDAO.java
... | ... | @@ -292,5 +292,9 @@ |
| 292 | 292 |
return (Integer)select("AddrDAO.getAddrCount", addrVO);
|
| 293 | 293 |
} |
| 294 | 294 |
|
| 295 |
+ public int deleteAddrPhoneNo(AddrVO addrVO) {
|
|
| 296 |
+ return update("AddrDAO.deleteAddrPhoneNo", addrVO);
|
|
| 297 |
+ } |
|
| 298 |
+ |
|
| 295 | 299 |
|
| 296 | 300 |
} |
--- src/main/java/itn/let/mjo/addr/service/impl/AddrServiceImpl.java
+++ src/main/java/itn/let/mjo/addr/service/impl/AddrServiceImpl.java
... | ... | @@ -34,6 +34,8 @@ |
| 34 | 34 |
import itn.let.mjo.addr.service.AddrService; |
| 35 | 35 |
import itn.let.mjo.addr.service.AddrTransHistVO; |
| 36 | 36 |
import itn.let.mjo.addr.service.AddrVO; |
| 37 |
+import itn.let.mjo.msgsent.service.MjonMsgSentVO; |
|
| 38 |
+import lombok.extern.slf4j.Slf4j; |
|
| 37 | 39 |
|
| 38 | 40 |
/** |
| 39 | 41 |
* 주소록 관리를 위한 서비스 구현 클래스 |
... | ... | @@ -49,6 +51,7 @@ |
| 49 | 51 |
* 2021.04.08 ITN 최초 생성 |
| 50 | 52 |
* </pre> |
| 51 | 53 |
*/ |
| 54 |
+@Slf4j |
|
| 52 | 55 |
@Service("AddrService")
|
| 53 | 56 |
public class AddrServiceImpl extends EgovAbstractServiceImpl implements AddrService {
|
| 54 | 57 |
|
... | ... | @@ -644,5 +647,57 @@ |
| 644 | 647 |
|
| 645 | 648 |
return aa; |
| 646 | 649 |
} |
| 650 |
+ |
|
| 651 |
+ @Override |
|
| 652 |
+ public StatusResponse insertByAddrGrpDataAndAddrDataAjax(AddrVO addrVO) throws Exception {
|
|
| 653 |
+ |
|
| 654 |
+ String userId = addrVO.getMberId(); |
|
| 655 |
+ |
|
| 656 |
+ AddrGroupVO addrGroupVO = new AddrGroupVO(); |
|
| 657 |
+ addrGroupVO.setAddrGrpNm(addrVO.getAddrGrpNm()); |
|
| 658 |
+ addrGroupVO.setMberId(userId); |
|
| 659 |
+ addrGroupVO.setFrstRegisterId(userId); |
|
| 660 |
+ |
|
| 661 |
+ int usedCnt = addrGroupDAO.selectDuplAddrGroupCnt(addrGroupVO); |
|
| 662 |
+ if(usedCnt > 0) {
|
|
| 663 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "이미 등록되어있는 그룹이름입니다.", LocalDateTime.now()); |
|
| 664 |
+ } |
|
| 665 |
+ |
|
| 666 |
+ String addrGrpId = addrGroupDAO.insertAddrGroup(addrGroupVO); |
|
| 667 |
+ |
|
| 668 |
+ |
|
| 669 |
+ |
|
| 670 |
+ List<AddrVO> addrDataInfo = new ArrayList<AddrVO>(); |
|
| 671 |
+ |
|
| 672 |
+ for(String phone : addrVO.getAddrPhones()) {
|
|
| 673 |
+ AddrVO addrTempVO = new AddrVO(); |
|
| 674 |
+ addrTempVO.setAddrPhoneNo(phone); |
|
| 675 |
+ addrTempVO.setAddrGrpId(addrGrpId); |
|
| 676 |
+ addrTempVO.setBookmark("N"); //북마크 : N
|
|
| 677 |
+ addrTempVO.setFrstRegisterId(userId); |
|
| 678 |
+ addrTempVO.setMberId(userId); |
|
| 679 |
+ addrDataInfo.add(addrTempVO); |
|
| 680 |
+ } |
|
| 681 |
+ |
|
| 682 |
+ int resultCnt = addrDAO.insertAddrList(addrDataInfo); |
|
| 683 |
+ |
|
| 684 |
+ |
|
| 685 |
+ |
|
| 686 |
+ return new StatusResponse(HttpStatus.OK, "총" + resultCnt + "건의 주소록 등록이 완료되었습니다.", addrVO); |
|
| 687 |
+ |
|
| 688 |
+ } |
|
| 689 |
+ |
|
| 690 |
+ @Override |
|
| 691 |
+ public StatusResponse deleteAddrNoDataAjax(AddrVO addrVO) throws Exception {
|
|
| 692 |
+ |
|
| 693 |
+// AddrPhones |
|
| 694 |
+ //아이디 저장 |
|
| 695 |
+ |
|
| 696 |
+ //주소록 디비에서 연락처 정보를 delete 시킴 |
|
| 697 |
+ int resultCnt = addrDAO.deleteAddrPhoneNo(addrVO); |
|
| 698 |
+ |
|
| 699 |
+ |
|
| 700 |
+ return new StatusResponse(HttpStatus.OK, "총 " + resultCnt + "건의 주소록을 삭제하였습니다.", addrVO); |
|
| 701 |
+ } |
|
| 647 | 702 |
|
| 648 | 703 |
} |
--- src/main/java/itn/let/mjo/addr/web/AddrController.java
+++ src/main/java/itn/let/mjo/addr/web/AddrController.java
... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 |
import java.io.InputStreamReader; |
| 5 | 5 |
import java.io.OutputStream; |
| 6 | 6 |
import java.text.SimpleDateFormat; |
| 7 |
+import java.time.LocalDateTime; |
|
| 7 | 8 |
import java.util.ArrayList; |
| 8 | 9 |
import java.util.Calendar; |
| 9 | 10 |
import java.util.Date; |
... | ... | @@ -31,10 +32,13 @@ |
| 31 | 32 |
import org.apache.poi.xssf.usermodel.XSSFRow; |
| 32 | 33 |
import org.apache.poi.xssf.usermodel.XSSFSheet; |
| 33 | 34 |
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
| 35 |
+import org.springframework.http.HttpStatus; |
|
| 36 |
+import org.springframework.http.ResponseEntity; |
|
| 34 | 37 |
import org.springframework.stereotype.Controller; |
| 35 | 38 |
import org.springframework.ui.Model; |
| 36 | 39 |
import org.springframework.ui.ModelMap; |
| 37 | 40 |
import org.springframework.web.bind.annotation.ModelAttribute; |
| 41 |
+import org.springframework.web.bind.annotation.RequestBody; |
|
| 38 | 42 |
import org.springframework.web.bind.annotation.RequestMapping; |
| 39 | 43 |
import org.springframework.web.bind.annotation.RequestParam; |
| 40 | 44 |
import org.springframework.web.bind.annotation.ResponseBody; |
... | ... | @@ -52,12 +56,14 @@ |
| 52 | 56 |
import itn.com.cmm.util.StringUtil; |
| 53 | 57 |
import itn.com.utl.fcc.service.EgovStringUtil; |
| 54 | 58 |
import itn.let.fax.addr.service.FaxAddrVO; |
| 59 |
+import itn.let.mail.service.StatusResponse; |
|
| 55 | 60 |
import itn.let.mjo.addr.service.AddrGroupService; |
| 56 | 61 |
import itn.let.mjo.addr.service.AddrGroupVO; |
| 57 | 62 |
import itn.let.mjo.addr.service.AddrService; |
| 58 | 63 |
import itn.let.mjo.addr.service.AddrTransHistVO; |
| 59 | 64 |
import itn.let.mjo.addr.service.AddrVO; |
| 60 | 65 |
import itn.let.mjo.msgdata.service.PhoneVO; |
| 66 |
+import lombok.extern.slf4j.Slf4j; |
|
| 61 | 67 |
|
| 62 | 68 |
/** |
| 63 | 69 |
* 주소록 관한 controller 클래스를 정의한다. |
... | ... | @@ -75,6 +81,7 @@ |
| 75 | 81 |
* |
| 76 | 82 |
* </pre> |
| 77 | 83 |
*/ |
| 84 |
+@Slf4j |
|
| 78 | 85 |
@Controller |
| 79 | 86 |
public class AddrController {
|
| 80 | 87 |
|
... | ... | @@ -2223,6 +2230,49 @@ |
| 2223 | 2230 |
return modelAndView; |
| 2224 | 2231 |
} |
| 2225 | 2232 |
|
| 2233 |
+ |
|
| 2234 |
+ @RequestMapping(value = {"/web/mjon/addr/insertByAddrGrpDataAndAddrDataAjax.do"})
|
|
| 2235 |
+ public ResponseEntity<StatusResponse> insertByAddrGrpDataAndAddrDataAjax(@RequestBody AddrVO addrVO) throws Exception {
|
|
| 2236 |
+ |
|
| 2237 |
+ ModelAndView modelAndView = new ModelAndView(); |
|
| 2238 |
+ modelAndView.setViewName("jsonView");
|
|
| 2239 |
+ |
|
| 2240 |
+ //로그인 권한정보 불러오기 |
|
| 2241 |
+ LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null; |
|
| 2242 |
+ String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId()); |
|
| 2243 |
+ |
|
| 2244 |
+ if(userId == null) {
|
|
| 2245 |
+ if(StringUtils.isEmpty(userId)) return ResponseEntity.ok().body(new StatusResponse(HttpStatus.BAD_REQUEST, "로그인 후 이용해 주세요", LocalDateTime.now())); |
|
| 2246 |
+ } |
|
| 2247 |
+ |
|
| 2248 |
+ log.info(" + addrVO.getAddrPhones() :: [{}]", addrVO.getAddrPhones().length);
|
|
| 2249 |
+ log.info(" + addrVO.getAddrGrpNm() :: [{}]", addrVO.getAddrGrpNm());
|
|
| 2250 |
+ addrVO.setMberId(userId); |
|
| 2251 |
+ |
|
| 2252 |
+ |
|
| 2253 |
+ return ResponseEntity.ok().body(addrService.insertByAddrGrpDataAndAddrDataAjax(addrVO)); |
|
| 2254 |
+ } |
|
| 2255 |
+ |
|
| 2256 |
+ @RequestMapping(value = {"/web/mjon/addr/deleteAddrNoDataAjax.do"})
|
|
| 2257 |
+ public ResponseEntity<StatusResponse> deleteAddrNoDataAjax(@RequestBody AddrVO addrVO) throws Exception {
|
|
| 2258 |
+ |
|
| 2259 |
+ ModelAndView modelAndView = new ModelAndView(); |
|
| 2260 |
+ modelAndView.setViewName("jsonView");
|
|
| 2261 |
+ |
|
| 2262 |
+ //로그인 권한정보 불러오기 |
|
| 2263 |
+ LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null; |
|
| 2264 |
+ String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId()); |
|
| 2265 |
+ |
|
| 2266 |
+ if(userId == null) {
|
|
| 2267 |
+ if(StringUtils.isEmpty(userId)) return ResponseEntity.ok().body(new StatusResponse(HttpStatus.BAD_REQUEST, "로그인 후 이용해 주세요", LocalDateTime.now())); |
|
| 2268 |
+ } |
|
| 2269 |
+ |
|
| 2270 |
+ addrVO.setMberId(userId); |
|
| 2271 |
+ |
|
| 2272 |
+ return ResponseEntity.ok().body(addrService.deleteAddrNoDataAjax(addrVO)); |
|
| 2273 |
+ } |
|
| 2274 |
+ |
|
| 2275 |
+ |
|
| 2226 | 2276 |
|
| 2227 | 2277 |
|
| 2228 | 2278 |
public boolean getNameRepLenChk(String type, String value) {
|
--- src/main/java/itn/let/mjo/msgdata/web/MjonMsgDataController.java
+++ src/main/java/itn/let/mjo/msgdata/web/MjonMsgDataController.java
... | ... | @@ -114,8 +114,9 @@ |
| 114 | 114 |
import itn.let.uss.umt.service.MberManageVO; |
| 115 | 115 |
import itn.let.uss.umt.service.UserManageVO; |
| 116 | 116 |
import itn.let.utl.sim.service.EgovClntInfo; |
| 117 |
+import lombok.extern.slf4j.Slf4j; |
|
| 117 | 118 |
|
| 118 |
- |
|
| 119 |
+@Slf4j |
|
| 119 | 120 |
@Controller |
| 120 | 121 |
public class MjonMsgDataController {
|
| 121 | 122 |
|
... | ... | @@ -816,6 +817,7 @@ |
| 816 | 817 |
|
| 817 | 818 |
mjonMsgDataVO.setMsgSeqList(tempList); |
| 818 | 819 |
|
| 820 |
+ log.info("===================================================");
|
|
| 819 | 821 |
List<MjonMsgVO> resultList = mjonMsgDataService.selectReSendMsgDataList(mjonMsgDataVO); |
| 820 | 822 |
|
| 821 | 823 |
//문자발송 이미지 처리 - 사용하지 않아서 주석처리함. |
--- src/main/java/itn/let/mjo/msgsent/service/MjonMsgDetailSentVO.java
+++ src/main/java/itn/let/mjo/msgsent/service/MjonMsgDetailSentVO.java
... | ... | @@ -53,6 +53,7 @@ |
| 53 | 53 |
|
| 54 | 54 |
private String statusCd; // 진행상태 코드 |
| 55 | 55 |
private String divideYN; |
| 56 |
+ private String divideText; |
|
| 56 | 57 |
private int diffMin; |
| 57 | 58 |
private String totPrice; |
| 58 | 59 |
|
--- src/main/java/itn/let/mjo/msgsent/service/impl/MjonMsgSentDAO.java
+++ src/main/java/itn/let/mjo/msgsent/service/impl/MjonMsgSentDAO.java
... | ... | @@ -186,5 +186,9 @@ |
| 186 | 186 |
|
| 187 | 187 |
return (List<MjonMsgDetailSentVO>) list("MjonMsgSentDAO.findByMsgDetailListAjax", mjonMsgDetailSentVO);
|
| 188 | 188 |
} |
| 189 |
+ |
|
| 190 |
+ public List<String> findByReqDateWhereMsgGroupId(String msgGroupId) {
|
|
| 191 |
+ return (List<String>) list("MjonMsgSentDAO.findByReqDateWhereMsgGroupId", msgGroupId);
|
|
| 192 |
+ } |
|
| 189 | 193 |
|
| 190 | 194 |
} |
--- src/main/java/itn/let/mjo/msgsent/service/impl/MjonMsgSentServiceImpl.java
+++ src/main/java/itn/let/mjo/msgsent/service/impl/MjonMsgSentServiceImpl.java
... | ... | @@ -4,9 +4,12 @@ |
| 4 | 4 |
import java.math.BigDecimal; |
| 5 | 5 |
import java.math.RoundingMode; |
| 6 | 6 |
import java.text.SimpleDateFormat; |
| 7 |
+import java.time.LocalDateTime; |
|
| 8 |
+import java.time.format.DateTimeFormatter; |
|
| 7 | 9 |
import java.util.ArrayList; |
| 8 | 10 |
import java.util.Date; |
| 9 | 11 |
import java.util.HashMap; |
| 12 |
+import java.util.LinkedHashMap; |
|
| 10 | 13 |
import java.util.List; |
| 11 | 14 |
import java.util.Locale; |
| 12 | 15 |
import java.util.Map; |
... | ... | @@ -126,13 +129,21 @@ |
| 126 | 129 |
|
| 127 | 130 |
Map<String, Object> resultMap = new HashMap<String, Object>(); |
| 128 | 131 |
|
| 129 |
- System.out.println("mjonMsgSentVO.getSearchConditionSite() :: "+ mjonMsgSentVO.getSearchConditionSite());
|
|
| 130 | 132 |
// 목록 |
| 131 | 133 |
List<MjonMsgSentVO> resultList = mjonMsgSentDAO.selectAllMsgSentList_advc(mjonMsgSentVO); |
| 132 | 134 |
|
| 135 |
+ // 내용이 없고 이미지만 있을 경우 |
|
| 136 |
+ resultList.stream().forEach(t->{
|
|
| 137 |
+ log.info("+ t.getMsgKind() : [{}]",t.getMsgType());
|
|
| 138 |
+ if("6".equals(t.getMsgType())
|
|
| 139 |
+ && StringUtils.isEmpty(t.getSmsTxt()) |
|
| 140 |
+ && !"0".equals(t.getFileCnt()) |
|
| 141 |
+ ) {
|
|
| 142 |
+ t.setSmsTxt("이미지");
|
|
| 143 |
+ } |
|
| 144 |
+ }); |
|
| 145 |
+ |
|
| 133 | 146 |
// groupID에 대한 결과건수(대기, 성공 실패) 분할건수를 가져옴 |
| 134 |
- // TODO : 분할여부는 예약일 때만 가져오게 해야되는지 검토 필요 |
|
| 135 |
- |
|
| 136 | 147 |
resultList = makeDetailFunction(resultList); |
| 137 | 148 |
|
| 138 | 149 |
/* |
... | ... | @@ -169,8 +180,8 @@ |
| 169 | 180 |
resultVO.setResultSValue(updatedVO.getResultSValue()); // 성공건수 |
| 170 | 181 |
resultVO.setResultWValue(updatedVO.getResultWValue()); // 대기건수 |
| 171 | 182 |
resultVO.setResultFValue(updatedVO.getResultFValue()); // 실패건수 |
| 172 |
- resultVO.setTotPrice(updatedVO.getTotPrice()); |
|
| 173 |
- resultVO.setDivideYN(updatedVO.getDivideYN()); |
|
| 183 |
+ resultVO.setTotPrice(updatedVO.getTotPrice()); // 총 발송 금액 (성공건수 * 개별금액) |
|
| 184 |
+ resultVO.setDivideYN(updatedVO.getDivideYN()); // 분할 여부 |
|
| 174 | 185 |
|
| 175 | 186 |
|
| 176 | 187 |
// 퍼센트 계산 실행 |
... | ... | @@ -182,21 +193,21 @@ |
| 182 | 193 |
|
| 183 | 194 |
// 진행상태 코드화 |
| 184 | 195 |
String statusCode = getStatusCode(MjonMsgSentVO.builder() |
| 185 |
- .reserveCYn(resultVO.getReserveCYn()) |
|
| 186 |
- .reserveYn(resultVO.getReserveYn()) |
|
| 187 |
- .msgGroupCnt(resultVO.getMsgGroupCnt()) |
|
| 188 |
- .resultSValue(resultVO.getResultSValue()) |
|
| 189 |
- .resultWValue(resultVO.getResultWValue()) |
|
| 190 |
- .resultFValue(resultVO.getResultFValue()) |
|
| 191 |
- .diffMin(resultVO.getDiffMin()) |
|
| 192 |
- .build()); |
|
| 193 |
- log.info(" ++ statusCode :: [{}]" ,statusCode);
|
|
| 196 |
+ .reserveCYn(resultVO.getReserveCYn()) |
|
| 197 |
+ .reserveYn(resultVO.getReserveYn()) |
|
| 198 |
+ .msgGroupCnt(resultVO.getMsgGroupCnt()) |
|
| 199 |
+ .resultSValue(resultVO.getResultSValue()) |
|
| 200 |
+ .resultWValue(resultVO.getResultWValue()) |
|
| 201 |
+ .resultFValue(resultVO.getResultFValue()) |
|
| 202 |
+ .diffMin(resultVO.getDiffMin()) |
|
| 203 |
+ .build()); |
|
| 204 |
+ |
|
| 194 | 205 |
resultVO.setStatusCd(statusCode); |
| 195 | 206 |
|
| 196 | 207 |
// 결과 출력 |
| 197 |
- System.out.println("성공률: " + returnMap.get("successPct"));
|
|
| 198 |
- System.out.println("대기율: " + returnMap.get("waitingPct"));
|
|
| 199 |
- System.out.println("실패율: " + returnMap.get("failedPct"));
|
|
| 208 |
+// log.info("성공률: [{}]", returnMap.get("successPct"));
|
|
| 209 |
+// log.info("대기율: [{}]", returnMap.get("waitingPct"));
|
|
| 210 |
+// log.info("실패율: [{}]", returnMap.get("failedPct"));
|
|
| 200 | 211 |
|
| 201 | 212 |
|
| 202 | 213 |
// 광고일떄 (광고)와 줄바꿈+무료거부 0808800858 삭제 |
... | ... | @@ -205,11 +216,17 @@ |
| 205 | 216 |
.replaceAll("\\s*무료거부 0808800858", ""));
|
| 206 | 217 |
} |
| 207 | 218 |
|
| 219 |
+ // 그림문자일 경우 그림정보 가져오기 |
|
| 208 | 220 |
if(StringUtils.isNotEmpty(resultVO.getFileCnt()) && Integer.parseInt(resultVO.getFileCnt()) > 0) |
| 209 | 221 |
{
|
| 210 |
- |
|
| 211 | 222 |
List<FileInfoVO> fileInfos = getFileInfo(resultVO); |
| 212 | 223 |
resultVO.setFileInfos(fileInfos); |
| 224 |
+ } |
|
| 225 |
+ |
|
| 226 |
+ // 분할문자인 경우 |
|
| 227 |
+ if("Y".equals(resultVO.getDivideYN())) {
|
|
| 228 |
+ String divideText = calculateBatchInfo(resultVO); |
|
| 229 |
+ resultVO.setDivideText(divideText); |
|
| 213 | 230 |
} |
| 214 | 231 |
|
| 215 | 232 |
|
... | ... | @@ -221,6 +238,37 @@ |
| 221 | 238 |
} |
| 222 | 239 |
|
| 223 | 240 |
|
| 241 |
+ private String calculateBatchInfo(MjonMsgDetailSentVO resultVO) {
|
|
| 242 |
+ |
|
| 243 |
+ String msgGroupId = resultVO.getMsgGroupId(); |
|
| 244 |
+ |
|
| 245 |
+ |
|
| 246 |
+ List<String> requestTimes = mjonMsgSentDAO.findByReqDateWhereMsgGroupId(msgGroupId); |
|
| 247 |
+ |
|
| 248 |
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
|
|
| 249 |
+ Map<LocalDateTime, Integer> timeCountMap = new LinkedHashMap<>(); |
|
| 250 |
+ |
|
| 251 |
+ // REQ_DATE 그룹화 (같은 시간대 몇 건인지) |
|
| 252 |
+ for (String timeStr : requestTimes) {
|
|
| 253 |
+ LocalDateTime time = LocalDateTime.parse(timeStr, formatter); |
|
| 254 |
+ timeCountMap.put(time, timeCountMap.getOrDefault(time, 0) + 1); |
|
| 255 |
+ } |
|
| 256 |
+ |
|
| 257 |
+ // 가장 첫 번째 시간 & 간격 계산 |
|
| 258 |
+ List<LocalDateTime> sortedKeys = new ArrayList<>(timeCountMap.keySet()); |
|
| 259 |
+ if (sortedKeys.size() < 2) {
|
|
| 260 |
+ return "데이터 부족 (분석 불가)"; |
|
| 261 |
+ } |
|
| 262 |
+ |
|
| 263 |
+ int batchSize = timeCountMap.get(sortedKeys.get(0)); // 한 번에 보낸 건수 |
|
| 264 |
+ int intervalMinutes = sortedKeys.get(1).getMinute() - sortedKeys.get(0).getMinute(); // 시간 간격 계산 |
|
| 265 |
+// int batchCount = sortedKeys.size(); // 총 몇 번 보냈는지 |
|
| 266 |
+ |
|
| 267 |
+// return String.format("%,d건씩 %d분 간격 (%d회 발송)", batchSize, intervalMinutes, batchCount);
|
|
| 268 |
+ return String.format("%,d건씩 %d분 간격", batchSize, intervalMinutes);
|
|
| 269 |
+ |
|
| 270 |
+ } |
|
| 271 |
+ |
|
| 224 | 272 |
private List<FileInfoVO> getFileInfo(MjonMsgDetailSentVO result) throws Exception {
|
| 225 | 273 |
|
| 226 | 274 |
|
--- src/main/resources/egovframework/sqlmap/let/mjo/addr/Addr_SQL_Mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/mjo/addr/Addr_SQL_Mysql.xml
... | ... | @@ -933,7 +933,7 @@ |
| 933 | 933 |
|
| 934 | 934 |
</select> |
| 935 | 935 |
|
| 936 |
- <insert id="AddrDAO.insertAddrList" parameterClass="java.util.List"> |
|
| 936 |
+ <update id="AddrDAO.insertAddrList" parameterClass="java.util.List"> |
|
| 937 | 937 |
/* AddrDAO.insertAddrList */ |
| 938 | 938 |
INSERT INTO MJ_ADDR |
| 939 | 939 |
( |
... | ... | @@ -967,7 +967,18 @@ |
| 967 | 967 |
) |
| 968 | 968 |
</iterate> |
| 969 | 969 |
|
| 970 |
- </insert> |
|
| 970 |
+ </update> |
|
| 971 |
+ |
|
| 972 |
+ <update id="AddrDAO.deleteAddrPhoneNo" parameterClass="addrVO"> |
|
| 973 |
+ |
|
| 974 |
+ DELETE FROM MJ_ADDR |
|
| 975 |
+ |
|
| 976 |
+ WHERE MBER_ID = #mberId# |
|
| 977 |
+ <iterate prepend="AND ADDR_PHONE_NO IN" open="(" close=")" conjunction="," property="addrPhones">
|
|
| 978 |
+ #addrPhones[]# |
|
| 979 |
+ </iterate> |
|
| 980 |
+ |
|
| 981 |
+ </update> |
|
| 971 | 982 |
|
| 972 | 983 |
<!-- 주소록 그룹명 중복확인 --> |
| 973 | 984 |
<select id="AddrDAO.selectDuplAddrCnt" parameterClass="addrVO" resultClass="int"> |
--- src/main/resources/egovframework/sqlmap/let/msg/MjonMsgData_SQL_mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/msg/MjonMsgData_SQL_mysql.xml
... | ... | @@ -4021,6 +4021,8 @@ |
| 4021 | 4021 |
|
| 4022 | 4022 |
<select id="MjonMsgDataDAO.selectReSendMsgDataList" parameterClass="mjonMsgDataVO" resultClass="mjonMsgVO"> |
| 4023 | 4023 |
|
| 4024 |
+ /* MjonMsgDataDAO.selectReSendMsgDataList */ |
|
| 4025 |
+ |
|
| 4024 | 4026 |
SELECT MSG_ID AS msgId, |
| 4025 | 4027 |
USER_ID AS userId, |
| 4026 | 4028 |
USERDATA AS msgSeq, |
... | ... | @@ -7936,6 +7938,7 @@ |
| 7936 | 7938 |
</select> |
| 7937 | 7939 |
|
| 7938 | 7940 |
<select id="MjonMsgDataDAO.selectMjMsgListByResend" parameterClass="mjonMsgDataVO" resultClass="mjonMsgDataVO"> |
| 7941 |
+ /* MjonMsgDataDAO.selectMjMsgListByResend */ |
|
| 7939 | 7942 |
SELECT |
| 7940 | 7943 |
CALL_TO AS callTo |
| 7941 | 7944 |
FROM MJ_MSG_DATA |
--- src/main/resources/egovframework/sqlmap/let/msg/MjonMsgSent_SQL_mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/msg/MjonMsgSent_SQL_mysql.xml
... | ... | @@ -410,6 +410,14 @@ |
| 410 | 410 |
|
| 411 | 411 |
</select> |
| 412 | 412 |
|
| 413 |
+ <!-- REQ_DATE 조회--> |
|
| 414 |
+ <select id="MjonMsgSentDAO.findByReqDateWhereMsgGroupId" parameterClass="String" resultClass="String"> |
|
| 415 |
+ /* MjonMsgSentDAO.findByReqDateWhereMsgGroupId*/ |
|
| 416 |
+ |
|
| 417 |
+ SELECT REQ_DATE FROM MJ_MSG_DATA WHERE MSG_GROUP_ID =#msgGroupId# |
|
| 418 |
+ |
|
| 419 |
+ </select> |
|
| 420 |
+ |
|
| 413 | 421 |
|
| 414 | 422 |
<!-- 전체 발송결과 조회 (전송사별)--> |
| 415 | 423 |
<select id="MjonMsgSentDAO.selectAllMsgSentList_advc" parameterClass="mjonMsgSentVO" resultClass="mjonMsgSentVO"> |
--- src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentDetailView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentDetailView.jsp
... | ... | @@ -24,9 +24,14 @@ |
| 24 | 24 |
|
| 25 | 25 |
<script type="text/javascript"> |
| 26 | 26 |
|
| 27 |
+var currentSearchKeyword = ""; // 검색어 저장 |
|
| 28 |
+var currentTabFilter = "전체"; // 현재 선택된 탭 (기본값: 전체) |
|
| 29 |
+ |
|
| 27 | 30 |
var $tbDtailList = null; //에러 팝업 영역 |
| 28 | 31 |
$(document).ready(function(){
|
| 29 | 32 |
|
| 33 |
+ // 탭별 하위 버튼 활성화 |
|
| 34 |
+ fn_rowBtnSH('전체');
|
|
| 30 | 35 |
|
| 31 | 36 |
//Tabulator AJAX Data Loading |
| 32 | 37 |
$tbDtailList = new Tabulator("#detailPopup", {
|
... | ... | @@ -67,44 +72,84 @@ |
| 67 | 72 |
$("#goList").submit();
|
| 68 | 73 |
}); |
| 69 | 74 |
|
| 70 |
- |
|
| 75 |
+ |
|
| 76 |
+ |
|
| 77 |
+ // 탭 버튼 클릭 이벤트 |
|
| 78 |
+ $(".tabType3 .tab button").on("click", function () {
|
|
| 79 |
+ |
|
| 80 |
+ // 모든 탭의 active 클래스 제거 |
|
| 81 |
+ $(".tabType3 .tab").removeClass("active");
|
|
| 82 |
+ |
|
| 83 |
+ // 클릭한 버튼의 부모 요소(li)에 active 클래스 추가 |
|
| 84 |
+ $(this).parent().addClass("active");
|
|
| 85 |
+ |
|
| 86 |
+ // 기존 버튼들의 title 속성 초기화 |
|
| 87 |
+ $(".tabType3 .tab button").removeAttr("title");
|
|
| 88 |
+ |
|
| 89 |
+ // 선택된 버튼의 title 속성을 "선택됨"으로 변경 |
|
| 90 |
+ $(this).attr("title", "선택됨");
|
|
| 91 |
+ |
|
| 92 |
+ // 검색어 초기화 |
|
| 93 |
+ $("#searchInput").val("");
|
|
| 94 |
+ |
|
| 95 |
+ // 필터 적용 (검색 필터 없이 탭 기준으로만 적용) |
|
| 96 |
+ fn_applyFilters(); |
|
| 97 |
+ }); |
|
| 98 |
+ |
|
| 71 | 99 |
// 검색 버튼 클릭 시 실행 |
| 72 | 100 |
$("#searchBtn").on("click", function () {
|
| 73 |
- searchTable(); |
|
| 101 |
+ fn_search(); |
|
| 74 | 102 |
}); |
| 75 | 103 |
|
| 76 |
- // Enter 키 입력 시 실행 |
|
| 104 |
+ // 실시간 검색 및 Enter 키 이벤트 처리 |
|
| 77 | 105 |
$("#searchInput").on("keyup", function (event) {
|
| 106 |
+ let keyword = $(this).val().trim(); |
|
| 107 |
+ |
|
| 108 |
+ if (keyword.length > 2) {
|
|
| 109 |
+ fn_applyFilters({ field: "phone", type: "like", value: keyword });
|
|
| 110 |
+ } else {
|
|
| 111 |
+ fn_applyFilters(null); |
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 114 |
+ // Enter 키 입력 시 검색 실행 |
|
| 78 | 115 |
if (event.key === "Enter") {
|
| 79 |
- searchTable(); |
|
| 116 |
+ fn_search(); |
|
| 80 | 117 |
} |
| 81 | 118 |
}); |
| 82 | 119 |
|
| 83 | 120 |
|
| 84 | 121 |
|
| 85 |
- // 탭 버튼 클릭 이벤트 |
|
| 86 |
- $(".tabType3 .tab button").on("click", function () {
|
|
| 87 |
- console.log('.tabType3 .tab button');
|
|
| 88 |
- // 모든 탭의 active 클래스 제거 |
|
| 89 |
- $(".tabType3 .tab").removeClass("active");
|
|
| 90 |
- |
|
| 91 |
- // 클릭한 버튼의 부모 요소(li)에 active 클래스 추가 |
|
| 92 |
- $(this).parent().addClass("active");
|
|
| 93 |
- |
|
| 94 |
- // 기존 버튼들의 title 속성 초기화 |
|
| 95 |
- $(".tabType3 .tab button").removeAttr("title");
|
|
| 96 |
- |
|
| 97 |
- // 선택된 버튼의 title 속성을 "선택됨"으로 변경 |
|
| 98 |
- $(this).attr("title", "선택됨");
|
|
| 99 |
- |
|
| 100 |
- |
|
| 101 |
- // 클릭한 버튼의 텍스트 가져오기 |
|
| 102 |
- let resultText = $(this).text().trim(); |
|
| 103 |
- fn_tabTable('result', resultText);
|
|
| 104 |
- |
|
| 122 |
+ $('.listClose').on("click", function (){
|
|
| 123 |
+ tooltipInit(); |
|
| 124 |
+ }); |
|
| 125 |
+ |
|
| 126 |
+ $('.grpClose').on("click", function (){
|
|
| 127 |
+ $('#grpNm').val('')
|
|
| 105 | 128 |
}); |
| 106 | 129 |
|
| 107 | 130 |
}); |
| 131 |
+ |
|
| 132 |
+//검색 실행 함수 |
|
| 133 |
+function fn_search() {
|
|
| 134 |
+ let keyword = $("#searchInput").val().trim();
|
|
| 135 |
+ |
|
| 136 |
+ if (keyword.length < 3) {
|
|
| 137 |
+ alert("검색어를 3자 이상 입력해주세요.");
|
|
| 138 |
+ return; |
|
| 139 |
+ } |
|
| 140 |
+ |
|
| 141 |
+ fn_applyFilters({ field: "phone", type: "like", value: keyword });
|
|
| 142 |
+} |
|
| 143 |
+ |
|
| 144 |
+/** |
|
| 145 |
+ * @Discription : 튤팁 닫을 때 팝업 초기화 |
|
| 146 |
+ */ |
|
| 147 |
+function tooltipInit(){
|
|
| 148 |
+ |
|
| 149 |
+ $tbDtailList.clearFilter(); |
|
| 150 |
+ $("#searchInput").val('');
|
|
| 151 |
+ $("#initTab").click();
|
|
| 152 |
+} |
|
| 108 | 153 |
|
| 109 | 154 |
/** |
| 110 | 155 |
* @Discription : 상세결과 팝업 내용 가져오는 로직 |
... | ... | @@ -158,35 +203,40 @@ |
| 158 | 203 |
|
| 159 | 204 |
}; |
| 160 | 205 |
|
| 161 |
-/** |
|
| 162 |
- * @Description: 검색 기능 |
|
| 206 |
+ |
|
| 207 |
+ |
|
| 208 |
+/** |
|
| 209 |
+ * @Discription : 필터 적용 |
|
| 163 | 210 |
*/ |
| 164 |
-function searchTable() {
|
|
| 165 |
- let column = $("#searchColumn").val(); // 선택한 컬럼
|
|
| 166 |
- let keyword = $("#searchInput").val(); // 검색어
|
|
| 167 |
- |
|
| 168 |
- // 검색어가 3자 이상일 때만 필터 적용 |
|
| 169 |
-// if (keyword.length >= 3) {
|
|
| 170 |
- $tbDtailList.setFilter(column, "like", keyword); |
|
| 171 |
- fn_setPlaceholder("검색 결과가 없습니다.");
|
|
| 172 |
-// } else {
|
|
| 173 |
-// $tbDtailList.clearFilter(); // 검색어가 짧으면 필터 제거 |
|
| 174 |
-// } |
|
| 175 |
-} |
|
| 176 |
- |
|
| 177 |
-/** |
|
| 178 |
- * @Description: 탭 검색 기능 |
|
| 179 |
- */ |
|
| 180 |
-function fn_tabTable(column, keyword) {
|
|
| 181 |
- |
|
| 182 |
- if(keyword == '전체'){
|
|
| 183 |
- $tbDtailList.clearFilter(); |
|
| 184 |
- }else{
|
|
| 185 |
- $tbDtailList.setFilter(column, "like", keyword); |
|
| 211 |
+function fn_applyFilters(newFilter) {
|
|
| 212 |
+ // 현재 적용된 모든 필터 가져오기 |
|
| 213 |
+ let filters = []; |
|
| 214 |
+ |
|
| 215 |
+ // 현재 선택된 탭 값 가져오기 |
|
| 216 |
+ let selectedTab = $(".tabType3 .tab.active button").text().trim();
|
|
| 217 |
+ |
|
| 218 |
+ // 탭 필터 적용 (탭이 "전체"가 아닐 경우) |
|
| 219 |
+ if (selectedTab !== "전체") {
|
|
| 220 |
+ filters.push({ field: "result", type: "like", value: selectedTab });
|
|
| 186 | 221 |
} |
| 187 | 222 |
|
| 223 |
+ // 검색어가 입력된 경우 검색 필터 추가 |
|
| 224 |
+ if (newFilter && newFilter.value) {
|
|
| 225 |
+ filters.push(newFilter); |
|
| 226 |
+ } |
|
| 227 |
+ |
|
| 228 |
+ // 필터 적용 |
|
| 229 |
+ $tbDtailList.setFilter(filters); |
|
| 230 |
+ |
|
| 231 |
+ // Placeholder 업데이트 |
|
| 188 | 232 |
fn_setPlaceholder("검색 결과가 없습니다.");
|
| 233 |
+ |
|
| 234 |
+ // 툽팁 하위 버튼 삭제 |
|
| 235 |
+ fn_rowBtnSH(selectedTab); |
|
| 189 | 236 |
} |
| 237 |
+ |
|
| 238 |
+ |
|
| 239 |
+ |
|
| 190 | 240 |
|
| 191 | 241 |
/** |
| 192 | 242 |
* @Description: 타블레이서 설명 수정 |
... | ... | @@ -207,21 +257,38 @@ |
| 207 | 257 |
/** |
| 208 | 258 |
* @Description: 필터링된 데이터만 다운로드 |
| 209 | 259 |
*/ |
| 210 |
-function fn_downloadFilteredExcel() {
|
|
| 211 |
- let filteredData = $tbDtailList.getData("active"); // 필터링된 데이터 가져오기
|
|
| 212 |
- |
|
| 213 |
- if (filteredData.length === 0) {
|
|
| 214 |
- alert("다운로드할 데이터가 없습니다.");
|
|
| 215 |
- return; |
|
| 260 |
+ function fn_downloadFilteredExcel() {
|
|
| 261 |
+ // 현재 날짜 및 시간 가져오기 (YYYYMMDD_HHMMSS 형식) |
|
| 262 |
+ let now = new Date(); |
|
| 263 |
+ let timestamp = now.getFullYear() + |
|
| 264 |
+ ("0" + (now.getMonth() + 1)).slice(-2) +
|
|
| 265 |
+ ("0" + now.getDate()).slice(-2) + "_" +
|
|
| 266 |
+ ("0" + now.getHours()).slice(-2) +
|
|
| 267 |
+ ("0" + now.getMinutes()).slice(-2) +
|
|
| 268 |
+ ("0" + now.getSeconds()).slice(-2);
|
|
| 269 |
+ |
|
| 270 |
+ // 파일명 생성 |
|
| 271 |
+ let fileName = "filtered_data_" + timestamp + ".xlsx"; |
|
| 272 |
+ |
|
| 273 |
+ // 필터링된 데이터 가져오기 |
|
| 274 |
+ let filteredData = getFilteredDataByTab(); |
|
| 275 |
+ |
|
| 276 |
+ if (filteredData.length === 0) {
|
|
| 277 |
+ alert("다운로드할 데이터가 없습니다.");
|
|
| 278 |
+ return; |
|
| 279 |
+ } |
|
| 280 |
+ |
|
| 281 |
+ console.log("엑셀 다운로드 - 필터링된 데이터:", filteredData);
|
|
| 282 |
+ |
|
| 283 |
+ // 필터링된 데이터만 다운로드 (Tabulator의 기존 데이터를 변경하지 않음) |
|
| 284 |
+ let workbook = XLSX.utils.book_new(); |
|
| 285 |
+ let worksheet = XLSX.utils.json_to_sheet(filteredData); |
|
| 286 |
+ |
|
| 287 |
+ XLSX.utils.book_append_sheet(workbook, worksheet, "Filtered Data"); |
|
| 288 |
+ |
|
| 289 |
+ // 엑셀 파일 다운로드 |
|
| 290 |
+ XLSX.writeFile(workbook, fileName); |
|
| 216 | 291 |
} |
| 217 |
- |
|
| 218 |
-// console.log("엑셀 다운로드 - 필터링된 데이터:", filteredData);
|
|
| 219 |
- |
|
| 220 |
- $tbDtailList.download("xlsx", "filtered_data.xlsx", {
|
|
| 221 |
- sheetName: "Filtered Data", |
|
| 222 |
- data: filteredData // 필터링된 데이터만 다운로드 |
|
| 223 |
- }); |
|
| 224 |
-} |
|
| 225 | 292 |
|
| 226 | 293 |
/** |
| 227 | 294 |
* @ 예약 취소 |
... | ... | @@ -285,75 +352,235 @@ |
| 285 | 352 |
} |
| 286 | 353 |
|
| 287 | 354 |
} |
| 288 |
- |
|
| 355 |
+ |
|
| 289 | 356 |
/** |
| 290 | 357 |
* @문자 재전송 |
| 291 | 358 |
*/ |
| 292 |
-function fnMjMsgReSendAll(msgGroupId |
|
| 293 |
- , replaceCnt, electionCnt, advertisementCnt |
|
| 294 |
- ) {
|
|
| 295 |
- |
|
| 296 |
- |
|
| 359 |
+function fnMjMsgReSendAll(msgGroupId) {
|
|
| 360 |
+ // 치환 여부 체크 |
|
| 361 |
+ var replaceYn = fn_getReplaceChk(); |
|
| 362 |
+ // 문자 종류 (일반:N, 광고:A, 선거:C, 관리자:S) |
|
| 363 |
+ var msgKind = $('#msgKind').val();
|
|
| 297 | 364 |
|
| 298 | 365 |
var form = document.reSendAllForm; |
| 299 | 366 |
form.msgResendAllFlag.value = "Y"; |
| 300 | 367 |
form.msgResendAllGroupId.value = msgGroupId; |
| 301 | 368 |
|
| 302 |
- if (replaceCnt > 0) {
|
|
| 303 |
- if (confirm("특정문구 일괄변환 문자(치환문자)의 경우 문자내용은 재전송할 수 없고 받는 사람 목록만 불러올 수 있습니다.\n받는사람 목록을 불러올까요?")) {
|
|
| 304 |
- // 광고문자 |
|
| 305 |
- form.msgResendAllReplaceYn.value = "Y"; |
|
| 306 |
- if (electionCnt > 0) {
|
|
| 307 |
- form.action="/web/mjon/msgcampain/selectMsgDataView.do"; |
|
| 308 |
- } |
|
| 309 |
- else {
|
|
| 310 |
- if (advertisementCnt > 0) {
|
|
| 311 |
- // 광고문자 |
|
| 312 |
- form.msgResendAllAdvertiseYn.value = "Y"; |
|
| 313 |
- form.action="/web/mjon/msgdata/excel/selectMsgExcelDataView.do"; |
|
| 314 |
- } |
|
| 315 |
- else |
|
| 316 |
- {
|
|
| 317 |
- form.action="/web/mjon/msgdata/selectMsgDataView.do"; |
|
| 318 |
- } |
|
| 319 |
- } |
|
| 320 |
- form.submit(); |
|
| 321 |
- } |
|
| 369 |
+ // 치환문자 포함 여부에 따른 분기 |
|
| 370 |
+ var msg = ""; |
|
| 371 |
+ if (replaceYn) {
|
|
| 372 |
+ msg = "문자 내용에 포함된 특정 문구가 변환되지 않은 상태([*이름*],[*1*] 등)로 표기됩니다.\n문자내용, 받는 사람 목록 확인 후 발송해주세요"; |
|
| 373 |
+// form.msgResendAllReplaceYn.value = "Y"; |
|
| 374 |
+ } else {
|
|
| 375 |
+ var title = (msgKind == 'C') ? "선거문자발송" : "문자발송"; |
|
| 376 |
+ msg = title + " 화면으로 이동합니다.\n문자내용, 받는 사람 목록 확인 후 발송해주세요."; |
|
| 322 | 377 |
} |
| 323 |
- else {
|
|
| 324 |
- var title = ""; |
|
| 325 |
- if (electionCnt > 0) {
|
|
| 326 |
- title = "선거문자발송"; |
|
| 327 |
- } |
|
| 328 |
- else {
|
|
| 329 |
- title = "문자발송"; |
|
| 330 |
- } |
|
| 331 |
- |
|
| 332 |
- if (confirm(title + " 화면으로 이동합니다.\n문자내용, 받는 사람 목록 확인후 발송해주세요.")) {
|
|
| 333 |
- if (electionCnt > 0) {
|
|
| 334 |
- form.action="/web/mjon/msgcampain/selectMsgDataView.do"; |
|
| 335 |
- } |
|
| 336 |
- else {
|
|
| 337 |
- if (advertisementCnt > 0) {
|
|
| 338 |
- // 광고문자 |
|
| 339 |
- form.msgResendAllAdvertiseYn.value = "Y"; |
|
| 340 |
- form.action="/web/mjon/msgdata/excel/selectMsgExcelDataView.do"; |
|
| 341 |
- } |
|
| 342 |
- else |
|
| 343 |
- {
|
|
| 344 |
- form.action="/web/mjon/msgdata/selectMsgDataView.do"; |
|
| 345 |
- } |
|
| 346 |
- } |
|
| 347 |
- form.submit(); |
|
| 348 |
- } |
|
| 378 |
+ |
|
| 379 |
+ if (!confirm(msg)) {
|
|
| 380 |
+ return; |
|
| 381 |
+ } |
|
| 382 |
+ |
|
| 383 |
+ // msgKind에 따른 action 설정 |
|
| 384 |
+ form.action = getMsgActionUrl(msgKind); |
|
| 385 |
+ if (msgKind === 'A') {
|
|
| 386 |
+ form.msgResendAllAdvertiseYn.value = "Y"; // 광고문자 설정 |
|
| 387 |
+ } |
|
| 388 |
+ |
|
| 389 |
+ form.submit(); |
|
| 390 |
+} |
|
| 391 |
+ |
|
| 392 |
+function fn_getReplaceChk(){
|
|
| 393 |
+ // 체크할 패턴 목록 |
|
| 394 |
+ var patterns = [/\[\*이름\*\]/, /\[\*1\*\]/, /\[\*2\*\]/, /\[\*3\*\]/, /\[\*4\*\]/]; |
|
| 395 |
+ |
|
| 396 |
+ // 대상 요소의 텍스트 가져오기 |
|
| 397 |
+ var text = $("#smsTxt").text();
|
|
| 398 |
+ |
|
| 399 |
+ // 패턴이 포함되어 있는지 확인 |
|
| 400 |
+ var found = patterns.some(function(pattern) {
|
|
| 401 |
+ return pattern.test(text); |
|
| 402 |
+ }); |
|
| 403 |
+ |
|
| 404 |
+ return found; |
|
| 405 |
+} |
|
| 406 |
+ |
|
| 407 |
+/** |
|
| 408 |
+ * msgKind 값에 따른 action URL 반환 |
|
| 409 |
+ */ |
|
| 410 |
+function getMsgActionUrl(msgKind) {
|
|
| 411 |
+ switch (msgKind) {
|
|
| 412 |
+ case 'C': |
|
| 413 |
+ return "/web/mjon/msgcampain/selectMsgDataView.do"; |
|
| 414 |
+ case 'A': |
|
| 415 |
+ return "/web/mjon/msgdata/excel/selectMsgExcelDataView.do"; |
|
| 416 |
+ default: |
|
| 417 |
+ return "/web/mjon/msgdata/selectMsgDataView.do"; |
|
| 418 |
+ } |
|
| 419 |
+} |
|
| 420 |
+ |
|
| 421 |
+function fn_rowBtnSH(tabText){
|
|
| 422 |
+ var $addReg = $('#addReg');
|
|
| 423 |
+ var $addRemove = $('#addRemove');
|
|
| 424 |
+ // addReg 주소록 등록 |
|
| 425 |
+ // addRemove 주소록 삭제 |
|
| 426 |
+ if(tabText == '전체' |
|
| 427 |
+ || tabText == '성공'){
|
|
| 428 |
+ $addReg.show(); |
|
| 429 |
+ $addRemove.hide(); |
|
| 430 |
+ }else if(tabText == '대기'){
|
|
| 431 |
+ $addReg.hide(); |
|
| 432 |
+ $addRemove.hide(); |
|
| 433 |
+ }else if(tabText == '실패' ){
|
|
| 434 |
+ $addReg.hide(); |
|
| 435 |
+ $addRemove.show(); |
|
| 349 | 436 |
} |
| 350 | 437 |
} |
| 351 | 438 |
|
| 352 | 439 |
|
| 440 |
+function fnAddAddrNo(){
|
|
| 441 |
+ |
|
| 442 |
+ |
|
| 443 |
+ let url = "/web/mjon/addr/insertByAddrGrpDataAndAddrDataAjax.do"; |
|
| 444 |
+ |
|
| 445 |
+ |
|
| 446 |
+ // 필터링된 데이터 가져오기 (탭 필터 적용) |
|
| 447 |
+ let filteredData = getFilteredDataByTab(); |
|
| 448 |
+ |
|
| 449 |
+ console.log('filteredData : ', filteredData)
|
|
| 450 |
+ |
|
| 451 |
+ // phone 필드 데이터만 추출 |
|
| 452 |
+ let addrPhones = filteredData.map(row => row.phone); |
|
| 453 |
+ console.log('addrPhones : ', addrPhones)
|
|
| 454 |
+ |
|
| 455 |
+ if(addrPhones.length < 1){
|
|
| 456 |
+ alert('해당 탭에 데이터가 없습니다.');
|
|
| 457 |
+ return false; |
|
| 458 |
+ } |
|
| 459 |
+ |
|
| 460 |
+ // 주소록 그룹명 가져오기 |
|
| 461 |
+ let addrGrpNm = $('#grpNm').val();
|
|
| 462 |
+ |
|
| 463 |
+ // 데이터 객체 생성 |
|
| 464 |
+ let data = {
|
|
| 465 |
+ addrPhones: addrPhones, |
|
| 466 |
+ addrGrpNm: addrGrpNm |
|
| 467 |
+ }; |
|
| 468 |
+ |
|
| 469 |
+ if(!confirm("연락처 정보를 주소록에 등록 하시겠습니까?")){
|
|
| 470 |
+ return false; |
|
| 471 |
+ } |
|
| 472 |
+ |
|
| 473 |
+ |
|
| 474 |
+ $.ajax({
|
|
| 475 |
+ type: "POST", |
|
| 476 |
+ url: url, |
|
| 477 |
+ data: JSON.stringify(data), |
|
| 478 |
+ dataType: "json", |
|
| 479 |
+ contentType: "application/json", |
|
| 480 |
+ async: false, |
|
| 481 |
+ processData: false, |
|
| 482 |
+ success: function(data) {
|
|
| 483 |
+ |
|
| 484 |
+ if(data.status == 'BAD_REQUEST'){
|
|
| 485 |
+ alert(data.message); |
|
| 486 |
+ return false; |
|
| 487 |
+ } |
|
| 488 |
+ |
|
| 489 |
+ |
|
| 490 |
+ // 성공 메세지 |
|
| 491 |
+ alert(data.message); |
|
| 492 |
+ // 그룹등록 팝업 닫기 |
|
| 493 |
+ $('.grpClose').click();
|
|
| 494 |
+ |
|
| 495 |
+ }, |
|
| 496 |
+ error: function(error) {
|
|
| 497 |
+ alert("오류가 발생하였습니다.")
|
|
| 498 |
+ console.error("에러 발생:", error);
|
|
| 499 |
+ } |
|
| 500 |
+ }); |
|
| 501 |
+} |
|
| 502 |
+ |
|
| 503 |
+function fnDelAddrNo(){
|
|
| 504 |
+ |
|
| 505 |
+ |
|
| 506 |
+ let url = "/web/mjon/addr/deleteAddrNoDataAjax.do"; |
|
| 507 |
+ |
|
| 508 |
+ |
|
| 509 |
+ // 필터링된 데이터 가져오기 (탭 필터 적용) |
|
| 510 |
+ let filteredData = getFilteredDataByTab(); |
|
| 511 |
+ |
|
| 512 |
+ console.log('filteredData : ', filteredData)
|
|
| 513 |
+ |
|
| 514 |
+ // phone 필드 데이터만 추출 |
|
| 515 |
+ let addrPhones = filteredData.map(row => row.phone); |
|
| 516 |
+ console.log('addrPhones : ', addrPhones)
|
|
| 517 |
+ |
|
| 518 |
+ if(addrPhones.length < 1){
|
|
| 519 |
+ alert('주소록에 살제할 연락처가 없습니다.');
|
|
| 520 |
+ return false; |
|
| 521 |
+ } |
|
| 522 |
+ |
|
| 523 |
+ // 데이터 객체 생성 |
|
| 524 |
+ let data = {
|
|
| 525 |
+ addrPhones: addrPhones |
|
| 526 |
+ }; |
|
| 527 |
+ |
|
| 528 |
+ let selectedTab = $(".tabType3 .tab.active button").text().trim();
|
|
| 529 |
+ if(!confirm(selectedTab+" 명단의 번호를 주소록에서 삭제하시겠습니까?")){
|
|
| 530 |
+ return false; |
|
| 531 |
+ } |
|
| 532 |
+ |
|
| 533 |
+ $.ajax({
|
|
| 534 |
+ type: "POST", |
|
| 535 |
+ url: url, |
|
| 536 |
+ data: JSON.stringify(data), |
|
| 537 |
+ dataType: "json", |
|
| 538 |
+ contentType: "application/json", |
|
| 539 |
+ async: false, |
|
| 540 |
+ processData: false, |
|
| 541 |
+ success: function(data) {
|
|
| 542 |
+ |
|
| 543 |
+ if(data.status == 'BAD_REQUEST'){
|
|
| 544 |
+ alert(data.message); |
|
| 545 |
+ return false; |
|
| 546 |
+ } |
|
| 547 |
+ |
|
| 548 |
+ |
|
| 549 |
+ // 성공 메세지 |
|
| 550 |
+ alert(data.message); |
|
| 551 |
+ |
|
| 552 |
+ }, |
|
| 553 |
+ error: function(error) {
|
|
| 554 |
+ alert("오류가 발생하였습니다.")
|
|
| 555 |
+ console.error("에러 발생:", error);
|
|
| 556 |
+ } |
|
| 557 |
+ }); |
|
| 558 |
+} |
|
| 559 |
+/** |
|
| 560 |
+ * @description 현재 선택된 탭(`result` 필터) 기준으로 데이터를 필터링 |
|
| 561 |
+ * @returns {Array} 필터링된 데이터 리스트
|
|
| 562 |
+ */ |
|
| 563 |
+function getFilteredDataByTab() {
|
|
| 564 |
+ // 현재 적용된 모든 필터 가져오기 |
|
| 565 |
+ let filters = $tbDtailList.getFilters(); |
|
| 566 |
+ |
|
| 567 |
+ // 현재 모든 데이터 가져오기 (전체 데이터에서 필터 적용) |
|
| 568 |
+ let allData = $tbDtailList.getData(); |
|
| 569 |
+ |
|
| 570 |
+ // 현재 적용된 필터에서 "result" 필터만 찾기 |
|
| 571 |
+ let tabFilter = filters.find(filter => filter.field === "result"); |
|
| 572 |
+ |
|
| 573 |
+ // 탭 필터 적용하여 데이터 필터링 (수신번호 필터는 무시) |
|
| 574 |
+ return allData.filter(row => tabFilter ? row.result.includes(tabFilter.value) : true); |
|
| 575 |
+} |
|
| 576 |
+ |
|
| 353 | 577 |
</script> |
| 354 | 578 |
<div class="inner"> |
| 355 |
- <input id="msgGroupId" name="msgGroupId" type="hidden" value="${result.msgGroupId}"/>
|
|
| 356 |
- <!-- send top --> |
|
| 579 |
+ <!-- js 참고용 hidden --> |
|
| 580 |
+ <input id="msgGroupId" type="hidden" value="${result.msgGroupId}"/>
|
|
| 581 |
+ <input id="msgKind" type="hidden" value="${result.msgKind}"/> <!-- 문자종류(일반:N, 광고:A, 선거:C, 관리자:S) -->
|
|
| 582 |
+ |
|
| 583 |
+ <!-- send top --> |
|
| 357 | 584 |
<div class="send_top"> |
| 358 | 585 |
<!-- 결제관리 - 요금 사용내역 --> |
| 359 | 586 |
<div class="rev_admin_cont serv_content current"> |
... | ... | @@ -421,7 +648,8 @@ |
| 421 | 648 |
<div class="di_info"> |
| 422 | 649 |
<button class="di">분할</button> |
| 423 | 650 |
<div class="di_hover_layer"> |
| 424 |
- <strong>100,000건</strong>씩 <strong>35분</strong> 간격 |
|
| 651 |
+ <strong>${result.divideText }</strong>
|
|
| 652 |
+<!-- <strong>100,000건</strong>씩 <strong>35분</strong> 간격 --> |
|
| 425 | 653 |
</div> |
| 426 | 654 |
</div> |
| 427 | 655 |
</c:if> |
... | ... | @@ -562,7 +790,7 @@ |
| 562 | 790 |
<c:if test="${result.msgKind eq 'A' }" >
|
| 563 | 791 |
<p class="ad_tit">(광고)</p> |
| 564 | 792 |
</c:if> |
| 565 |
- <p class="none_txt"><c:out value="${result.smsTxt }" /></p>
|
|
| 793 |
+ <p class="none_txt" id="smsTxt"><c:out value="${result.smsTxt }" /></p>
|
|
| 566 | 794 |
<p class="realtime"></p> |
| 567 | 795 |
<c:if test="${result.msgKind eq 'A' }" >
|
| 568 | 796 |
<p class="deny_receipt">무료 거부 080-0000-0000</p> |
... | ... | @@ -596,31 +824,28 @@ |
| 596 | 824 |
<div class="popup-com ad_layer rev_popup04" tabindex="0" data-tooltip-con="rev_popup04" data-focus="rev_popup04" data-focus-prev="rev_popup04-close" style="width:530px;"> |
| 597 | 825 |
<div class="popup_heading"> |
| 598 | 826 |
<p>발송대상 리스트</p> |
| 599 |
- <button type="button" class="tooltip-close" data-focus="rev_popup04-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button> |
|
| 827 |
+ <button type="button" class="tooltip-close listClose" data-focus="rev_popup04-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button> |
|
| 600 | 828 |
</div> |
| 601 | 829 |
<div class="layer_in"> |
| 602 | 830 |
|
| 603 |
- <div class="gorup_join_cont" style="margin:-15px 0 0 0;"> |
|
| 604 |
- <div class="group_input"> |
|
| 605 |
- <div class="input_left">발신번호</div> |
|
| 606 |
- <div class="input_right type1"><c:out value="${result.callFrom }" /></div>
|
|
| 607 |
- </div> |
|
| 608 |
- </div> |
|
| 831 |
+<!-- <div class="gorup_join_cont" style="margin:-15px 0 0 0;"> --> |
|
| 832 |
+<!-- <div class="group_input"> --> |
|
| 833 |
+<!-- <div class="input_left">발신번호</div> --> |
|
| 834 |
+<%-- <div class="input_right type1"><c:out value="${result.callFrom }" /></div> --%>
|
|
| 835 |
+<!-- </div> --> |
|
| 836 |
+<!-- </div> --> |
|
| 609 | 837 |
|
| 610 |
- <div class="popup_search_type1"> |
|
| 838 |
+ <div class="popup_search_type2"> |
|
| 611 | 839 |
<label for="" class="label">검색종류 선택</label> |
| 612 |
- <select id="searchColumn" class="selType1 select_btn"> |
|
| 613 |
- <option value="phone">수신번호</option> |
|
| 614 |
- <option value="result">상세결과</option> |
|
| 615 |
- </select> |
|
| 840 |
+ <div class="title">수신번호</div> |
|
| 616 | 841 |
<label for="" class="label">검색어입력</label> |
| 617 |
- <input type="text" class="send_text" id="searchInput" name="" value="" placeholder="3자 이상 입력하세요." onfocus="this.placeholder=''" onblur="this.placeholder='3자 이상 입력하세요.'"> |
|
| 842 |
+ <input type="text" class="send_text" id="searchInput" placeholder="3자 이상 입력하세요." onfocus="this.placeholder=''" onblur="this.placeholder='3자 이상 입력하세요.'"> |
|
| 618 | 843 |
<button type="button" id="searchBtn" class="btnType btnType2" style="width:63px; margin:0;">검색</button> |
| 619 | 844 |
</div> |
| 620 | 845 |
|
| 621 | 846 |
<div class="list_tab_wrap2 type4"> |
| 622 | 847 |
<ul class="tabType3" id="tabType" name="tabType"> |
| 623 |
- <li class="tab active"><button type="button" title="선택됨">전체</button></li> |
|
| 848 |
+ <li class="tab active"><button type="button" id="initTab" title="선택됨">전체</button></li> |
|
| 624 | 849 |
<li class="tab"><button type="button">대기</button></li> |
| 625 | 850 |
<li class="tab"><button type="button">성공</button></li> |
| 626 | 851 |
<li class="tab"><button type="button">실패</button></li> |
... | ... | @@ -634,18 +859,44 @@ |
| 634 | 859 |
<div class="table_btn clearfix"> |
| 635 | 860 |
<div class="table_btn_left"> |
| 636 | 861 |
<button type="button" onclick="fn_downloadFilteredExcel()" class="excel_btn btnType"><i class="downroad"></i>엑셀 다운로드</button> |
| 637 |
- <button type="button" data-tooltip="rev_popup02" class="btnType btnType14"><i class="add_img"></i>주소록 등록</button> |
|
| 638 |
- <button type="button" class="btnType btnType15"><i class="remove_img"></i>주소록에서 번호 삭제</button> |
|
| 862 |
+ <button type="button" id="addReg" data-tooltip="rev_popup02" class="btnType btnType14"><i class="add_img"></i>주소록 등록</button> |
|
| 863 |
+ <button type="button" onclick="fnDelAddrNo()" id="addRemove" class="btnType btnType15"><i class="remove_img"></i>주소록에서 번호 삭제</button> |
|
| 639 | 864 |
</div> |
| 640 | 865 |
</div> |
| 641 | 866 |
</div> |
| 642 | 867 |
<div class="popup_btn_wrap2" style="margin: -40px auto 30px auto;"> |
| 643 |
- <button type="button" class="tooltip-close" data-focus="adr_popup01-close" data-focus-next="popup02">닫기</button> |
|
| 868 |
+ <button type="button" class="tooltip-close listClose" data-focus="adr_popup01-close" data-focus-next="popup02">닫기</button> |
|
| 644 | 869 |
</div> |
| 645 | 870 |
|
| 646 | 871 |
</div> |
| 647 | 872 |
</div> |
| 648 | 873 |
<!-- //발송대상 리스트 안내 팝업 --> |
| 874 |
+ |
|
| 875 |
+ <div class="tooltip-wrap"> |
|
| 876 |
+ <div class="popup-com adr_layer rev_popup02" tabindex="0" data-tooltip-con="rev_popup02" data-focus="rev_popup02" data-focus-prev="rev_popup02-close" style="width: 500px;"> |
|
| 877 |
+ <div class="popup_heading"> |
|
| 878 |
+ <p>그룹등록</p> |
|
| 879 |
+ <button type="button" class="tooltip-close grpClose" data-focus="rev_popup02-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button> |
|
| 880 |
+ </div> |
|
| 881 |
+ <div class="layer_in"> |
|
| 882 |
+ <div class="gorup_join_cont"> |
|
| 883 |
+ <p class="adr_pop_title">선택된 발송내역 전화번호를 그룹으로 등록합니다.</p> |
|
| 884 |
+ <div class="group_input" style="margin-top: 0;"> |
|
| 885 |
+ <div class="input_left">그룹이름</div> |
|
| 886 |
+ <div class="input_right"> |
|
| 887 |
+ <label for="grpNm" class="label">새 그룹명 입력</label> |
|
| 888 |
+ <input type="text" id="grpNm" name="grpNm" placeholder="새 그룹명 입력" onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명 입력'" class="inputLight"> |
|
| 889 |
+ </div> |
|
| 890 |
+ </div> |
|
| 891 |
+ <div class="popup_btn_wrap2"> |
|
| 892 |
+ <button type="button" onclick="javascript:fnAddAddrNo(); return false;">저장</button> |
|
| 893 |
+ <button type="button" class="tooltip-close grpClose" data-focus="rev_popup02-close" data-focus-next="rev_popup02">취소</button> |
|
| 894 |
+ </div> |
|
| 895 |
+ </div> |
|
| 896 |
+ </div> |
|
| 897 |
+ </div> |
|
| 898 |
+ </div> |
|
| 899 |
+ |
|
| 649 | 900 |
|
| 650 | 901 |
<!-- 이전 리스트 상태(검색조건, 페이징) 그대로 가기 위한 form --> |
| 651 | 902 |
<form id="goList" name="goList" method="post" action="/web/mjon/msgsent/selectMsgSentView.do"> |
... | ... | @@ -658,6 +909,7 @@ |
| 658 | 909 |
<input type="hidden" name="searchEndDate" value="<c:out value='${searchVO.searchEndDate }' />" />
|
| 659 | 910 |
<input type="hidden" name="searchCondition" value="<c:out value='${searchVO.searchCondition }' />" />
|
| 660 | 911 |
<input type="hidden" name="searchKeyword" value="<c:out value='${searchVO.searchKeyword }' />" />
|
| 912 |
+ <input type="hidden" name="pageUnit" value="<c:out value='${searchVO.pageUnit }' />" />
|
|
| 661 | 913 |
</form> |
| 662 | 914 |
|
| 663 | 915 |
<!-- 예약 취소 --> |
--- src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgsent/MsgSentView.jsp
... | ... | @@ -844,6 +844,7 @@ |
| 844 | 844 |
<form id="searchForm" name="searchForm" method="post"> |
| 845 | 845 |
<!-- <input type="hidden" id="pageIndex" name="pageIndex" value="1"/> --> |
| 846 | 846 |
<input type="hidden" id="pageIndex" name="pageIndex" value="<c:out value="${searchVO.pageIndex}" />" />
|
| 847 |
+ <input type="hidden" id="pageUnit" name="pageUnit" value="<c:out value="${searchVO.pageUnit}" />" />
|
|
| 847 | 848 |
<input type="hidden" id="msgGroupIdList" name="msgGroupIdList" value=""/> |
| 848 | 849 |
<input type="hidden" id="msgGroupId" name="msgGroupId" value=""/> |
| 849 | 850 |
<input type="hidden" name="searchSortCnd" value="<c:out value="${searchVO.searchSortCnd}" />" />
|
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?