OneToOneQnaFormMob.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. <!DOCTYPE html>
  2. <html lang="ko"
  3. xmlns:th="http://www.thymeleaf.org"
  4. xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
  5. layout:decorator="mob/common/layout/CallcenterLayoutMob">
  6. <!--
  7. *******************************************************************************
  8. * @source : OneToOneQnaFormWeb.html
  9. * @desc : 1:1문의 Page
  10. *============================================================================
  11. * STYLE24
  12. * Copyright(C) 2020 TSIT, All rights reserved.
  13. *============================================================================
  14. * VER DATE AUTHOR DESCRIPTION
  15. * === =========== ========== =============================================
  16. * 1.0 2021.02.19 gagamel 최초 작성
  17. *******************************************************************************
  18. -->
  19. <body>
  20. <th:block layout:fragment="content">
  21. <main role="" id="" class="container cs">
  22. <!-- 고객센터 Gnb -->
  23. <nav class="pnb" id="callcenterGnb">
  24. </nav>
  25. <!-- //고객센터 Gnb -->
  26. <!-- ★ 컨텐츠 시작 -->
  27. <section class="content cs_contactUs_1">
  28. <div class="inner sr-only"><h2 class="title">1:1문의</h2></div>
  29. <div class="inner wide">
  30. <!-- 게시판info -->
  31. <ul class="inquiry_box">
  32. <li>
  33. <p id="qnaTotCnt"></p>
  34. <p>총 문의</p>
  35. </li>
  36. <li>
  37. <p id="qnaAnsCnt"></p>
  38. <p>답변완료</p>
  39. </li>
  40. <li>
  41. <p id="qnaIngCnt"></p>
  42. <p>처리 중</p>
  43. </li>
  44. </ul>
  45. <!-- //게시판info -->
  46. </div>
  47. <div class="inner wide">
  48. <!-- 폴딩리스트2 -->
  49. <div class="ui_row" id="divQna"> <!-- 데이터 없을시 클래스 nodata 추가 -->
  50. <div class="foldGroup case2">
  51. <!-- list2 -->
  52. <ul id="ulQna">
  53. </ul>
  54. <!-- //list2 -->
  55. </div>
  56. </div>
  57. <div class="ui_foot">
  58. <button class="btn btnM btnIcon_more" id="btnQnaMore">더보기</button>
  59. </div>
  60. </div>
  61. </section>
  62. <!-- ★ 컨텐츠 종료 -->
  63. </main>
  64. <nav id="tabbar" class="tabbar fixed">
  65. <div class="tabbar-btn">
  66. <a href="#none" class="questionMy"><p>1:1문의</p></a>
  67. </div>
  68. <div class="tabbar-inner">
  69. <a href="javascript:menu;" class="btn-menu" data-popup-trigger="" data-target="#menu">Menu</a>
  70. <a href="javascript:myPage" class="btn-my">Mypage</a>
  71. <a href="javascript:home" class="btn-home">Home</a>
  72. <a href="javascript:wish" class="btn-wish">Wish</a>
  73. <a href="javascript:history" class="btn-history">History</a>
  74. </div>
  75. </nav>
  76. <!-- 모달영역 -->
  77. <div>
  78. <!-- 문의이미지슬라이드 -->
  79. <div class="modal pop_full fade" id="thumb_pic" tabindex="-1" role="dialog" aria-labelledby="exampleFullLabel" aria-hidden="true" style="display: none;">
  80. <div class="modal-dialog" role="document">
  81. <div class="modal-content">
  82. <div class="modal-header">
  83. <h5 class="modal-title sr-only">문의이미지슬라이드</h5>
  84. </div>
  85. <div class="modal-body">
  86. <div class="pop_cont">
  87. <!-- Swiper -->
  88. <div class="swiper-container cs_pop">
  89. <div class="swiper-wrapper" id="qnaImg">
  90. <div class="swiper-slide"><div class="pop_img" style="background-image: url(//image.istyle24.com/Style24/images/mo/cs_pop_people.png);"></div></div>
  91. <div class="swiper-slide"><div class="pop_img" style="background-image: url(//image.istyle24.com/Style24/images/mo/cs_pop_people2.png);"></div></div>
  92. </div>
  93. <!-- Add Pagination -->
  94. <div class="swiper-pagination"></div>
  95. </div>
  96. </div>
  97. </div>
  98. </div>
  99. </div>
  100. </div>
  101. <!-- //문의이미지슬라이드 -->
  102. <!-- 문의등록 -->
  103. <div class="modal pop_full fade" id="myQuestion" tabindex="-1" role="dialog" aria-labelledby="exampleFullLabel" aria-hidden="true">
  104. <div class="modal-dialog" role="document">
  105. <div class="modal-content">
  106. <div class="modal-header">
  107. <h5 class="modal-title">1:1문의</h5>
  108. </div>
  109. <div class="modal-body">
  110. <div class="pop_cont">
  111. <div class="content cs_contactUs_my">
  112. <form class="form_wrap" role="form" name="qnaRegisterForm" id="qnaRegisterForm" th:action="@{'/callcenter/onetoone/qna/create'}" method="post" onsubmit="$('#qnaRegisterForm').trigger('click'); return false;">
  113. <div class="form_field">
  114. <div class="ui_col_12 form_full">
  115. <div class="input_wrap">
  116. <div class="select">
  117. <select class="select_hidden" name="counselClsf" required="required" data-valid-name="문의유형">
  118. <option value="">문의 유형을 선택해 주세요 (필수)</option>
  119. <option th:if="${counselClsfList}" th:each="oneData, status : ${counselClsfList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}"></option>
  120. </select>
  121. <!-- <div class="select_dress">문의 유형을 선택해 주세요 (필수)<span></span></div> -->
  122. </div>
  123. </div>
  124. </div>
  125. </div>
  126. <div class="form_field">
  127. <div class="ui_col_12 form_full">
  128. <div class="input_wrap test">
  129. <span class="input_group_addon"><span class="ico"></span></span>
  130. <input type="text" class="form_control" placeholder="제목을 입력해 주세요 (필수)" maxlength="30" name="questTitle" required="required" data-valid-name="제목"/>
  131. </div>
  132. <!-- 숫자, 특수문자, 불완성형 한글 제외하여 입력 -->
  133. </div>
  134. </div>
  135. <div class="form_field">
  136. <div class="ui_col_12 form_full">
  137. <div class="input_wrap">
  138. <textarea class="doc_contactus" name="questContent" cols="30" rows="10" style="resize: none;" placeholder="내용을 입력해 주세요. (필수)" required="required" data-valid-name="내용"></textarea>
  139. <p class="txt_cnt">
  140. <span id="contactus_cnt" class="contactus_cnt"><em class="c_primary">0</em>/500</span>
  141. </p>
  142. </div>
  143. <!-- 특수문자 : \ / : < > 사용 불가 > 입력 시, “특수문자 \ / : < > 는 사용할 수 없습니다.” 얼럿 호출 스크립트 입력 불가능 -->
  144. </div>
  145. </div>
  146. <div class="form_field">
  147. <div class="ui_col_12 form_full">
  148. <div class="input_wrap">
  149. <!-- 이미지첨부 -->
  150. <div class="form_field">
  151. <div class="imgUpload">
  152. <label for="fileAdds" class="fileAdd">업로드</label>
  153. <input type="file" id="fileAdds" name="file2">
  154. </div>
  155. </div>
  156. <!-- //이미지첨부 -->
  157. <div class="info_addfile">
  158. <ul>
  159. <li>사진은 이미지당 10MB 이하의 JPEG, JPG, PNG 파일 2장까지 첨부 가능합니다.</li>
  160. <li>파일명에 한글은 사용 불가입니다.</li>
  161. <li>첨부된 사진은 문의 외의 목적으로는 사용되지 않습니다.</li>
  162. </ul>
  163. </div>
  164. </div>
  165. </div>
  166. </div>
  167. <div class="form_field">
  168. <div class="form_field">
  169. <div class="ui_col_12 cellphone">
  170. <div class="input_wrap">
  171. <span class="tt">알림톡 수신 여부</span>
  172. <!-- 알림 신청 체크박스(선택 _ 기본값) -->
  173. <div>
  174. <div class="ck_box">
  175. <input type="radio" name="smsReqYn" id="smsReqYn1" value="Y" checked="checked"/>
  176. <label for="smsReqYn1"><span>수신</span></label>
  177. </div>
  178. <div class="ck_box">
  179. <input type="radio" name="smsReqYn" id="smsReqYn2" value="N">
  180. <label for="smsReqYn2"><span>미수신</span></label>
  181. </div>
  182. </div>
  183. </div>
  184. </div>
  185. </div>
  186. </div>
  187. </form>
  188. </div>
  189. </div>
  190. </div>
  191. </div>
  192. <div class="modal-footer">
  193. <div class="btn_group_flex">
  194. <div><button type="button" class="btn btn_dark" id="btnSaveQna"><span>등록</span></button></div>
  195. </div>
  196. </div>
  197. </div>
  198. </div>
  199. <!-- //문의등록 -->
  200. </div>
  201. <!-- //모달끝 -->
  202. <form id="qnaForm" name="qnaForm" action="#" th:action="@{'/callcenter/onetoone/qna/list'}">
  203. <input type="hidden" name="pageNo" value ="1"/>
  204. <input type="hidden" name="pageSize" value ="10"/>
  205. </form>
  206. <script th:inline="javascript">
  207. /*<![CDATA[*/
  208. // JQUERY를 이용한 버튼 모달 팝업
  209. $(document).on('click', '.thumb_pic', function() {
  210. let oImg = $(this).parent('.img_group').find('.thumb_pic');
  211. $('#qnaImg').html('');
  212. for (let i = 0; i < oImg.length; i++) {
  213. $('#qnaImg').append('<div class="swiper-slide"><div class="pop_img"><img src="' + oImg.find('img').eq(i).attr("src") + '"/></div></div>');
  214. }
  215. $("#thumb_pic").modal("show");
  216. // 슬라이더_팝업에 이미지슬라이드
  217. var swiper = new Swiper('#thumb_pic .swiper-container.cs_pop', {
  218. observer: true,
  219. observeParents: true,
  220. pagination: {
  221. el: '#thumb_pic .swiper-pagination',
  222. }
  223. });
  224. });
  225. $(document).ready(function() {
  226. $('select').each(function() {
  227. var $this = $(this), numberOfOptions = $(this).children('option').length;
  228. $this.addClass('select_hidden');
  229. $this.wrap('<div class="select"></div>');
  230. $this.after('<div class="select_dress"></div>');
  231. var $dressSelect = $this.next('div.select_dress');
  232. $dressSelect.text($this.children('option').eq(0).text());
  233. var $selList = $('<ul />', {
  234. 'class': 'select_options'
  235. }).insertAfter($dressSelect);
  236. for (var i = 0; i < numberOfOptions; i++) {
  237. $('<li />', {
  238. text: $this.children('option').eq(i).text(),
  239. rel: $this.children('option').eq(i).val(),
  240. class: $this.children('option').eq(i).attr('disabled')
  241. }).appendTo($selList);
  242. }
  243. var $selListItems = $selList.children('li');
  244. $dressSelect.click(function(e) {
  245. e.stopPropagation();
  246. $('div.select_dress.active').not(this).each(function(){
  247. $(this).removeClass('active').next('ul.select_options').hide();
  248. });
  249. $(this).toggleClass('active').next('ul.select_options').toggle();
  250. });
  251. $selListItems.click(function(e) {
  252. e.stopPropagation();
  253. if($(this).hasClass('disabled')){
  254. $this.val($(this).attr('rel',false));
  255. } else {
  256. $dressSelect.text($(this).text()).removeClass('active');
  257. $this.val($(this).attr('rel'));
  258. $selList.hide();
  259. fnChangeCounselClsf($(this).attr('rel'));
  260. }
  261. });
  262. $(document).click(function() {
  263. $dressSelect.removeClass('active');
  264. $selList.hide();
  265. });
  266. });
  267. // 타이틀명
  268. $('#htopTitle').text('고객센터');
  269. // 고객센터 GNB 설정
  270. fnSetCallcenterGnb(2);
  271. fnGetOneToOneQnaCountInfo();
  272. $('#btnQnaMore').trigger('click');
  273. $('#qnaRegisterForm textarea[name=questContent]').bind('input paste', function() {
  274. $(this).trigger('keyup');
  275. });
  276. });
  277. // 더보기
  278. $('#btnQnaMore').on('click', function() {
  279. gagajf.ajaxFormSubmit($('#qnaForm').prop('action'), '#qnaForm', fnGetListCallback);
  280. });
  281. // QNA 콜백함수
  282. var fnGetListCallback = function(result) {
  283. // 목록
  284. if (result.dataList != null && result.dataList.length > 0) {
  285. $.each(result.dataList, function(idx, item) {
  286. let tag = '<li>\n';
  287. tag += ' <div class="fold_head">\n';
  288. tag += ' <a href="javascript:void(0)">\n';
  289. tag += ' <div>\n';
  290. tag += ' <div class="fold_tit">\n';
  291. tag += ' <div class="lap1">\n';
  292. tag += ' <span class="fold_state ' + (item.ansStat == "G060_10" ? "doing" : "done") + '">' + item.ansStatNm + '</span>\n'; //답변완료 : done / 처리중 : doing
  293. tag += ' <span class="prod">' + item.counselClsfNm + '</span>\n';
  294. tag += ' </div>\n';
  295. tag += ' <div class="lap2"><span>' + item.questTitle + '</span></div>\n';
  296. tag += ' </div>\n';
  297. tag += ' <span class="data">' + item.questDt + '</span>\n';
  298. tag += ' </div>\n';
  299. tag += ' </a>\n';
  300. tag += ' </div>\n';
  301. tag += ' <div class="fold_cont">\n';
  302. tag += ' <div class="fold_detail">\n';
  303. tag += ' <div><p>' + item.questContent.replace(/(\r\n)/g, '<br/>') + '</p></div>\n';
  304. if (!gagajf.isNull(item.sysFileNm1) || !gagajf.isNull(item.sysFileNm2)) {
  305. tag += ' <p class="img_group">\n';
  306. if (!gagajf.isNull(item.sysFileNm1)) {
  307. tag += ' <span class="thumb_pic">\n';
  308. // tag += ' <img src="' + _uploadImageUrl + '/counsel/' + item.sysFileNm1 + '" alt="" onerror="this.src=\'/image/bg_profile.png\'">\n';
  309. tag += ' <img src="' + _uploadImageUrl + '/' + item.sysFileNm1 + '" alt="">\n';
  310. tag += ' </span>\n';
  311. }
  312. if (!gagajf.isNull(item.sysFileNm2)) {
  313. tag += ' <span class="thumb_pic">\n';
  314. // tag += ' <img src="' + _uploadImageUrl + '/counsel/' + item.sysFileNm2 + '" alt="" onerror="this.src=\'/image/bg_profile.png\'">\n';
  315. tag += ' <img src="' + _uploadImageUrl + '/' + item.sysFileNm2 + '" alt="">\n';
  316. tag += ' </span>\n';
  317. }
  318. tag += ' </p>\n';
  319. }
  320. if (item.ansStat != 'G060_20') { // 답변완료가 아닐 때
  321. tag += ' <div class="answer_foot">\n';
  322. tag += ' <button type="button" class="btn_delete" onclick="fnDeleteQna(' + item.counselSq + ');"><span>삭제</span></button>\n';
  323. tag += ' </div>\n';
  324. }
  325. tag += ' </div>\n';
  326. if (item.ansStat == 'G060_20') { // 답변완료 상태일 때
  327. tag += ' <div class="fold_answer">\n';
  328. tag += ' <div>\n';
  329. tag += ' <div class="answer_body">' + item.ansContent.replace(/(\r\n)/g, '<br/>') + '</div>\n';
  330. tag += ' <div class="answer_foot">\n';
  331. tag += ' <span class="data">' + item.ansDt + '</span>\n';
  332. tag += ' </div>\n';
  333. tag += ' </div>\n';
  334. tag += ' </div>\n';
  335. }
  336. tag += ' </div>\n';
  337. tag += '</li>\n';
  338. $('#ulQna').append(tag);
  339. });
  340. $('#divQna').removeClass('nodata');
  341. } else {
  342. // let tag = '<li>내역이 없습니다.</li>\n';
  343. // $('#ulQna').append(tag);
  344. $('#divQna').addClass('nodata');
  345. }
  346. if (result.paging.pageable.totalPage > result.paging.pageable.pageNo) {
  347. $('#btnQnaMore').parent().show();
  348. $('#qnaForm input[name=pageNo]').val(result.paging.pageable.pageNo + 1);
  349. } else {
  350. $('#btnQnaMore').parent().hide();
  351. }
  352. }
  353. // 삭제
  354. let fnDeleteQna = function(counselSq) {
  355. mcxDialog.confirm("등록된 내용을 삭제하시겠습니까?", {
  356. cancelBtnText: "취소",
  357. sureBtnText: "확인",
  358. sureBtnClick: function() {
  359. let params = new Object();
  360. params.counselSq = counselSq;
  361. var jsonData = JSON.stringify(params);
  362. gagajf.ajaxJsonSubmit('/callcenter/onetoone/qna/delete'
  363. , jsonData
  364. , function() {
  365. $('#qnaForm input[name=pageNo]').val(1);
  366. $('#ulQna').html('');
  367. $('#btnQnaMore').trigger('click');
  368. fnGetOneToOneQnaCountInfo();
  369. });
  370. }
  371. });
  372. }
  373. // JQUERY를 이용한 버튼 모달 팝업
  374. $(".questionMy").click(function() {
  375. $("#myQuestion").modal("show");
  376. });
  377. // text_area
  378. $('.doc_contactus').keyup(function (e) {
  379. var content = $(this).val();
  380. $('#contactus_cnt').html("(<em class='c_primary'>" + content.length + "</em>/500자)");
  381. if (content.length > 500) {
  382. alert("최대 500자까지 입력 가능합니다.");
  383. $(this).val(content.substring(0, 500));
  384. $('#contactus_cnt').html("(<em class='c_primary'>500</em>/500자)");
  385. }
  386. });
  387. // 파일첨부 선택 시
  388. $('#fileAdd').on('change', function() { fnChooseFile(this); });
  389. $('#fileAdds').on('change', function() { fnChooseFile(this); });
  390. var fnChooseFile = function(obj) {
  391. // multiple 속성이 있으면 files에는 다수의 객체가 할당됨
  392. var file = obj.files[0];
  393. if (!gagajf.isNull(file.name)) {
  394. var extension = "\.(jpg|jpeg|png)$";
  395. if (!(new RegExp(extension, "i")).test(file.name)) {
  396. mcxDialog.alertC('이미지는 [jpg, jpeg, png] 파일만 가능합니다.', {
  397. sureBtnText: "확인",
  398. sureBtnClick: function() {
  399. $(obj).parent('.imgUpload').find('.removes').trigger('click');
  400. }
  401. });
  402. return false;
  403. }
  404. }
  405. if (!gagajf.isNull(file.size) && Number(file.size) > 20 * 1000000) {
  406. mcxDialog.alertC('이미지는 최대 20MB 이하 파일만 가능합니다.', {
  407. sureBtnText: "확인",
  408. sureBtnClick: function() {
  409. $(obj).parent('.imgUpload').find('.removes').trigger('click');
  410. }
  411. });
  412. return false;
  413. }
  414. // 파일 업로드
  415. gagajf.ajaxFileUpload('/common/file/upload?subDir=/counsel'
  416. , file
  417. , function(result) {
  418. // 업로드한 파일명 설정
  419. $(".pics").children().last().append("<input type='hidden' name='orgFileNmArr' value='"+result.oldFileName+"'>");
  420. $(".pics").children().last().append("<input type='hidden' name='sysFileNmArr' value='"+result.newFileName+"'>");
  421. }
  422. );
  423. }
  424. // 저장
  425. $('#btnSaveQna').on('click', function() {
  426. // 입력 값 체크
  427. if (!gagajf.validation('#qnaRegisterForm'))
  428. return false;
  429. mcxDialog.confirm("저장하시겠습니까?", {
  430. cancelBtnText: "취소",
  431. sureBtnText: "확인",
  432. sureBtnClick: function() {
  433. gagajf.ajaxFormSubmit($('#qnaRegisterForm').prop('action')
  434. , '#qnaRegisterForm'
  435. , function() {
  436. cfnGoToPage(_PAGE_ONETOONE_QNA);
  437. }
  438. );
  439. }
  440. });
  441. });
  442. // 문의유형 선택 시
  443. var fnChangeCounselClsf = function(counselClsf) {
  444. var actionUrl = '/callcenter/onetoone/qna/answer/template/' + counselClsf;
  445. $.get(actionUrl
  446. , function(data) {
  447. if (!gagajf.isNull(data)) {
  448. $('textarea[name=questContent]').val(data);
  449. $('.doc_contactus').trigger('keyup');
  450. } else {
  451. // 초기화
  452. $('textarea[name=questContent]').val('');
  453. $('.doc_contactus').trigger('keyup');
  454. }
  455. });
  456. }
  457. let fnGetOneToOneQnaCountInfo = function() {
  458. $.get('/callcenter/onetoone/qna/count/info'
  459. , function(result) {
  460. $('#qnaTotCnt').html(result.totCnt);
  461. $('#qnaAnsCnt').html(result.ansCnt);
  462. $('#qnaIngCnt').html(result.ingCnt);
  463. }
  464. );
  465. }
  466. /*]]>*/
  467. </script>
  468. </th:block>
  469. </body>
  470. </html>