--- src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java
+++ src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java
... | ... | @@ -59,6 +59,7 @@ |
| 59 | 59 |
private String eachPrice; // sms 단가 |
| 60 | 60 |
private String smsPrice; // sms 단가 |
| 61 | 61 |
private String mmsPrice; // mms 단가 |
| 62 |
+ private String picturePrice; // mms 단가 |
|
| 62 | 63 |
private String totPrice; // mms 단가 |
| 63 | 64 |
private String befCash; // mms 단가 |
| 64 | 65 |
private String befPoint; // mms 단가 |
... | ... | @@ -68,6 +69,8 @@ |
| 68 | 69 |
private String atDelayYn; // 카카오 알림톡 단가 |
| 69 | 70 |
private String bizKakaoResendOrgnlTxt; // 카카오 알림톡 단가 |
| 70 | 71 |
private String bizKakaoResendType; // 카카오 알림톡 단가 |
| 72 |
+ private String filePath1; // 대체문자 이미지 |
|
| 73 |
+ private String fileCnt; // 파일 카운트 |
|
| 71 | 74 |
|
| 72 | 75 |
|
| 73 | 76 |
|
... | ... | @@ -109,6 +112,7 @@ |
| 109 | 112 |
"\n , atDelayYn=[" + atDelayYn + "]" + |
| 110 | 113 |
"\n , bizKakaoResendOrgnlTxt=[" + bizKakaoResendOrgnlTxt + "]" + |
| 111 | 114 |
"\n , bizKakaoResendType=[" + bizKakaoResendType + "]" + |
| 115 |
+ "\n , filePath1=[" + filePath1 + "]" + |
|
| 112 | 116 |
"\n ]"; |
| 113 | 117 |
} |
| 114 | 118 |
|
--- src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java
+++ src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java
... | ... | @@ -34,6 +34,7 @@ |
| 34 | 34 |
import itn.let.mail.service.StatusResponse; |
| 35 | 35 |
import itn.let.mjo.mjocommon.MjonCommon; |
| 36 | 36 |
import itn.let.mjo.msg.service.MjonMsgVO; |
| 37 |
+import itn.let.mjo.msg.service.impl.MjonMsgDAO; |
|
| 37 | 38 |
import itn.let.mjo.msgdata.service.MjonMsgDataService; |
| 38 | 39 |
import itn.let.mjo.spammsg.web.ComGetSpamStringParser; |
| 39 | 40 |
import itn.let.module.base.PriceAndPoint; |
... | ... | @@ -53,6 +54,9 @@ |
| 53 | 54 |
|
| 54 | 55 |
@Resource(name = "MjonMsgDataService") |
| 55 | 56 |
private MjonMsgDataService mjonMsgDataService; |
| 57 |
+ |
|
| 58 |
+ @Resource(name = "mjonMsgDAO") |
|
| 59 |
+ private MjonMsgDAO mjonMsgDAO; |
|
| 56 | 60 |
|
| 57 | 61 |
@Autowired |
| 58 | 62 |
KakaoApiTemplate kakaoApiTemplate; |
... | ... | @@ -367,15 +371,25 @@ |
| 367 | 371 |
Float kakaoFtPrice = |
| 368 | 372 |
getValidPrice(kakaoMemberFtPrice, kakaoSysJoinFtPrice); |
| 369 | 373 |
|
| 370 |
-// imageType |
|
| 371 |
- // 친구통 금액 |
|
| 372 |
- |
|
| 373 | 374 |
// 대체문자가 있을경우 사용 |
| 374 | 375 |
float shortPrice = getValidPrice(mberManageVO.getShortPrice(), sysJoinSetVO.getShortPrice()); |
| 375 | 376 |
float longPrice = getValidPrice(mberManageVO.getLongPrice(), sysJoinSetVO.getLongPrice()); |
| 376 |
- String shortPStr = Float.toString(shortPrice); |
|
| 377 |
- String mmsPStr = Float.toString(longPrice); |
|
| 377 |
+ float picturePrice = getValidPrice(mberManageVO.getPicturePrice(), sysJoinSetVO.getPicturePrice()); |
|
| 378 |
+// String shortPStr = Float.toString(shortPrice); |
|
| 379 |
+// String mmsPStr = Float.toString(longPrice); |
|
| 380 |
+// String imgPrice = Float.toString(picturePrice); |
|
| 378 | 381 |
|
| 382 |
+ |
|
| 383 |
+ String imgFilePath = ""; |
|
| 384 |
+ if(StringUtils.isNotEmpty(kakaoVO.getAtchFileId()) && |
|
| 385 |
+ ("I".equals(imageType) || "W".equals(imageType))) {
|
|
| 386 |
+ |
|
| 387 |
+ |
|
| 388 |
+ imgFilePath = mjonMsgDAO.selectPhotoImgFileRealPath(kakaoVO.getAtchFileId()); |
|
| 389 |
+ |
|
| 390 |
+ } |
|
| 391 |
+ |
|
| 392 |
+ |
|
| 379 | 393 |
|
| 380 | 394 |
/** @jsonStr 필요유무 */ |
| 381 | 395 |
boolean hasButtons = CollectionUtils.isNotEmpty(kakaoVO.getButtonVOList()); |
... | ... | @@ -390,8 +404,9 @@ |
| 390 | 404 |
|
| 391 | 405 |
KakaoSendAdvcVO sendVO = createFTSendVO(kakaoVO, calendar); |
| 392 | 406 |
// 공통 가격 설정 |
| 393 |
- sendVO.setSmsPrice(shortPStr); |
|
| 394 |
- sendVO.setMmsPrice(mmsPStr); |
|
| 407 |
+ sendVO.setSmsPrice(Float.toString(shortPrice)); |
|
| 408 |
+ sendVO.setMmsPrice(Float.toString(longPrice)); |
|
| 409 |
+ sendVO.setPicturePrice(Float.toString(picturePrice)); |
|
| 395 | 410 |
|
| 396 | 411 |
sendVO.setCallTo(mjonFTSendVO.getPhone()); |
| 397 | 412 |
sendVO.setMsgId(idList.get(i)); |
... | ... | @@ -443,17 +458,39 @@ |
| 443 | 458 |
//대체문자가 있으면 |
| 444 | 459 |
// Step 1-4: 실패 대체 문자 치환데이터 설정 |
| 445 | 460 |
if(StringUtils.isNotEmpty(subMsgTxtTemp)) { // 대체문자가 있나?
|
| 446 |
- int smsTxtByte = mjonCommon.getSmsTxtBytes(subMsgTxtTemp); |
|
| 447 |
- String sendType = getMsgType(smsTxtByte); |
|
| 448 |
- sendVO.setSubMsgType(sendType); |
|
| 461 |
+ |
|
| 462 |
+ String sendType = "MMS"; |
|
| 463 |
+ if(StringUtils.isEmpty(imgFilePath)) {
|
|
| 464 |
+ int smsTxtByte = mjonCommon.getSmsTxtBytes(subMsgTxtTemp); // 문자 byte 수 계산 |
|
| 465 |
+ sendType = getMsgType(smsTxtByte); // 문자 타입(SHORT / MMS) 판별 |
|
| 466 |
+ } |
|
| 467 |
+ sendVO.setSubMsgType(sendType); // 실패 대체 문자 타입 설정 |
|
| 449 | 468 |
|
| 450 | 469 |
if ("INVALID".equals(sendType)) {
|
| 451 |
- statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.");return kakaoSendAdvcListVO; |
|
| 470 |
+ // INVALID 타입이면 길이 초과 에러 응답 후 리턴 |
|
| 471 |
+ statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다."); |
|
| 472 |
+ return kakaoSendAdvcListVO; |
|
| 452 | 473 |
} |
| 453 |
- |
|
| 454 |
- boolean isMms = "MMS".equals(sendType); |
|
| 455 |
- sendVO.setEachPrice(isMms ? mmsPStr : shortPStr); |
|
| 474 |
+ |
|
| 475 |
+ float chosenPrice = 0f; |
|
| 476 |
+ |
|
| 477 |
+ if(StringUtils.isNotEmpty(imgFilePath)) {
|
|
| 478 |
+ chosenPrice = Math.max(picturePrice, kakaoFtPrice); |
|
| 479 |
+ sendVO.setFilePath1(imgFilePath); |
|
| 480 |
+ sendVO.setFileCnt("1");
|
|
| 481 |
+ |
|
| 482 |
+ }else if ("MMS".equals(sendType)) {
|
|
| 483 |
+ // MMS 타입일 경우: longPrice(장문 가격)와 카카오톡 단가 중 큰 값을 선택 |
|
| 484 |
+ chosenPrice = Math.max(longPrice, kakaoFtPrice); |
|
| 485 |
+ } else {
|
|
| 486 |
+ // SHORT 타입일 경우: shortPrice(단문 가격)와 카카오톡 단가 중 큰 값을 선택 |
|
| 487 |
+ chosenPrice = Math.max(shortPrice, kakaoFtPrice); |
|
| 488 |
+ } |
|
| 489 |
+ sendVO.setEachPrice(Float.toString(chosenPrice)); // 선택된 단가 설정 |
|
| 490 |
+ |
|
| 491 |
+ |
|
| 456 | 492 |
}else {
|
| 493 |
+ // 대체문자가 없으면 카카오톡 단가 그대로 사용 |
|
| 457 | 494 |
sendVO.setEachPrice( Float.toString(kakaoFtPrice) ); |
| 458 | 495 |
} |
| 459 | 496 |
|
... | ... | @@ -990,7 +1027,9 @@ |
| 990 | 1027 |
// 사용자 개인 단가가 없으면 시스템 단가로 |
| 991 | 1028 |
if(mberManageVO.getLongPrice() == 0.0f) |
| 992 | 1029 |
mberManageVO.setLongPrice(sysJoinSetVO.getLongPrice()); |
| 993 |
- |
|
| 1030 |
+ |
|
| 1031 |
+ if(mberManageVO.getPicturePrice() == 0.0f) |
|
| 1032 |
+ mberManageVO.setPicturePrice(sysJoinSetVO.getPicturePrice()); |
|
| 994 | 1033 |
|
| 995 | 1034 |
return mberManageVO; |
| 996 | 1035 |
} |
--- src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java
+++ src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java
... | ... | @@ -260,6 +260,9 @@ |
| 260 | 260 |
private String msgResendAllGroupId; |
| 261 | 261 |
private String msgResendAllTmpKey; |
| 262 | 262 |
private String msgResendAllYellowId; |
| 263 |
+ |
|
| 264 |
+ private String bizKakaoResendType; |
|
| 265 |
+ private String fileCnt; |
|
| 263 | 266 |
|
| 264 | 267 |
private List<Map<String, String>> varListMap; |
| 265 | 268 |
|
--- src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiImageUpload.java
+++ src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiImageUpload.java
... | ... | @@ -5,8 +5,10 @@ |
| 5 | 5 |
import java.io.File; |
| 6 | 6 |
import java.io.FileInputStream; |
| 7 | 7 |
import java.io.InputStream; |
| 8 |
+import java.text.SimpleDateFormat; |
|
| 8 | 9 |
import java.time.LocalDateTime; |
| 9 | 10 |
import java.util.ArrayList; |
| 11 |
+import java.util.Date; |
|
| 10 | 12 |
import java.util.HashMap; |
| 11 | 13 |
import java.util.List; |
| 12 | 14 |
import java.util.ListIterator; |
... | ... | @@ -38,6 +40,7 @@ |
| 38 | 40 |
import org.springframework.web.multipart.MultipartFile; |
| 39 | 41 |
|
| 40 | 42 |
import egovframework.rte.fdl.property.EgovPropertyService; |
| 43 |
+import itn.com.cmm.service.EgovFileMngService; |
|
| 41 | 44 |
import itn.com.cmm.service.EgovFileMngUtil; |
| 42 | 45 |
import itn.com.cmm.service.FileVO; |
| 43 | 46 |
import itn.let.kakao.kakaoComm.KakaoReturnVO; |
... | ... | @@ -64,7 +67,17 @@ |
| 64 | 67 |
|
| 65 | 68 |
@Resource(name = "propertiesService") |
| 66 | 69 |
protected EgovPropertyService propertyService; |
| 67 |
- |
|
| 70 |
+ |
|
| 71 |
+ /** 첨부파일 저장경로 */ |
|
| 72 |
+ @Value("#{globalSettings['Globals.file.saveDir']}")
|
|
| 73 |
+ private String fileSaveDir; |
|
| 74 |
+ |
|
| 75 |
+ @Resource(name="EgovFileMngUtil") |
|
| 76 |
+ private EgovFileMngUtil fileUtil; |
|
| 77 |
+ |
|
| 78 |
+ |
|
| 79 |
+ @Resource(name="EgovFileMngService") |
|
| 80 |
+ private EgovFileMngService fileMngService; |
|
| 68 | 81 |
|
| 69 | 82 |
/** |
| 70 | 83 |
* @Method Name : kakaoApiImageUpload |
... | ... | @@ -293,118 +306,162 @@ |
| 293 | 306 |
* @param files |
| 294 | 307 |
* @param i |
| 295 | 308 |
* @return |
| 309 |
+ * @throws Exception |
|
| 296 | 310 |
* |
| 297 | 311 |
*/ |
| 298 |
- public StatusResponse kakaoApiImageUpload_advc(KakaoVO kakaoVO, Map<String, MultipartFile> files, int fileKeyParam) {
|
|
| 299 |
- try {
|
|
| 312 |
+ public StatusResponse kakaoApiImageUpload_advc(KakaoVO kakaoVO, Map<String, MultipartFile> files, int fileKeyParam) throws Exception {
|
|
| 313 |
+// try {
|
|
| 300 | 314 |
String storePathString = propertyService.getString("Globals.fileStorePath");
|
| 301 | 315 |
File saveFolder = new File(storePathString); |
| 302 | 316 |
if (!saveFolder.exists()) saveFolder.mkdirs(); |
| 303 | 317 |
|
| 304 |
- for (MultipartFile file : files.values()) {
|
|
| 305 |
- if (file.isEmpty()) continue; |
|
| 318 |
+// for (MultipartFile file : files.values()) {
|
|
| 319 |
+ MultipartFile file = files.values().stream().findFirst().orElse(null); |
|
| 320 |
+ if (file == null || file.isEmpty()) {
|
|
| 321 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "유효한 이미지 파일이 없습니다.", LocalDateTime.now()); |
|
| 322 |
+ } |
|
| 323 |
+ |
|
| 306 | 324 |
|
| 307 |
- String originalName = file.getOriginalFilename(); |
|
| 308 |
- if (originalName == null || originalName.isEmpty()) continue; |
|
| 325 |
+ String originalName = file.getOriginalFilename(); |
|
| 326 |
+ if (originalName == null || originalName.isEmpty()) {
|
|
| 327 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "파일명이 비어 있습니다.", LocalDateTime.now()); |
|
| 328 |
+ } |
|
| 329 |
+ |
|
| 330 |
+ String ext = FilenameUtils.getExtension(originalName).toLowerCase(); |
|
| 331 |
+ if (!ext.matches("jpg|jpeg|png")) {
|
|
| 332 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "지원하지 않는 이미지 형식입니다."); |
|
| 333 |
+ } |
|
| 309 | 334 |
|
| 310 |
- String ext = FilenameUtils.getExtension(originalName).toLowerCase(); |
|
| 311 |
- if (!ext.matches("jpg|jpeg|png")) {
|
|
| 312 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, "지원하지 않는 이미지 형식입니다."); |
|
| 335 |
+ long size = file.getSize(); |
|
| 336 |
+ if (size > 5 * 1024 * 1024) {
|
|
| 337 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "이미지 용량은 5MB 이내여야 합니다."); |
|
| 338 |
+ } |
|
| 339 |
+ |
|
| 340 |
+ BufferedImage image = ImageIO.read(file.getInputStream()); |
|
| 341 |
+ if (image == null) {
|
|
| 342 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "이미지를 읽을 수 없습니다."); |
|
| 343 |
+ } |
|
| 344 |
+ |
|
| 345 |
+ int width = image.getWidth(); |
|
| 346 |
+ int height = image.getHeight(); |
|
| 347 |
+ String type = kakaoVO.getImageType(); |
|
| 348 |
+ |
|
| 349 |
+ if ("W".equals(type)) {
|
|
| 350 |
+ if (width != 800 || height != 600) {
|
|
| 351 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "와이드 이미지는 800x600 사이즈만 허용됩니다."); |
|
| 313 | 352 |
} |
| 314 |
- |
|
| 315 |
- long size = file.getSize(); |
|
| 316 |
- if (size > 5 * 1024 * 1024) {
|
|
| 317 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, "이미지 용량은 5MB 이내여야 합니다."); |
|
| 318 |
- } |
|
| 319 |
- |
|
| 320 |
- BufferedImage image = ImageIO.read(file.getInputStream()); |
|
| 321 |
- if (image == null) {
|
|
| 322 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, "이미지를 읽을 수 없습니다."); |
|
| 323 |
- } |
|
| 324 |
- |
|
| 325 |
- int width = image.getWidth(); |
|
| 326 |
- int height = image.getHeight(); |
|
| 327 |
- String type = kakaoVO.getImageType(); |
|
| 328 |
- |
|
| 329 |
- if ("W".equals(type)) {
|
|
| 330 |
- if (width != 800 || height != 600) {
|
|
| 331 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, "와이드 이미지는 800x600 사이즈만 허용됩니다."); |
|
| 332 |
- } |
|
| 333 |
- } else {
|
|
| 334 |
- float ratio = width / (float) height; |
|
| 353 |
+ } else {
|
|
| 354 |
+ float ratio = width / (float) height; |
|
| 335 | 355 |
// log.info("width : [{}], ",width);
|
| 336 | 356 |
// log.info("height : [{}], ",height);
|
| 337 | 357 |
// log.info("ratio : [{}], ",ratio);
|
| 338 |
- if (width < 500 || ratio < 0.75 || ratio > 2.0) {
|
|
| 339 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, "일반 이미지는 가로 500px 이상, 비율 2:1 이상 또는 3:4 이하만 허용됩니다."); |
|
| 340 |
- } |
|
| 341 |
- } |
|
| 342 |
- |
|
| 343 |
- String newName = EgovStringUtil.getTimeStamp() + fileKeyParam; |
|
| 344 |
- String filePath = storePathString + File.separator + newName + "." + ext; |
|
| 345 |
- file.transferTo(new File(filePath)); |
|
| 346 |
- |
|
| 347 |
- // 카카오 API 호출 |
|
| 348 |
- CloseableHttpClient httpClient = HttpClients.createDefault(); |
|
| 349 |
- String apiUrl = mjonBizUrl + "/v3/kakao/image/upload"; |
|
| 350 |
- |
|
| 351 |
- HttpPost httpPost = new HttpPost(apiUrl); |
|
| 352 |
- /*HttpEntity httpEntity = MultipartEntityBuilder.create() |
|
| 353 |
- .addTextBody("bizId", mjonBizId)
|
|
| 354 |
- .addTextBody("apiKey", mjonBizKakaoApiKey)
|
|
| 355 |
- .addTextBody("imageType", kakaoVO.getImageType())
|
|
| 356 |
- .addTextBody("title", kakaoVO.getImgTitle())
|
|
| 357 |
- .addTextBody("link", kakaoVO.getImgLink())
|
|
| 358 |
- .addTextBody("senderKey", kakaoVO.getSenderKey())
|
|
| 359 |
- .addBinaryBody("image", new File(filePath), ContentType.MULTIPART_FORM_DATA, newName + "." + ext)
|
|
| 360 |
- .build(); |
|
| 361 |
- */ |
|
| 362 |
- |
|
| 363 |
- HttpEntity httpEntity = MultipartEntityBuilder.create() |
|
| 364 |
- .addTextBody("bizId", mjonBizId)
|
|
| 365 |
- .addTextBody("apiKey", mjonBizKakaoApiKey)
|
|
| 366 |
- .addTextBody("imageType", kakaoVO.getImageType())
|
|
| 367 |
- .addTextBody("title", originalName)
|
|
| 368 |
- .addTextBody("link", StringUtils.isEmpty(kakaoVO.getImgLink()) ? "https://" : kakaoVO.getImgLink())
|
|
| 369 |
- .addTextBody("senderKey", kakaoVO.getSenderKey())
|
|
| 370 |
- .addBinaryBody("image", new File(filePath), ContentType.MULTIPART_FORM_DATA, newName + "." + ext)
|
|
| 371 |
- .build(); |
|
| 372 |
- |
|
| 373 |
- httpPost.setEntity(httpEntity); |
|
| 374 |
- |
|
| 375 |
- |
|
| 376 |
- |
|
| 377 |
- CloseableHttpResponse response = httpClient.execute(httpPost); |
|
| 378 |
- int statusCode = response.getStatusLine().getStatusCode(); |
|
| 379 |
- |
|
| 380 |
- if (statusCode == 200) {
|
|
| 381 |
- String result = EntityUtils.toString(response.getEntity(), "UTF-8"); |
|
| 382 |
- JSONParser parser = new JSONParser(); |
|
| 383 |
- JSONObject object = (JSONObject) parser.parse(result); |
|
| 384 |
- |
|
| 385 |
- String code = object.get("code").toString();
|
|
| 386 |
- if ("200".equals(code)) {
|
|
| 387 |
- Map<String, Object> returnMap = new HashMap<>(); |
|
| 388 |
- returnMap.put("imgUrl", object.get("image").toString());
|
|
| 389 |
- returnMap.put("fileName", originalName);
|
|
| 390 |
- |
|
| 391 |
- return new StatusResponse(HttpStatus.OK, "이미지 등록이 완료 되었습니다.", returnMap); |
|
| 392 |
- } else {
|
|
| 393 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, object.get("message").toString(), LocalDateTime.now());
|
|
| 394 |
- } |
|
| 395 |
- } else {
|
|
| 396 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, "카카오 API 요청 실패", LocalDateTime.now()); |
|
| 358 |
+ if (width < 500 || ratio < 0.75 || ratio > 2.0) {
|
|
| 359 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "일반 이미지는 가로 500px 이상, 비율 2:1 이상 또는 3:4 이하만 허용됩니다."); |
|
| 397 | 360 |
} |
| 398 | 361 |
} |
| 399 |
- } catch (Exception e) {
|
|
| 400 |
- log.error("kakaoApiImageUpload_advc API Error", e);
|
|
| 401 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, "친구톡 이미지 등록에 실패했습니다.", LocalDateTime.now()); |
|
| 402 |
- } |
|
| 403 |
- return new StatusResponse(HttpStatus.BAD_REQUEST, "유효한 이미지 파일이 없습니다.", LocalDateTime.now()); |
|
| 362 |
+ |
|
| 363 |
+ String atchFileId = this.saveImgFile(files); |
|
| 364 |
+ |
|
| 365 |
+ |
|
| 366 |
+ |
|
| 367 |
+ |
|
| 368 |
+ |
|
| 369 |
+ String newName = EgovStringUtil.getTimeStamp() + fileKeyParam; |
|
| 370 |
+ String filePath = storePathString + File.separator + newName + "." + ext; |
|
| 371 |
+ file.transferTo(new File(filePath)); |
|
| 372 |
+ |
|
| 373 |
+ // 카카오 API 호출 |
|
| 374 |
+ CloseableHttpClient httpClient = HttpClients.createDefault(); |
|
| 375 |
+ String apiUrl = mjonBizUrl + "/v3/kakao/image/upload"; |
|
| 376 |
+ |
|
| 377 |
+ HttpPost httpPost = new HttpPost(apiUrl); |
|
| 378 |
+ /*HttpEntity httpEntity = MultipartEntityBuilder.create() |
|
| 379 |
+ .addTextBody("bizId", mjonBizId)
|
|
| 380 |
+ .addTextBody("apiKey", mjonBizKakaoApiKey)
|
|
| 381 |
+ .addTextBody("imageType", kakaoVO.getImageType())
|
|
| 382 |
+ .addTextBody("title", kakaoVO.getImgTitle())
|
|
| 383 |
+ .addTextBody("link", kakaoVO.getImgLink())
|
|
| 384 |
+ .addTextBody("senderKey", kakaoVO.getSenderKey())
|
|
| 385 |
+ .addBinaryBody("image", new File(filePath), ContentType.MULTIPART_FORM_DATA, newName + "." + ext)
|
|
| 386 |
+ .build(); |
|
| 387 |
+ */ |
|
| 388 |
+ |
|
| 389 |
+ HttpEntity httpEntity = MultipartEntityBuilder.create() |
|
| 390 |
+ .addTextBody("bizId", mjonBizId)
|
|
| 391 |
+ .addTextBody("apiKey", mjonBizKakaoApiKey)
|
|
| 392 |
+ .addTextBody("imageType", kakaoVO.getImageType())
|
|
| 393 |
+ .addTextBody("title", originalName)
|
|
| 394 |
+ .addTextBody("link", StringUtils.isEmpty(kakaoVO.getImgLink()) ? "https://" : kakaoVO.getImgLink())
|
|
| 395 |
+ .addTextBody("senderKey", kakaoVO.getSenderKey())
|
|
| 396 |
+ .addBinaryBody("image", new File(filePath), ContentType.MULTIPART_FORM_DATA, newName + "." + ext)
|
|
| 397 |
+ .build(); |
|
| 398 |
+ |
|
| 399 |
+ httpPost.setEntity(httpEntity); |
|
| 400 |
+ |
|
| 401 |
+ |
|
| 402 |
+ |
|
| 403 |
+ CloseableHttpResponse response = httpClient.execute(httpPost); |
|
| 404 |
+ int statusCode = response.getStatusLine().getStatusCode(); |
|
| 405 |
+ |
|
| 406 |
+ if (statusCode == 200) {
|
|
| 407 |
+ String result = EntityUtils.toString(response.getEntity(), "UTF-8"); |
|
| 408 |
+ JSONParser parser = new JSONParser(); |
|
| 409 |
+ JSONObject object = (JSONObject) parser.parse(result); |
|
| 410 |
+ |
|
| 411 |
+ String code = object.get("code").toString();
|
|
| 412 |
+ if ("200".equals(code)) {
|
|
| 413 |
+ Map<String, Object> returnMap = new HashMap<>(); |
|
| 414 |
+ returnMap.put("imgUrl", object.get("image").toString());
|
|
| 415 |
+ returnMap.put("fileName", originalName);
|
|
| 416 |
+ returnMap.put("atchFileId", atchFileId);
|
|
| 417 |
+ |
|
| 418 |
+ return new StatusResponse(HttpStatus.OK, "이미지 등록이 완료 되었습니다.", returnMap); |
|
| 419 |
+ } else {
|
|
| 420 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, object.get("message").toString(), LocalDateTime.now());
|
|
| 421 |
+ } |
|
| 422 |
+ } else {
|
|
| 423 |
+ return new StatusResponse(HttpStatus.BAD_REQUEST, "카카오 API 요청 실패", LocalDateTime.now()); |
|
| 424 |
+ } |
|
| 425 |
+// } |
|
| 426 |
+// } catch (Exception e) {
|
|
| 427 |
+// log.error("kakaoApiImageUpload_advc API Error", e);
|
|
| 428 |
+// return new StatusResponse(HttpStatus.BAD_REQUEST, "친구톡 이미지 등록에 실패했습니다.", LocalDateTime.now()); |
|
| 429 |
+// } |
|
| 404 | 430 |
} |
| 405 | 431 |
|
| 406 | 432 |
|
| 407 | 433 |
|
| 434 |
+ private String saveImgFile(Map<String, MultipartFile> files) throws Exception {
|
|
| 435 |
+ |
|
| 436 |
+ |
|
| 437 |
+ |
|
| 438 |
+ String atchFileId = ""; |
|
| 439 |
+ String isThumbFile = ""; |
|
| 440 |
+ String imagePath = ""; |
|
| 441 |
+ String KeyStr = "CANVASIMG_"; |
|
| 442 |
+ |
|
| 443 |
+ |
|
| 444 |
+ Date now = new Date(); |
|
| 445 |
+ SimpleDateFormat formatDate = new SimpleDateFormat("yyyyMMdd");
|
|
| 446 |
+ String fdlDate = formatDate.format(now); |
|
| 447 |
+ |
|
| 448 |
+ |
|
| 449 |
+ imagePath = fileSaveDir+"/file/MMS/" + fdlDate; |
|
| 450 |
+ |
|
| 451 |
+ |
|
| 452 |
+ |
|
| 453 |
+ if (!files.isEmpty()) {
|
|
| 454 |
+ List<FileVO> result = fileUtil.parseImageFileInf(files, KeyStr, 0, atchFileId, imagePath, isThumbFile); |
|
| 455 |
+ atchFileId = fileMngService.insertFileInfs(result); |
|
| 456 |
+ } |
|
| 457 |
+ |
|
| 458 |
+ |
|
| 459 |
+ return atchFileId; |
|
| 460 |
+ } |
|
| 461 |
+ |
|
| 462 |
+ |
|
| 463 |
+ |
|
| 464 |
+ |
|
| 408 | 465 |
/** |
| 409 | 466 |
* @Method Name : kakaoApiTemplateImageUpload |
| 410 | 467 |
* @작성일 : 2023. 2. 16. |
--- src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java
+++ src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java
... | ... | @@ -177,9 +177,10 @@ |
| 177 | 177 |
|
| 178 | 178 |
/** @biz_kakao_price에 insert (대체문자 환불관련 테이블)*/ |
| 179 | 179 |
kakaoVO.setMsgGroupId(sendVO.getMsgGroupId()); |
| 180 |
- kakaoVO.setKakaoAtPrice(Float.parseFloat(sendVO.getEachPrice())); |
|
| 180 |
+ kakaoVO.setKakaoFtPrice(Float.parseFloat(sendVO.getEachPrice())); |
|
| 181 | 181 |
kakaoVO.setSmsPrice(Float.parseFloat(sendVO.getSmsPrice())); |
| 182 | 182 |
kakaoVO.setMmsPrice(Float.parseFloat(sendVO.getMmsPrice())); |
| 183 |
+ kakaoVO.setPicturePrice(Float.parseFloat(sendVO.getPicturePrice())); |
|
| 183 | 184 |
|
| 184 | 185 |
kakaoAlimTalkDAO.insertKakaoSendPrice(kakaoVO); |
| 185 | 186 |
|
--- src/main/java/itn/let/mjo/msg/service/MjonMsgVO.java
+++ src/main/java/itn/let/mjo/msg/service/MjonMsgVO.java
... | ... | @@ -165,6 +165,7 @@ |
| 165 | 165 |
|
| 166 | 166 |
private float smsPrice; // sms 단가 |
| 167 | 167 |
private float mmsPrice; // mms 단가 |
| 168 |
+ private float picturePrice; // mms 단가 |
|
| 168 | 169 |
private float kakaoAtPrice; // 카카오 알림톡 단가 |
| 169 | 170 |
private float kakaoFtPrice; // 카카오 친구톡 단가 |
| 170 | 171 |
private float kakaoFtImgPrice;// 카카오 이미지 단가 |
--- src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml
... | ... | @@ -73,12 +73,15 @@ |
| 73 | 73 |
, SMS_TXT |
| 74 | 74 |
, BIZ_KAKAO_TITLE |
| 75 | 75 |
, AD_FLAG |
| 76 |
+ , FILE_PATH1 |
|
| 76 | 77 |
|
| 77 | 78 |
, BIZ_KAKAO_RESEND_YN |
| 78 | 79 |
, BIZ_KAKAO_RESEND_DATA |
| 79 | 80 |
, BIZ_KAKAO_RESEND_TYPE |
| 80 | 81 |
, BIZ_KAKAO_JSON_FILE |
| 81 | 82 |
, REQ_DATE |
| 83 |
+ |
|
| 84 |
+ , FILE_CNT |
|
| 82 | 85 |
)VALUES |
| 83 | 86 |
<iterate conjunction=","> |
| 84 | 87 |
( |
... | ... | @@ -97,12 +100,15 @@ |
| 97 | 100 |
, #[].templateContent# |
| 98 | 101 |
, #[].templateTitle# |
| 99 | 102 |
, #[].adFlag# |
| 103 |
+ , #[].filePath1# |
|
| 100 | 104 |
|
| 101 | 105 |
, #[].subMsgSendYn# |
| 102 | 106 |
, #[].subMsgTxt# |
| 103 | 107 |
, #[].subMsgType# |
| 104 | 108 |
, #[].bizJsonName# |
| 105 | 109 |
, #[].reqDate# |
| 110 |
+ |
|
| 111 |
+ , #[].fileCnt# |
|
| 106 | 112 |
) |
| 107 | 113 |
</iterate> |
| 108 | 114 |
</insert> |
... | ... | @@ -178,20 +184,18 @@ |
| 178 | 184 |
MSG_GROUP_ID |
| 179 | 185 |
, BIZ_KAKAO_AT_PRICE |
| 180 | 186 |
, BIZ_KAKAO_FT_PRICE |
| 181 |
- , BIZ_KAKAO_FT_IMG_PRICE |
|
| 182 |
- , BIZ_KAKAO_FT_WIDE_IMG_PRICE |
|
| 183 | 187 |
, BIZ_SMS_PRICE |
| 184 | 188 |
, BIZ_MMS_PRICE |
| 189 |
+ , BIZ_PICTURE_PRICE |
|
| 185 | 190 |
) |
| 186 | 191 |
VALUES |
| 187 | 192 |
( |
| 188 | 193 |
#msgGroupId# |
| 189 | 194 |
,#kakaoAtPrice# |
| 190 | 195 |
,#kakaoFtPrice# |
| 191 |
- ,#kakaoFtImgPrice# |
|
| 192 |
- ,#kakaoFtWideImgPrice# |
|
| 193 | 196 |
,#smsPrice# |
| 194 | 197 |
,#mmsPrice# |
| 198 |
+ ,#picturePrice# |
|
| 195 | 199 |
) |
| 196 | 200 |
</insert> |
| 197 | 201 |
|
... | ... | @@ -235,6 +239,8 @@ |
| 235 | 239 |
, DATE_FORMAT(MMD.RSLT_DATE,'%Y-%m-%d %T') AS rsltDate |
| 236 | 240 |
, MMD.BIZ_KAKAO_RESEND_YN AS subMsgSendYn |
| 237 | 241 |
, MMD.BIZ_KAKAO_RESEND_TYPE AS subMsgType |
| 242 |
+ , MMD.FILE_CNT AS fileCnt |
|
| 243 |
+ , MMD.BIZ_KAKAO_RESEND_TYPE AS bizKakaoResendType |
|
| 238 | 244 |
|
| 239 | 245 |
FROM |
| 240 | 246 |
MJ_MSG_DATA MMD |
... | ... | @@ -275,7 +281,7 @@ |
| 275 | 281 |
|
| 276 | 282 |
<!-- 카카오 친구톡 전송 환불 프로시저 실행 (카카오 전송 성공 관련 - 대체문자 선택시 차액 환불 처리) --> |
| 277 | 283 |
<procedure id="kakaoAlimTalkDAO.updateKakaoFtSend" parameterClass="kakaoVO"> |
| 278 |
- {call kakaoFt_Send(#userId#, #msgGroupId#, #userData#)}
|
|
| 284 |
+ {call kakaoFt_Send(#userId#, #msgGroupId#, #userData#, #fileCnt#, #bizKakaoResendType#)}
|
|
| 279 | 285 |
</procedure> |
| 280 | 286 |
|
| 281 | 287 |
<!-- 카카오 친구톡 전송 환불 프로시저 실행 (카카오 전송 실패시 대체문자 관련 - 대체문자 발송 완료 된 경우) --> |
--- src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp
... | ... | @@ -180,6 +180,7 @@ |
| 180 | 180 |
if ($('#sendFailImgSrc').attr('src') != null) {
|
| 181 | 181 |
$('#sendFailImg').hide();
|
| 182 | 182 |
$('#sendFailImgSrc').attr('src', '');
|
| 183 |
+ $('#atchFileId').val('');
|
|
| 183 | 184 |
} |
| 184 | 185 |
|
| 185 | 186 |
|
... | ... | @@ -599,6 +600,9 @@ |
| 599 | 600 |
$(".kakao_image").css("display", "block");
|
| 600 | 601 |
$("#kakaoImg").attr("src", returnData.object.imgUrl);
|
| 601 | 602 |
|
| 603 |
+ |
|
| 604 |
+ // 대체문자 이미지 |
|
| 605 |
+ $("#atchFileId").val(returnData.object.atchFileId);
|
|
| 602 | 606 |
// 대체문자 |
| 603 | 607 |
$('#sendFailImg').show();
|
| 604 | 608 |
$('#sendFailImgSrc').attr('src', returnData.object.imgUrl);
|
... | ... | @@ -1619,6 +1623,7 @@ |
| 1619 | 1623 |
<input type="hidden" id="kakaoFtWideImgPrice" value="<c:out value='${sendPrice.kakaoFtWideImgPrice}' />"> <!-- 친구톡 와이드이미지 단가 -->
|
| 1620 | 1624 |
<input type="hidden" id="longPrice" value="<c:out value='${sendPrice.longPrice}' />"> <!-- mms 단가 -->
|
| 1621 | 1625 |
<input type="hidden" id="shortPrice" value="<c:out value='${sendPrice.shortPrice}' />"> <!-- sms 단가 -->
|
| 1626 |
+ <input type="hidden" id="picturePrice" value="<c:out value='${sendPrice.picturePrice}' />"> <!-- sms 단가 -->
|
|
| 1622 | 1627 |
|
| 1623 | 1628 |
<form id="bizForm" name="bizForm" method="multipart/form-data"> |
| 1624 | 1629 |
<input type="hidden" id="menuTopTab" name="menuTopTab" value="tabFriend"> |
... | ... | @@ -1631,6 +1636,9 @@ |
| 1631 | 1636 |
<input type="hidden" id="adFlag" name="adFlag" value="<c:out value='${resultTemplateVO.adFlag}' default='Y'/>">
|
| 1632 | 1637 |
<input type="hidden" id="templateContent" name="templateContent" value=""/> |
| 1633 | 1638 |
|
| 1639 |
+ <!-- 이미지 있을때 대체문자 발송 참고 이미지 --> |
|
| 1640 |
+ <input type="hidden" id="atchFileId" name="atchFileId" value=""/> |
|
| 1641 |
+ |
|
| 1634 | 1642 |
<!-- 예약발송 여부 --> |
| 1635 | 1643 |
<input type="hidden" id="reserveYn" name="reserveYn" value="N"/> |
| 1636 | 1644 |
<input type="hidden" id="reqDate" name="reqDate" value=""/> |
--- src/main/webapp/js/kakao/ft/ftPriceClclt.js
+++ src/main/webapp/js/kakao/ft/ftPriceClclt.js
... | ... | @@ -33,80 +33,52 @@ |
| 33 | 33 |
* 대체 문자 X |
| 34 | 34 |
* 카카오 금액 * 수신자 수 계산 |
| 35 | 35 |
*/ |
| 36 |
-function totalFtPriceSum(totRows){
|
|
| 37 |
- |
|
| 38 |
- var collNumCnt = parseInt(totRows); //받는사람 건수 |
|
| 39 |
- var price; |
|
| 40 |
- |
|
| 36 |
+function totalFtPriceSum(totRows) {
|
|
| 37 |
+ // 수신자 수 계산 |
|
| 38 |
+ var count = parseInt(totRows); |
|
| 41 | 39 |
|
| 42 |
- if ($("input[name='img_file_add']:checked").attr("id") == "img_file_1") {
|
|
| 43 |
- price = KAKAO_FT_IMG_PRICE; |
|
| 44 |
- } else if ($("input[name='img_file_add']:checked").attr("id") == "img_file_2") {
|
|
| 45 |
- price = KAKAO_FT_WIDE_IMG_PRICE; |
|
| 46 |
- } else {
|
|
| 47 |
- price = KAKAO_FT_PRICE; //개별 건수 금액 |
|
| 48 |
- } |
|
| 49 |
- |
|
| 50 |
- |
|
| 51 |
- var totalPrice = 0; //전체 금액 |
|
| 52 |
- var totalStr = "0"; //전체 합계 금액 |
|
| 53 |
- var userMoney = $('#hdUserMoney').text(); //헤더 영역 보유 금액 불러오기
|
|
| 54 |
- |
|
| 55 |
- if(!userMoney > 0){
|
|
| 56 |
- |
|
| 57 |
- userMoney = 0; |
|
| 58 |
- |
|
| 59 |
- } |
|
| 60 |
- //헤더 영역 보유 금액 콤마 문자 제거 |
|
| 61 |
- if(userMoney != ''){
|
|
| 62 |
- |
|
| 63 |
- userMoney = userMoney.replaceAll("," , "");
|
|
| 64 |
- |
|
| 65 |
- } |
|
| 66 |
- |
|
| 67 |
- //대체문자가 있는 경우 대체문자의 단/장문에 따른 금액 계산 |
|
| 68 |
- var subMsgSts = $("#send_fail_check").is(":checked");
|
|
| 69 |
- |
|
| 70 |
- if(subMsgSts){
|
|
| 71 |
- |
|
| 72 |
- var conLeng = conByteLeng($('#smsTxtArea').val()); // 내용 문자 입력 바이트 수 계산하기
|
|
| 73 |
- if(conLeng > 90){
|
|
| 74 |
- price = $("#longPrice").val();
|
|
| 75 |
- }else{
|
|
| 76 |
- price = $("#shortPrice").val();
|
|
| 40 |
+ // 기본 단가는 일반 친구톡 이미지 없는 가격 |
|
| 41 |
+ var price = KAKAO_FT_PRICE; |
|
| 42 |
+ |
|
| 43 |
+ // 선택된 이미지 유형에 따라 단가 변경 |
|
| 44 |
+ var imgTypeId = $("input[name='img_file_add']:checked").attr("id");
|
|
| 45 |
+ if (imgTypeId === "img_file_1") price = KAKAO_FT_IMG_PRICE; |
|
| 46 |
+ else if (imgTypeId === "img_file_2") price = KAKAO_FT_WIDE_IMG_PRICE; |
|
| 47 |
+ |
|
| 48 |
+ // 대체문자 발송 옵션이 체크된 경우, 메시지 종류별로 단가 재계산 |
|
| 49 |
+ if ($("#send_fail_check").is(":checked")) {
|
|
| 50 |
+ if (imgTypeId === "img_file_0") {
|
|
| 51 |
+ // 장문/단문 여부에 따라 가격 비교 후 더 큰 값으로 설정 |
|
| 52 |
+ var len = conByteLeng($('#smsTxtArea').val());
|
|
| 53 |
+ var long = parseFloat($("#longPrice").val());
|
|
| 54 |
+ var short = parseFloat($("#shortPrice").val());
|
|
| 55 |
+ price = Math.max(price, len > 90 ? long : short); |
|
| 56 |
+ } else {
|
|
| 57 |
+ // 이미지 대체문자의 경우 별도 이미지 가격과 비교 |
|
| 58 |
+ var picture = parseFloat($('#picturePrice').val());
|
|
| 59 |
+ price = Math.max(price, picture); |
|
| 77 | 60 |
} |
| 78 |
- |
|
| 79 | 61 |
} |
| 80 |
- |
|
| 81 |
- totalPrice = price * collNumCnt; |
|
| 82 |
- |
|
| 83 |
- // 소수점 첫째자리 까지 표시 |
|
| 84 |
- totalPrice = totalPrice.toFixed(1); |
|
| 85 |
- |
|
| 86 |
- if(totalPrice > 0){
|
|
| 87 |
- |
|
| 88 |
- //totalStr = totalPrice.toFixed(2); |
|
| 89 |
- totalStr = totalPrice; |
|
| 90 |
- |
|
| 91 |
- } |
|
| 92 |
- |
|
| 93 |
- //개별 문자 단가 파라미터에 입력 |
|
| 62 |
+ |
|
| 63 |
+ // 총 금액 계산 (단가 * 수신자 수) |
|
| 64 |
+ var totalPrice = (price * count).toFixed(1); |
|
| 65 |
+ var totalStr = totalPrice > 0 ? totalPrice : "0"; |
|
| 66 |
+ |
|
| 67 |
+ // 사용자 보유 금액 텍스트에서 콤마 제거 (표시 용도일 뿐 실제 계산엔 안 씀) |
|
| 68 |
+ var userMoney = $('#hdUserMoney').text().replaceAll(",", "") || 0;
|
|
| 69 |
+ |
|
| 70 |
+ // 개별 단가, 총 금액을 input/화면에 반영 |
|
| 94 | 71 |
$('#eachPrice').val(numberWithCommas(price));
|
| 95 |
- |
|
| 96 |
- //결제금액 합계 파라이터에 입력 |
|
| 97 | 72 |
$('#totPrice').val(numberWithCommas(totalStr));
|
| 98 |
- |
|
| 99 |
- //결제금액 합계 화면에 표시 |
|
| 100 | 73 |
$('#totalPriceTxt').text(numberWithCommas(totalStr));
|
| 101 |
- |
|
| 102 |
- $('#repPriceTxt').hide();
|
|
| 103 |
- |
|
| 104 |
- return totalStr; |
|
| 105 |
- |
|
| 74 |
+ $('#repPriceTxt').hide(); // 기존 합계 표시 숨김
|
|
| 75 |
+ |
|
| 76 |
+ return totalStr; // 계산된 총 금액 반환 |
|
| 106 | 77 |
} |
| 107 | 78 |
|
| 108 | 79 |
|
| 109 | 80 |
|
| 81 |
+ |
|
| 110 | 82 |
/* |
| 111 | 83 |
* ====================================================================================================================== |
| 112 | 84 |
* |
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?