CustomerGradeOrderForm.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. <!DOCTYPE html>
  2. <html lang="ko"
  3. xmlns:th="http://www.thymeleaf.org">
  4. <!--
  5. *******************************************************************************
  6. * @source : CustomerGradeOrderForm.html
  7. * @desc : 등급별주문현황 Page
  8. *============================================================================
  9. * STYLE24
  10. * Copyright(C) 2020 TSIT, All rights reserved.
  11. *============================================================================
  12. * VER DATE AUTHOR DESCRIPTION
  13. * === =========== ========== =============================================
  14. * 1.0 2021.09.28 swkim 최초 작성
  15. *******************************************************************************
  16. -->
  17. <div id="main">
  18. <!-- 메인타이틀 영역 -->
  19. <div class="main-title"></div>
  20. <!-- //메인타이틀 영역 -->
  21. <!-- 메뉴 설명 -->
  22. <div class="infoBox menu-desc"></div>
  23. <!-- //메뉴 설명 -->
  24. <!-- 검색조건 영역 -->
  25. <div class="panelStyle">
  26. <form id="searchForm" name="searchForm" action="#" th:action="@{'/statistics/customer/grade/order/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
  27. <input type="hidden" name="dayGb" value="D"/>
  28. <table class="frmStyle" aria-describedby="검색조건">
  29. <colgroup>
  30. <col style="width:10%;"/>
  31. <col style="width:25%;"/>
  32. <col style="width:10%;"/>
  33. <col/>
  34. </colgroup>
  35. <tr>
  36. <th>기간<i class="required" title="필수" aria-hidden="true"></i></th>
  37. <td colspan="3" id="terms"></td>
  38. </tr>
  39. <tr>
  40. <th>디바이스</th>
  41. <td colspan="3">
  42. <label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="P" checked="checked"/>PC웹</label>
  43. <label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="M" checked="checked"/>모바일웹</label>
  44. <label class="chkBox checked"><input type="checkbox" name="multiFrontGb" value="A" checked="checked"/>APP</label>
  45. </td>
  46. </tr>
  47. <tr>
  48. <th>성별</th>
  49. <td>
  50. <label class="chkBox checked"><input type="checkbox" name="multiSexGb" value="G007_F" checked="checked"/>여성</label>
  51. <label class="chkBox checked"><input type="checkbox" name="multiSexGb" value="G007_M" checked="checked"/>남성</label>
  52. <label class="chkBox checked"><input type="checkbox" name="multiSexGb" value="G007_X" checked="checked"/>알수없음</label>
  53. </td>
  54. <th>연령</th>
  55. <td>
  56. <label class="chkBox checked"><input type="checkbox" name="multiAgeGb" value="10" checked="checked"/>10대</label>
  57. <label class="chkBox checked"><input type="checkbox" name="multiAgeGb" value="20" checked="checked"/>20대</label>
  58. <label class="chkBox checked"><input type="checkbox" name="multiAgeGb" value="30" checked="checked"/>30대</label>
  59. <label class="chkBox checked"><input type="checkbox" name="multiAgeGb" value="40" checked="checked"/>40대</label>
  60. <label class="chkBox checked"><input type="checkbox" name="multiAgeGb" value="X" checked="checked"/>기타/미상</label>
  61. </td>
  62. </tr>
  63. <tr>
  64. <th>브랜드</th>
  65. <td>
  66. <input type="text" class="w100" name="brandCdSearchTxt" id="brandCdSearchTxt" maxlength="20" />
  67. <button type="button" class="btn icn" onclick="cfnOpenBrandListPopup('fnSetBrandInfo', 'M');"><i class="fa fa-search"></i></button>
  68. <span id="brandCdTxt"></span>
  69. <input type="hidden" name="brandCdList"/>
  70. </td>
  71. <th>매출카테고리</th>
  72. <td>
  73. <input type="text" class="w100" name="itemkindCdSearchTxt" id="itemkindCdSearchTxt" maxlength="20" />
  74. <button type="button" class="btn icn" onclick="cfnOpenItemkindListPopup('fnSetItemkindInfo', 'M');"><i class="fa fa-search"></i></button>
  75. <span id="itemkindCdTxt"></span>
  76. <input type="hidden" name="itemkindCdList"/>
  77. </td>
  78. </tr>
  79. </table>
  80. <ul class="panelBar">
  81. <li class="center">
  82. <button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
  83. <button type="button" class="btn btn-gray btn-lg" id="btnInit">초기화</button>
  84. </li>
  85. </ul>
  86. </form>
  87. </div>
  88. <!-- 검색조건 영역 -->
  89. <!-- 차트영역 -->
  90. <div class="panelStyle" id="chartDiv">
  91. <div id="chart" class="chartUnit"></div>
  92. </div>
  93. <!-- //차트영역 -->
  94. <!-- 리스트 영역 -->
  95. <div class="panelStyle">
  96. <ul class="panelBar">
  97. <li>
  98. <button type="button" class="btn btn-default btn-lg" onclick="fnExcelDownLoad();">엑셀다운로드</button>
  99. </li>
  100. </ul>
  101. <div id="gridList" style="width: 100%; height: 470px" class="ag-theme-balham"></div>
  102. </div>
  103. <!-- //리스트 영역 -->
  104. </div>
  105. <style>
  106. .ag-header-group-text{
  107. margin-left: calc(50% - 25px);
  108. }
  109. </style>
  110. <script th:inline="javascript">
  111. /*<![CDATA[*/
  112. let columnDefs = [
  113. { headerName: "등급", field: "custGrade", width: 100, cellClass: 'text-center' },
  114. {
  115. headerName: "주문 현황", field: "", width: 1200, cellClass: 'text-center',
  116. children: [
  117. {headerName: "총매출액(A+B)", field: "totOrdAmt", width: 150, cellClass: 'text-center',
  118. cellRenderer: function(params) {
  119. return gagaAgGrid.toAddComma(params.value);
  120. }
  121. },
  122. {headerName: "매출액(A)", field: "ordAmt", width: 150, cellClass: 'text-center',
  123. cellRenderer: function(params) {
  124. return gagaAgGrid.toAddComma(params.value);
  125. }
  126. },
  127. {headerName: "취/반품액(B)", field: "cnclAmt", width: 150, cellClass: 'text-center',
  128. cellRenderer: function(params) {
  129. return gagaAgGrid.toAddComma(params.value);
  130. }
  131. },
  132. {headerName: "주문수", field: "ordCnt", width: 120, cellClass: 'text-center',
  133. cellRenderer: function(params) {
  134. return gagaAgGrid.toAddComma(params.value);
  135. }
  136. },
  137. {headerName: "취/반품갯수", field: "cnclQty", width: 150, cellClass: 'text-center',
  138. cellRenderer: function(params) {
  139. return gagaAgGrid.toAddComma(params.value);
  140. }
  141. },
  142. {headerName: "기간평균주문수", field: "avgOrdCnt", width: 150, cellClass: 'text-center',
  143. cellRenderer: function(params) {
  144. return gagaAgGrid.toAddComma(params.value);
  145. }
  146. },
  147. {headerName: "평균주문상품개수", field: "avgSellQty", width: 150, cellClass: 'text-center',
  148. cellRenderer: function(params) {
  149. return gagaAgGrid.toAddComma(params.value);
  150. }
  151. },
  152. {headerName: "객단가", field: "custPrice", width: 150, cellClass: 'text-center',
  153. cellRenderer: function(params) {
  154. return gagaAgGrid.toAddComma(params.value);
  155. }
  156. }
  157. ]
  158. }
  159. ];
  160. let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
  161. gridOptions.excelStyles = [
  162. {
  163. id: 'text-center',
  164. dataType: 'string',
  165. font: {size : 10, bold: false}
  166. },
  167. {
  168. id: 'text-left',
  169. dataType: 'string',
  170. font: {size : 10, bold: false}
  171. },
  172. {
  173. id: 'text-right',
  174. dataType: 'number',
  175. font: {size : 10, bold: false}
  176. }
  177. ];
  178. var fnExcelDownLoad = function(){
  179. var totalRows = gridOptions.api.getDisplayedRowCount();
  180. if(totalRows==0){
  181. mcxDialog.alert('조회된 내역이 없습니다.');
  182. return;
  183. }
  184. var date = new Date().format("YYYYMMDDHHmmss");
  185. var params = {
  186. fileName : "등급별주문현황_"+ date,
  187. sheetName: "DATA"
  188. };
  189. gridOptions.api.exportDataAsExcel(params);
  190. }
  191. // 브랜드 조회 팝업에서 호출
  192. var fnSetBrandInfo = function(result) {
  193. var arrBrandCd = [];
  194. var brandCdTxt = "";
  195. var bIndex = 0;
  196. $('#brandCdTxt').html('');
  197. $('#searchForm input[name=brandCdSearchTxt]').val('');
  198. result.forEach(function(brand){
  199. bIndex++;
  200. arrBrandCd.push(brand.brandCd);
  201. });
  202. // 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
  203. if (bIndex == 1) {
  204. $('#searchForm input[name=brandCdSearchTxt]').val(arrBrandCd[0]);
  205. } else {
  206. brandCdTxt = bIndex + " 개";
  207. $('#brandCdTxt').html(brandCdTxt);
  208. }
  209. var jsonData = JSON.stringify(arrBrandCd);
  210. $("#searchForm input[name=brandCdList]").val(arrBrandCd.join(","));
  211. }
  212. // 품목 조회 팝업에서 호출
  213. var fnSetItemkindInfo = function(result) {
  214. var arrItemkindCd = [];
  215. var itemkindCdTxt = "";
  216. var bIndex = 0;
  217. $('#itemkindCdTxt').html('');
  218. $('#searchForm input[name=itemkindCdSearchTxt]').val('');
  219. result.forEach(function(itemkind){
  220. bIndex++;
  221. arrItemkindCd.push(itemkind.itemkindCd);
  222. });
  223. // 조회 값이 하나일 경우 화면에 코드 노출. 그 외는 갯수 처리
  224. if (bIndex == 1) {
  225. $('#searchForm input[name=itemkindCdSearchTxt]').val(arrItemkindCd[0]);
  226. } else {
  227. itemkindCdTxt = bIndex + " 개";
  228. $('#itemkindCdTxt').html(itemkindCdTxt);
  229. }
  230. var jsonData = JSON.stringify(arrItemkindCd);
  231. $("#searchForm input[name=itemkindCdList]").val(arrItemkindCd.join(','));
  232. }
  233. // 검색
  234. $('#btnSearch').on('click', function() {
  235. // 입력 값 체크
  236. if (!gagajf.validation($('#searchForm')))
  237. return false;
  238. gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm', fnCreateTotal);
  239. });
  240. // 합계 생성
  241. let fnCreateTotal = function() {
  242. // Draw chart
  243. fnDrawChart(gagaAgGrid.getAllRowData(gridOptions));
  244. let len = 0;
  245. let totInfo = {};
  246. totInfo.custGrade = 'TOTAL';
  247. totInfo.totOrdAmt = 0;
  248. totInfo.ordAmt = 0;
  249. totInfo.cnclAmt = 0;
  250. totInfo.ordCnt = 0;
  251. totInfo.cnclQty = 0;
  252. totInfo.avgOrdCnt = 0;
  253. totInfo.avgSellQty = 0;
  254. totInfo.custPrice = 0;
  255. gridOptions.api.forEachNode(function(rowNode, index) {
  256. if (!rowNode.group) {
  257. if( typeof rowNode.data.totOrdAmt == 'number') { totInfo.totOrdAmt += rowNode.data.totOrdAmt ; }
  258. if( typeof rowNode.data.ordAmt == 'number') { totInfo.ordAmt += rowNode.data.ordAmt ; }
  259. if( typeof rowNode.data.cnclAmt == 'number') { totInfo.cnclAmt += rowNode.data.cnclAmt ; }
  260. if( typeof rowNode.data.ordCnt == 'number') { totInfo.ordCnt += rowNode.data.ordCnt ; if (rowNode.data.ordCnt > 0) len++; }
  261. if( typeof rowNode.data.cnclQty == 'number') { totInfo.cnclQty += rowNode.data.cnclQty ; }
  262. if( typeof rowNode.data.avgOrdCnt == 'number') { totInfo.avgOrdCnt += rowNode.data.avgOrdCnt ; }
  263. if( typeof rowNode.data.avgSellQty == 'number') { totInfo.avgSellQty += rowNode.data.avgSellQty ; }
  264. if( typeof rowNode.data.custPrice == 'number') { totInfo.custPrice += rowNode.data.custPrice ; }
  265. }
  266. });
  267. totInfo.avgOrdCnt = (Math.round(totInfo.avgOrdCnt / len * 10) / 10);
  268. totInfo.avgSellQty = (Math.round(totInfo.avgSellQty / len * 10) / 10);
  269. totInfo.custPrice = Math.floor(totInfo.custPrice / len);
  270. gagaAgGrid.setPinnedRowData(gridOptions, totInfo, 'top');
  271. }
  272. // 그래프 그리기
  273. var chart1;
  274. var fnDrawChart = function(data) {
  275. let xList = [];
  276. let ordAmtList = [];
  277. $(data).each(function(idx, item) {
  278. xList.push(item.custGrade);
  279. ordAmtList.push(item.ordAmt);
  280. });
  281. chart1 = c3.generate({
  282. bindto: "#chart",
  283. padding: {
  284. bottom: 20 //adjust chart padding bottom
  285. },
  286. data: {
  287. x: 'x',
  288. json: {
  289. x: xList,
  290. 등급별매출액: ordAmtList
  291. },
  292. types: {
  293. 등급별매출액: 'bar'
  294. }/* ,
  295. regions: {
  296. 'data1': [
  297. {
  298. 'start': 1,
  299. 'end': 2,
  300. 'style': 'dashed'
  301. }, {
  302. 'start': 3
  303. }
  304. ]
  305. } */
  306. },
  307. color: {
  308. pattern: ['#48C9B0', '#FF7043', '#FF7043']
  309. },
  310. legend: { padding: 15 }, //범례 item 우측 간격
  311. axis: {
  312. x: {
  313. type: 'category',
  314. padding: { left: 0.5, right: 0.5 }
  315. }/* ,
  316. y: {
  317. tick: {
  318. format: function(d) { return Number(d).addComma() + 'K'; }
  319. }
  320. } */
  321. },
  322. tooltip: {
  323. format: {
  324. title: function (d) {
  325. return '등급별 매출액 Chart';
  326. }
  327. }
  328. }/* ,
  329. bar: {
  330. width: { ratio: 0.2 } // 막대 폭 20%로 조절
  331. } */
  332. });
  333. }
  334. // LNB 또는 GNB 클릭시 차트 넓이 변경
  335. var chartResize = function() {
  336. setTimeout(function () {
  337. // 모든 차트 ID객체에 적용
  338. chart1.resize();
  339. }, 300);
  340. }
  341. // 초기화 클릭시
  342. $('#btnInit').on('click', function() {
  343. $('#searchForm')[0].reset();
  344. $('#brandCdTxt').html('');
  345. $('#searchForm input[name=brandCdList]').val('');
  346. $('#itemkindCdTxt').html('');
  347. $('#searchForm input[name=itemkindCdList]').val('');
  348. });
  349. // 엑셀다운로드
  350. $('#btnExcel').on('click', function() {
  351. gagaAgGrid.exportToExcel('일자별주문 목록', gridOptions);
  352. });
  353. $(document).ready(function() {
  354. cfnCreateCalendar('#terms', 'startDt', 'endDt', true, '주문', undefined, ['btnToday']);
  355. $('.btnYesterday').trigger('click');
  356. // Create a agGrid
  357. gagaAgGrid.createGrid('gridList', gridOptions);
  358. });
  359. /*]]>*/
  360. </script>
  361. </html>