이호영 이호영 2025-06-05
친구톡 진행중
@d0a6292cc591d27e0465d8332a18b7345282574e
src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiImageUpload.java
--- src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiImageUpload.java
+++ src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiImageUpload.java
@@ -5,6 +5,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
+import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -15,6 +16,7 @@
 import javax.imageio.ImageIO;
 import javax.swing.ImageIcon;
 
+import org.apache.commons.io.FilenameUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
@@ -30,6 +32,7 @@
 import org.json.simple.JSONObject;
 import org.json.simple.parser.JSONParser;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -38,8 +41,11 @@
 import itn.com.cmm.service.FileVO;
 import itn.let.kakao.kakaoComm.KakaoReturnVO;
 import itn.let.kakao.kakaoComm.KakaoVO;
+import itn.let.mail.service.StatusResponse;
 import itn.let.utl.fcc.service.EgovStringUtil;
+import lombok.extern.slf4j.Slf4j;
 
+@Slf4j
 @Component("kakaoApiImageUpload")
 public class KakaoApiImageUpload {
 
@@ -219,13 +225,13 @@
 						.addTextBody("bizId", mjonBizId)
 						.addTextBody("apiKey", mjonBizKakaoApiKey)
 						.addTextBody("imageType", kakaoVO.getImageType())
-						.addTextBody("title", kakaoVO.getImgTitle())
-						.addTextBody("link", kakaoVO.getImgLink())
+						.addTextBody("title", "test")
+						.addTextBody("link", "https://maaa.com")
 						.addTextBody("senderKey", kakaoVO.getSenderKey())
 						.addBinaryBody("image", new File(filePath),ContentType.MULTIPART_FORM_DATA,fullFileName)
 						.build();
 				
-				httpPost.setEntity(httpEntity);
+ 				httpPost.setEntity(httpEntity);
 
 		        CloseableHttpResponse response = httpClient.execute(httpPost);
 
@@ -245,6 +251,7 @@
 					String msg = object.get("message").toString();
 					String imgUrl = "";
 					
+					log.info(" : code :: [{}]", code);
 					if(code.equals("200")) {
 						imgUrl = object.get("image").toString();
 					}
@@ -271,6 +278,113 @@
 		}
 		return resultMap;
 	}
+	
+	
+	
+
+	/**
+	 * @methodName	: kakaoApiImageUpload_advc 
+	 * @author		: 이호영
+	 * @date		: 2025. 6. 4.
+	 * @description	: kakaoApiImageUpload 수정
+	 * @return : StatusResponse
+	 * @param kakaoVO
+	 * @param files
+	 * @param i
+	 * @return
+	 * 
+	 */
+	public StatusResponse kakaoApiImageUpload_advc(KakaoVO kakaoVO, Map<String, MultipartFile> files, int fileKeyParam) {
+		try {
+			String storePathString = propertyService.getString("Globals.fileStorePath");
+			File saveFolder = new File(storePathString);
+			if (!saveFolder.exists()) saveFolder.mkdirs();
+
+			for (MultipartFile file : files.values()) {
+				if (file.isEmpty()) continue;
+
+				String originalName = file.getOriginalFilename();
+				if (originalName == null || originalName.isEmpty()) continue;
+
+				String ext = FilenameUtils.getExtension(originalName).toLowerCase();
+				if (!ext.matches("jpg|jpeg|png")) {
+					return new StatusResponse(HttpStatus.BAD_REQUEST, "지원하지 않는 이미지 형식입니다.");
+				}
+
+				long size = file.getSize();
+				if (size > 5 * 1024 * 1024) {
+					return new StatusResponse(HttpStatus.BAD_REQUEST, "이미지 용량은 5MB 이내여야 합니다.");
+				}
+
+				BufferedImage image = ImageIO.read(file.getInputStream());
+				if (image == null) {
+					return new StatusResponse(HttpStatus.BAD_REQUEST, "이미지를 읽을 수 없습니다.");
+				}
+
+				int width = image.getWidth();
+				int height = image.getHeight();
+				String type = kakaoVO.getImageType();
+
+				if ("W".equals(type)) {
+					if (width != 800 || height != 600) {
+						return new StatusResponse(HttpStatus.BAD_REQUEST, "와이드 이미지는 800x600 사이즈만 허용됩니다.");
+					}
+				} else {
+					float ratio = width / (float) height;
+					if (width < 500 || ratio < 0.5 || ratio > 0.75) {
+						return new StatusResponse(HttpStatus.BAD_REQUEST, "일반 이미지 조건 위반: 가로 500px 이상, 비율 2:1 미만 및 3:4 초과 불가");
+					}
+				}
+
+				String newName = EgovStringUtil.getTimeStamp() + fileKeyParam;
+				String filePath = storePathString + File.separator + newName + "." + ext;
+				file.transferTo(new File(filePath));
+
+				// 카카오 API 호출
+				CloseableHttpClient httpClient = HttpClients.createDefault();
+				String apiUrl = mjonBizUrl + "/v3/kakao/image/upload";
+
+				HttpPost httpPost = new HttpPost(apiUrl);
+				HttpEntity httpEntity = MultipartEntityBuilder.create()
+						.addTextBody("bizId", mjonBizId)
+						.addTextBody("apiKey", mjonBizKakaoApiKey)
+						.addTextBody("imageType", kakaoVO.getImageType())
+						.addTextBody("title", kakaoVO.getImgTitle())
+						.addTextBody("link", kakaoVO.getImgLink())
+						.addTextBody("senderKey", kakaoVO.getSenderKey())
+						.addBinaryBody("image", new File(filePath), ContentType.MULTIPART_FORM_DATA, newName + "." + ext)
+						.build();
+				httpPost.setEntity(httpEntity);
+
+				CloseableHttpResponse response = httpClient.execute(httpPost);
+				int statusCode = response.getStatusLine().getStatusCode();
+
+				if (statusCode == 200) {
+					String result = EntityUtils.toString(response.getEntity(), "UTF-8");
+					JSONParser parser = new JSONParser();
+					JSONObject object = (JSONObject) parser.parse(result);
+
+					String code = object.get("code").toString();
+					if ("200".equals(code)) {
+						Map<String, Object> returnMap = new HashMap<>();
+						returnMap.put("imgUrl", object.get("image").toString());
+						returnMap.put("fileName", originalName);
+						
+						return new StatusResponse(HttpStatus.OK, "이미지 등록이 완료 되었습니다.", returnMap);
+					} else {
+						return new StatusResponse(HttpStatus.BAD_REQUEST, object.get("message").toString(), LocalDateTime.now());
+					}
+				} else {
+					return new StatusResponse(HttpStatus.BAD_REQUEST, "카카오 API 요청 실패", LocalDateTime.now());
+				}
+			}
+		} catch (Exception e) {
+			log.error("kakaoApiImageUpload_advc API Error", e);
+			return new StatusResponse(HttpStatus.BAD_REQUEST, "친구톡 이미지 등록에 실패했습니다.", LocalDateTime.now());
+		}
+		return new StatusResponse(HttpStatus.BAD_REQUEST, "유효한 이미지 파일이 없습니다.", LocalDateTime.now());
+	}
+
 	
 	
 	/**
@@ -528,5 +642,7 @@
 		
 		return kakaoReturnVO;
 	}
+
+
 	
 }
src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkTemplateController.java
--- src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkTemplateController.java
+++ src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkTemplateController.java
@@ -1,5 +1,6 @@
 package itn.let.kakao.user.kakaoFt.web;
 
+import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -8,11 +9,15 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+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.ResponseBody;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartHttpServletRequest;
 import org.springframework.web.servlet.ModelAndView;
@@ -21,6 +26,7 @@
 import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
 import itn.com.cmm.EgovMessageSource;
 import itn.com.cmm.LoginVO;
+import itn.com.cmm.RestResponse;
 import itn.com.cmm.service.EgovCmmUseService;
 import itn.com.utl.fcc.service.EgovStringUtil;
 import itn.let.kakao.kakaoComm.KakaoReturnVO;
@@ -32,6 +38,7 @@
 import itn.let.kakao.kakaoComm.kakaoApi.KakaoFTJsonSave;
 import itn.let.kakao.kakaoComm.kakaoApi.service.KakaoApiService;
 import itn.let.kakao.user.kakaoFt.service.KakaoFriendsTalkTemplateService;
+import itn.let.mail.service.StatusResponse;
 import itn.let.mjo.symbol.service.MjonSymbolService;
 import itn.let.mjo.symbol.service.MjonSymbolVO;
 import itn.let.uss.umt.service.EgovUserManageService;
@@ -170,6 +177,56 @@
 		
 		return modelAndView;
 	}
+
+	@ResponseBody
+	@RequestMapping(value= {"/web/mjon/kakao/template/sendKakaoFriendsTemplateImageUploadAjax_advc.do"})
+	public ResponseEntity<StatusResponse> sendKakaoFriendsTemplateImageUploadAjax_advc(
+			@ModelAttribute("kakaoVO")  KakaoVO kakaoVO
+			, final MultipartHttpServletRequest multiRequest
+			) throws Exception {
+		ModelAndView modelAndView = new ModelAndView();		
+		modelAndView.setViewName("jsonView");
+		
+		try {
+			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+			
+			if(StringUtils.isEmpty(userId)) {	//KISA 보안취약점 조치 (2018-12-10, 이정은)
+				return ResponseEntity.ok(
+						new StatusResponse(HttpStatus.UNAUTHORIZED
+								, "로그인을 하셔야 이용 가능합니다."
+								, LocalDateTime.now()
+								)
+						);
+			}
+			
+			
+				
+				final Map<String, MultipartFile> files = multiRequest.getFileMap();
+				/*				if (!files.isEmpty()){
+									
+									Map<String, String> resultMap = kakaoApiImageUpload.kakaoApiImageUpload(kakaoVO, files, 0);
+									
+									//테스트 용 
+									modelAndView.addObject("code", resultMap.get("code"));
+									modelAndView.addObject("msg", resultMap.get("msg"));
+									modelAndView.addObject("imgUrl", resultMap.get("imgUrl"));
+								}
+								
+								modelAndView.addObject("result", "success");*/
+
+				return ResponseEntity.ok().body(kakaoApiImageUpload.kakaoApiImageUpload_advc(kakaoVO, files, 0));
+			} catch (Exception e) {
+				e.printStackTrace();
+				// TODO: handle exception
+				return ResponseEntity.ok().body(new StatusResponse(
+						HttpStatus.BAD_REQUEST
+						, "오류가 발생하였습니다."
+						, ""
+						));
+		}
+		
+	}
 	
 	
 	// 카카오 친구톡 템플릿 등록요청
src/main/java/itn/let/mail/service/StatusResponse.java
--- src/main/java/itn/let/mail/service/StatusResponse.java
+++ src/main/java/itn/let/mail/service/StatusResponse.java
@@ -5,6 +5,7 @@
 import org.springframework.http.HttpStatus;
 
 import itn.let.mjo.pay.service.RefundVO;
+import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp
--- src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp
@@ -414,7 +414,7 @@
 	}
 	
 	//이미지 선택시 링크 정보 및 url 패턴 검사
-	if(link == ''){
+	/* if(link == ''){
 		
 		$("#imgNm").text("");
 		$("#imgFile").val("");
@@ -427,7 +427,7 @@
 		$("#imgFile").val("");
 		alert("이미지 URL 주소에는 http:// 또는 https://를 포함하여 입력해야 합니다.");
 		return false;
-	}
+	} */
 	
 	//첨부파일 선택 팝업 호출해주기
 	$("#imgFile").click();
@@ -485,6 +485,7 @@
 	}
 
 	
+//     var url = url = "/web/mjon/kakao/template/sendKakaoFriendsTemplateImageUploadAjax_advc.do";
     var url = url = "/web/mjon/kakao/template/sendKakaoFriendsTemplateImageUploadAjax.do";
 	
 	$.ajax({
@@ -500,7 +501,32 @@
 		, success : function(returnData){
 			console.log('returnData : ', returnData);
 			
-			if(returnData.result == "success") {
+
+
+			if (returnData.status === 'OK' || returnData.status === 200) {
+				alert(returnData.message);
+
+				$("#templateImageName").val(fileName);
+				$("#imageFileName").val(fileName);
+
+				// imgUrl은 object에 포함된 경우만 처리
+				if (returnData.object) {
+					$("#templateImageUrl").val(returnData.object);
+					$(".kakao_image").css("display", "block");
+					$("#kakaoImg").attr("src", returnData.object);
+				}
+
+			} else {
+				alert(returnData.message || "이미지 등록 중 오류가 발생하였습니다.");
+
+				// 첨부파일 정보 초기화
+				$("#imgFile").val("");
+				$("#imgNm").text("");
+				return false;
+			}
+		},
+			
+		/* 	if(returnData.result == "success") {
 				
 				var code = returnData.code;
 				var msg = returnData.msg;
@@ -549,7 +575,7 @@
 				alert("이미지 등록 중 오류가 발생하였습니다.!!!");
 				return false;
 			}
-		},
+		}, */
 		beforeSend : function(xmlHttpRequest) {
         	//로딩창 show
         	$('.loading_layer').addClass('active');				
@@ -1574,49 +1600,82 @@
 								<tr>
 									<th>이미지 첨부</th>
 									<td>
-										<div class="img_sort_wrap">
-											<input type="radio" name="img_file_add" id="img_file_0" value="" <c:if test="${resultTemplateVO.imageType eq ''}">checked</c:if> > <label for="img_file_0">첨부안함</label>
-											<input type="radio" name="img_file_add" id="img_file_1" value="I" <c:if test="${resultTemplateVO.imageType eq 'I'}">checked</c:if> > <label for="img_file_1">이미지 첨부</label>
-											<input type="radio" name="img_file_add" id="img_file_2" value="W" <c:if test="${resultTemplateVO.imageType eq 'W'}">checked</c:if> > <label for="img_file_2">와이드 이미지 첨부</label>
-											<div class="img_add_info_wrap basic_img_add_wrap">
-												<p class="info_title_text"><span class="c_e40000">*</span> 이미지 첨부 안내</p>
-												<ul class="info_text">
-												<li>- 권장사이즈 : 720px * 720px</li>
+										<input type="radio" name="img_file_add" id="img_file_0" value="" <c:if test="${resultTemplateVO.imageType eq ''}">checked</c:if> >
+										<label for="img_file_0">첨부 안함</label>
+										<input type="radio" name="img_file_add" id="img_file_1" value="I" <c:if test="${resultTemplateVO.imageType eq 'I'}">checked</c:if> >
+										<label for="img_file_1">이미지 첨부</label>
+										<input type="radio" name="img_file_add" id="img_file_2" value="W" <c:if test="${resultTemplateVO.imageType eq 'W'}">checked</c:if> >
+										<label for="img_file_2">와이드 이미지 첨부</label>
+										
+										<div class="img_file_add_wrap basic_img_add_wrap">
+											<p class="info_title_text"><span class="c_e40000">*</span> 이미지 첨부 안내</p>
+											<ul class="info_text">
+												<li>- 권장사이즈 : 800px * 400px</li>
 												<li>- 제한사이즈 : 가로 500px 미만, 가로:세로 비율이 2:1 미만 또는 3:4 초과시 업로드 불가</li>
-												<li>- 파일형식 : jpg, png (최대 500kb)</li>
-												<li>- 이미지 첨부시 메시지 내용은 최대 400자까지 입력할 수 있습니다.</li>
-												</ul>
-											</div>
-											<div class="img_add_info_wrap wide_img_add_wrap">
-												<p class="info_title_text"><span class="c_e40000">*</span> 와이드 이미지 첨부 안내</p>
-												<ul class="info_text">
-												<li>- 권장사이즈 : 800px * 600px</li>
-												<!-- <li>- 제한사이즈 : 가로 500px 미만, 가로:세로 비율이 2:1 미만 또는 3:4 초과시 업로드 불가</li> -->
-												<li>- 파일형식 : jpg, png (최대 2mb)</li>
-												<li>- 와이드 이미지 첨부시 메시지 내용은 최대 76자, 버튼 1개까지 입력할 수 있습니다.</li>
-												</ul>
-											</div>
-										</div>
-										<div class="img_file_add_wrap">
-											<ul class="img_file_info_wrap">
-												<li>
-													<p>이미지 제목</p>
-													<input type="text" id="imgTitle" name="imgTitle" value="<c:out value='${resultTemplateVO.imgTitle}'/>" class="img_url" maxLength="50">
-												</li>
-												<li>
-													<p>이미지 클릭시 이동할 URL</p>
-													<input type="text" id="imgLink" name="imgLink" value="<c:out value='${resultTemplateVO.imgLink}'/>" placeholder="http://" class="img_url" maxLength="1000">
-												</li>
-												<li>
-													<p class="file_name"  id="imgNm" name="imgNm">첨부파일 이미지</p>
-													<button type="button" class="btn_del btnImgDel" onclick="buttonTypeDel(this);">
-														<img src="/publish/images/btn_delete.png" id="imgDel" alt="이미지 삭제" onclick="fnImageDel();">
-													</button>
-												</li>
+												<li>- 파일형식 : jpg, png (최대 5MB)</li>
+												<li>- 이미지 첨부 시 메시지 내용은 최대 400자, 버튼 5개까지 입력할 수 있습니다.</li>
 											</ul>
-											<button type="button" class="btnType btnType8 btn_img_upload" title="이미지 불러오기" onclick="javascript:upImgClick(); return false;">이미지 불러오기</button>
-											<input type="file" id="imgFile" accept=".jpg, .jpeg, .png" onchange="imgResizeInfo(event); return false;" style="display:none"/>
+<!-- 											<ul class="img_file_info_wrap"> -->
+<!-- 												<li> -->
+<!-- 													<button type="button" class="btnType btnType8 btn_img_upload">이미지 불러오기</button> -->
+<!-- 													<div class="img_file_wrap"> -->
+<!-- 														<p class="file_name">image_testtest.jpg</p> -->
+<!-- 														<button type="button" class="btn_del" onclick="buttonTypeDel(this);"> -->
+<!-- 															<img src="/publish/images/btn_delete.png" alt=""> -->
+<!-- 														</button> -->
+<!-- 													</div> -->
+<!-- 												</li> -->
+<!-- 												<li> -->
+<!-- 													<p>이미지 클릭시 이동할 URL</p> <input type="text" -->
+<!-- 													placeholder="(선택사항) https://" class="img_url"> -->
+<!-- 												</li> -->
+<!-- 											</ul> -->
 										</div>
+										<div class="img_file_add_wrap wide_img_add_wrap">
+											<p class="info_title_text"><span class="c_e40000">*</span> 와이드 이미지 첨부 안내</p>
+											<ul class="info_text">
+												<li>- 권장사이즈 : 800px * 600px</li>
+												<li>- 파일형식 : jpg, png (최대 5MB)</li>
+												<li>- 와이드 이미지 첨부시 메시지 내용은 최대 76자, 버튼 1개까지 입력할 수 있습니다.</li>
+											</ul>
+											
+											
+										</div>
+										<ul class="img_file_info_wrap">
+											<li>
+												<button type="button" class="btnType btnType8 btn_img_upload" onclick="javascript:upImgClick(); return false;">이미지 불러오기</button>
+												<input type="file" id="imgFile" accept=".jpg, .jpeg, .png" onchange="imgResizeInfo(event); return false;" style="display:none"/> 
+												<div class="img_file_wrap">
+													<p class="file_name file_none">이미지 없음</p>
+													<button type="button" class="btn_del" onclick="buttonTypeDel(this);">
+														<img src="/publish/images/btn_delete.png" alt="">
+													</button>
+												</div>
+											</li>
+											<li>
+												<p>이미지 클릭시 이동할 URL</p> <input type="text" placeholder="(선택사항) https://" class="img_url">
+											</li>
+										</ul>
+											
+											
+										<%-- <ul class="img_file_info_wrap">
+											<li>
+												<p>이미지 제목</p>
+												<input type="text" id="imgTitle" name="imgTitle" value="<c:out value='${resultTemplateVO.imgTitle}'/>" class="img_url" maxLength="50">
+											</li>
+											<li>
+												<p>이미지 클릭시 이동할 URL</p>
+												<input type="text" id="imgLink" name="imgLink" value="<c:out value='${resultTemplateVO.imgLink}'/>" placeholder="http://" class="img_url" maxLength="1000">
+											</li>
+											<li>
+												<p class="file_name"  id="imgNm" name="imgNm">첨부파일 이미지</p>
+												<button type="button" class="btn_del btnImgDel" onclick="buttonTypeDel(this);">
+													<img src="/publish/images/btn_delete.png" id="imgDel" alt="이미지 삭제" onclick="fnImageDel();">
+												</button>
+											</li>
+										</ul>
+										<button type="button" class="btnType btnType8 btn_img_upload" title="이미지 불러오기" onclick="javascript:upImgClick(); return false;">이미지 불러오기</button>
+										<input type="file" id="imgFile" accept=".jpg, .jpeg, .png" onchange="imgResizeInfo(event); return false;" style="display:none"/> --%>
 									</td>
 								</tr>
 								<tr>
src/main/webapp/publish/css/content.css
--- src/main/webapp/publish/css/content.css
+++ src/main/webapp/publish/css/content.css
@@ -1649,18 +1649,18 @@
 .kakao_wrap .img_add_info_wrap .info_text{font-size: 15px; color: #555;}
 .kakao_wrap .img_add_info_wrap .info_text li{margin: 3px 0 0 0;}
 .kakao_wrap .img_file_add_wrap .info_title_text{font-weight: 500;margin:0 0 5px 0;}
-.kakao_wrap .img_file_add_wrap .btn_img_upload{width: 251px;}
-.kakao_wrap .img_file_add_wrap .img_file_info_wrap{width: 100%; max-width: 623px; border: 1px solid #e5e5e5; border-radius: 5px;}
-.kakao_wrap .img_file_add_wrap .img_file_info_wrap li{display: flex;min-height: 60px;padding: 10px 20px; border-bottom: 1px solid #e5e5e5;justify-content: space-between; align-items: center; box-sizing: border-box;}
-.kakao_wrap .img_file_add_wrap .img_file_info_wrap li:last-child{border-bottom: 0;}
-.kakao_wrap .img_file_add_wrap .file_name{font-size: 16px; font-weight: 500;}
-.kakao_wrap .img_file_add_wrap .btn_del{width: 30px;height: 30px;border: 1px solid #002c9a;border-radius: 5px;}
-.kakao_wrap .img_file_add_wrap .img_url{width: calc(100% - 190px);}
-.kakao_wrap .img_file_add_wrap .info_text{margin:0 0 10px 0;}
-.kakao_wrap .img_file_add_wrap .info_text li{list-style:1.4;}
-.kakao_wrap .img_file_add_wrap .img_file_wrap{display:inline-flex;width:calc(100% - 200px);}
-.kakao_wrap .img_file_add_wrap .img_file_wrap .file_name{width:calc(100% - 28px);}
-.kakao_wrap .img_file_add_wrap .img_file_wrap .file_name.file_none{color:#666;font-weight:300;line-height:1.8;}
+.kakao_wrap .img_file_info_wrap .btn_img_upload{width: 251px;}
+.kakao_wrap .img_file_info_wrap{display:none;width: 100%; max-width: 623px; border: 1px solid #e5e5e5; border-radius: 5px;margin:15px 0 0 0;}
+.kakao_wrap .img_file_info_wrap li{display: flex;min-height: 60px;padding: 10px 20px; border-bottom: 1px solid #e5e5e5;justify-content: space-between; align-items: center; box-sizing: border-box;}
+.kakao_wrap .img_file_info_wrap li:last-child{border-bottom: 0;}
+.kakao_wrap .img_file_info_wrap .file_name{font-size: 16px; font-weight: 500;}
+.kakao_wrap .img_file_info_wrap .btn_del{width: 30px;height: 30px;border: 1px solid #002c9a;border-radius: 5px;}
+.kakao_wrap .img_file_info_wrap .img_url{width: calc(100% - 190px);}
+.kakao_wrap .img_file_info_wrap .info_text{margin:0 0 10px 0;}
+.kakao_wrap .img_file_info_wrap .info_text li{list-style:1.4;}
+.kakao_wrap .img_file_info_wrap .img_file_wrap{display:inline-flex;width:calc(100% - 200px);}
+.kakao_wrap .img_file_info_wrap .img_file_wrap .file_name{width:calc(100% - 28px);}
+.kakao_wrap .img_file_info_wrap .img_file_wrap .file_name.file_none{color:#666;font-weight:300;line-height:1.8;}
 
 .kakaotalkset_cont .kakao_wrap .template_category{width: 270px;}
 .kakaotalkset_cont .kakao_wrap .emphasis_select{width: 250px;}
src/main/webapp/publish/js/content.js
--- src/main/webapp/publish/js/content.js
+++ src/main/webapp/publish/js/content.js
@@ -522,15 +522,15 @@
 	$("input[name='img_file_add']").change(function () {
 		if ($("input[name='img_file_add']:checked").attr("id") == "img_file_1") {
 			$(".basic_img_add_wrap").show().siblings(".wide_img_add_wrap").hide();
-			//$(".img_file_add_wrap").show();
+			$(".img_file_info_wrap").show();
 			$(".kakao_image img").show().attr("src", "/publish/images/content/kakao_img_basic.jpg");
 		} else if ($("input[name='img_file_add']:checked").attr("id") == "img_file_2") {
 			$(".wide_img_add_wrap").show().siblings(".basic_img_add_wrap").hide();
 			$(".kakao_image img").show().attr("src", "/publish/images/content/kakao_img_wide.jpg");
-			//$(".img_file_add_wrap").show();
+			$(".img_file_info_wrap").show();
 		} else {
 			$(".img_add_info_wrap, .img_file_add_wrap").hide();
-			$(".kakao_image img").hide();
+			$(".kakao_image img, .img_file_info_wrap").hide();
 		}
 	});
 
src/main/webapp/publish/kakao_friendtalk_send.html
--- src/main/webapp/publish/kakao_friendtalk_send.html
+++ src/main/webapp/publish/kakao_friendtalk_send.html
@@ -101,6 +101,7 @@
                                             <label for="img_file_1">이미지 첨부</label>
                                             <input type="radio" name="img_file_add" id="img_file_2">
                                             <label for="img_file_2">와이드 이미지 첨부</label>
+                                            
                                             <div class="img_file_add_wrap basic_img_add_wrap">
                                                 <p class="info_title_text"><span class="c_e40000">*</span> 이미지 첨부 안내</p>
                                                 <ul class="info_text">
Add a comment
List