فهرست منبع

통계 => 시간별 매출현황 추가

skyhopes 4 سال پیش
والد
کامیت
23c7c0da56

+ 13 - 0
src/main/java/com/style24/persistence/domain/Statistics.java

@@ -40,6 +40,8 @@ public class Statistics extends TscBaseDomain {
 	private String dayGb;		// 날짜구분(D:일별, W:주별, M:월별)
 	private String startDt;		// 시작일
 	private String endDt;		// 종료일
+	private String compStDt;	// 비교시작일
+	private String compEdDt;	// 비교종료일
 	private String frontGb;	    // 프론트구분
 	private String frontGbP;	// 프론트구분(=디바이스구분)PC웹
 	private String frontGbM;	// 프론트구분(=디바이스구분)모바일웹
@@ -82,6 +84,9 @@ public class Statistics extends TscBaseDomain {
 	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 	private String[] multiFrontGb;	// 화면구분
 
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] dtGb;	// 날짜구분
+
 	// 일일거래내역
 	private Integer ordNo;				// 주문번호
 	private Integer ordDtlNo;			// 주문상세번호
@@ -140,4 +145,12 @@ public class Statistics extends TscBaseDomain {
 	private String formalGb;			// 이월구분
 	private double yoyRate;             // 전년대비 증감율
 
+	private String hour;                //시간
+	private int ordAmt;                 //주문금액
+	private int ordCust;                //주문자수
+	private int cplRate;                //달성율
+	private long custPrice;             //고객단가
+	private long compOrdAmt;            //비교
+
+
 }

+ 87 - 21
src/main/java/com/style24/persistence/mybatis/shop/TsaStatistics.xml

@@ -765,22 +765,56 @@
 		        , SUM(CNCL_AMT) AS CNCL_AMT /*취반품액*/
 		    FROM TB_STAT_ORD_TIME A
 		    WHERE 1=1
-		        /* 직전동기간 */
-		        <![CDATA[
-		        AND A.DAY_TIME >= DATE_ADD(DATE_FORMAT(#{startDt},'%Y-%m-%d'), INTERVAL (DATE_FORMAT('20210901', '%Y%m%d') - DATE_FORMAT('20210906', '%Y%m%d')) -1  DAY)
-		        AND A.DAY_TIME < DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL (DATE_FORMAT('20210901', '%Y%m%d') - DATE_ADD(DATE_FORMAT('20210906', '%Y%m%d'), INTERVAL 1 DAY)) * -1 DAY)
-		        ]]>
-		        /* 전년동기간 */
-		        <![CDATA[
-		        AND A.DAY_TIME >= DATE_ADD(DATE_FORMAT(#{startDt}, '%Y%m%d'), INTERVAL -1 YEAR )
-		        AND A.DAY_TIME < DATE_ADD(DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL 1 DAY), INTERVAL -1 YEAR )
-		        ]]>
-
-		        /* 직접선택 */
-		        <![CDATA[
-		        AND A.DAY_TIME >= DATE_FORMAT(#{startDt}, '%Y%m%d')
-		        AND A.DAY_TIME < DATE_FORMAT(#{endDt}, '%Y%m%d')
-		        ]]>
+		    	<if test="dtGb != null">
+					<foreach collection="dtGb" item="item" index="index">
+						<if test="item == 'COMPARE_TERMS'">
+					        <![CDATA[
+					        /* 직전동기간 */
+					        AND A.DAY_TIME >= DATE_ADD(DATE_FORMAT(#{compStDt},'%Y-%m-%d'), INTERVAL (DATE_FORMAT(#{compStDt}, '%Y%m%d') - DATE_FORMAT(#{compEdDt}, '%Y%m%d')) -1  DAY)
+					        AND A.DAY_TIME < DATE_ADD(DATE_FORMAT(#{compEdDt}, '%Y%m%d'), INTERVAL (DATE_FORMAT(#{compStDt}, '%Y%m%d') - DATE_ADD(DATE_FORMAT(#{compEdDt}, '%Y%m%d'), INTERVAL 1 DAY)) * -1 DAY)
+					        ]]>
+						</if>
+						<if test="item == 'YOY'">
+					        <![CDATA[
+					        /* 전년비교 */
+					        AND A.DAY_TIME >= DATE_ADD(DATE_FORMAT(#{startDt}, '%Y%m%d'), INTERVAL -1 YEAR )
+					        AND A.DAY_TIME < DATE_ADD(DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL 1 DAY), INTERVAL -1 YEAR )
+					        ]]>
+						</if>
+					</foreach>
+				</if>
+				<if test="multiFrontGb != null">
+					/* 디바이스 */
+					<foreach collection="multiFrontGb" item="item" index="index"  open="AND A.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiFormalGb != null">
+					/* 정상/이월구분 */
+					<foreach collection="multiFormalGb" item="item" index="index"  open="AND A.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiDistributionGb != null">
+					/* 물류구분 */
+					<foreach collection="multiDistributionGb" item="item" index="index"  open="AND A.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiSupplyCompCd != null">
+					/* 공급처 */
+					<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND A.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiItemkindCd != null">
+					/* 품목 */
+					<foreach collection="multiItemkindCd" item="item" index="index"  open="AND A.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiExtmallId != null">
+					/* 제휴몰 */
+					<foreach collection="multiExtmallId" item="item" index="index"  open="AND A.EXTMALL_ID IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiAfLinkCd != null">
+					/* 채널 */
+					<foreach collection="multiAfLinkCd" item="item" index="index"  open="AND A.AF_LINK_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
+				<if test="multiBrandCd != null">
+					/* 브랜드 */
+					<foreach collection="multiBrandCd" item="item" index="index"  open="AND A.BRAND_CD IN (" close=")" separator=",">#{item}</foreach>
+				</if>
 		        AND A.SHOT_DELV_YN = 'Y' /*총알배송*/
 		    GROUP BY HOUR
 		)
@@ -807,11 +841,43 @@
 		        , SUM(CNCL_AMT) AS CNCL_AMT /*취반품액*/
 		    FROM TB_STAT_ORD_TIME A
 		    WHERE 1=1
-		      <![CDATA[
-		      AND A.DAY_TIME >= DATE_FORMAT(#{startDt}, '%Y%m%d')
-		      AND A.DAY_TIME < DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL 1 DAY)
-		      ]]>
-		      AND A.SHOT_DELV_YN = 'Y' -- 총알배송
+		    <![CDATA[
+		    AND A.DAY_TIME >= DATE_FORMAT(#{startDt}, '%Y%m%d')
+		    AND A.DAY_TIME < DATE_ADD(DATE_FORMAT(#{endDt}, '%Y%m%d'), INTERVAL 1 DAY)
+		    ]]>
+			<if test="multiFrontGb != null">
+				/* 디바이스 */
+				<foreach collection="multiFrontGb" item="item" index="index"  open="AND A.FRONT_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiFormalGb != null">
+				/* 정상/이월구분 */
+				<foreach collection="multiFormalGb" item="item" index="index"  open="AND A.FORMAL_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiDistributionGb != null">
+				/* 물류구분 */
+				<foreach collection="multiDistributionGb" item="item" index="index"  open="AND A.DISTRIBUTION_GB IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiSupplyCompCd != null">
+				/* 공급처 */
+				<foreach collection="multiSupplyCompCd" item="item" index="index"  open="AND A.SUPPLY_COMP_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiItemkindCd != null">
+				/* 품목 */
+				<foreach collection="multiItemkindCd" item="item" index="index"  open="AND A.ITEMKIND_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiExtmallId != null">
+				/* 제휴몰 */
+				<foreach collection="multiExtmallId" item="item" index="index"  open="AND A.EXTMALL_ID IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiAfLinkCd != null">
+				/* 채널 */
+				<foreach collection="multiAfLinkCd" item="item" index="index"  open="AND A.AF_LINK_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+			<if test="multiBrandCd != null">
+				/* 브랜드 */
+				<foreach collection="multiBrandCd" item="item" index="index"  open="AND A.BRAND_CD IN (" close=")" separator=",">#{item}</foreach>
+			</if>
+
 		    GROUP BY HOUR
 		) A
 		LEFT OUTER JOIN TAB B ON A.HOUR = B.HOUR

+ 114 - 67
src/main/webapp/WEB-INF/views/statistics/HourlyTradingForm.html

@@ -39,6 +39,14 @@
 						<th>기간<i class="required" title="필수" aria-hidden="true"></i></th>
 						<td colspan="3" id="terms"></td>
 					</tr>
+					<tr>
+						<th>비교기간<i class="required" title="필수" aria-hidden="true"></i></th>
+						<td colspan="3">
+							<label class="chkBox checked"><input type="checkbox" name="dtGb" value="COMPARE_TERMS"/>직전 동일 기간 비교</label>
+							<label class="chkBox checked"><input type="checkbox" name="dtGb" value="YOY"/>전년 비교</label>
+							<span id="compTerms"></span>
+						</td>
+					</tr>
 					<tr>
 						<th>디바이스</th>
 						<td>
@@ -54,31 +62,6 @@
 							<input type="hidden" name="extmallIdList"/>
 						</td>
 					</tr>
-					<tr>
-						<th>물류구분</th>
-						<td>
-							<label class="chkBox checked"><input type="checkbox" name="multiDistributionGb" value="SCM" checked="checked"/>입점</label>
-							<label class="chkBox checked"><input type="checkbox" name="multiDistributionGb" value="WMS" checked="checked"/>위탁</label>
-						</td>
-						<th></th>
-						<td></td>
-					</tr>
-					<tr>
-						<th>공급업체</th>
-						<td>
-							<input type="text" class="w100" name="supplyCompCdSearchTxt" id="supplyCompCdSearchTxt" maxlength="20"/>
-							<button type="button" class="btn icn" onclick="cfnOpenCompanyListPopup('fnSetSupplyCompInfo', 'M');"><i class="fa fa-search"></i></button>
-							<span id="supplyCompCdTxt"></span>
-							<input type="hidden" name="supplyCompCdList"/>
-						</td>
-						<th>제휴채널</th>
-						<td>
-							<input type="text" class="w100" name="afLinkCdSearchTxt" id="afLinkCdSearchTxt" maxlength="20" />
-							<button type="button" class="btn icn" onclick="cfnOpenAfLinkListPopup('fnSetAfLinkInfo', 'M');"><i class="fa fa-search"></i></button>
-							<span id="afLinkCdTxt"></span>
-							<input type="hidden" name="afLinkCdList"/>
-						</td>
-					</tr>
 					<tr>
 						<th>브랜드</th>
 						<td>
@@ -107,6 +90,12 @@
 		</div>
 		<!-- 검색조건 영역 -->
 
+		<!-- 차트영역 -->
+		<div class="panelStyle" id="chartDiv" style="display:none;">
+			<div id="chart" class="chartUnit"></div>
+		</div>
+		<!-- //차트영역 -->
+
 		<!-- 리스트 영역 -->
 		<div class="panelStyle">
 			<ul class="panelBar">
@@ -127,68 +116,63 @@
 <script th:inline="javascript">
 /*<![CDATA[*/
 	let columnDefs = [
-		{ headerName: "브랜드번호", field: "brandCd", width: 100, cellClass: 'text-center' },
-		{ headerName: "브랜드명", field: "brandEnm", width: 180, cellClass: 'text-center'},
-		{ headerName: "브랜드 매출액", field: "", width: 120, cellClass: 'text-center',
+		{ headerName: "시간", field: "hour", width: 100, cellClass: 'text-center'},
+		{ headerName: "매출현황", field: "", width: 100, cellClass: 'text-center',
 			children: [
-				{headerName: "총매출액(A+B+C)", field: "totAmt", width: 120, cellClass: 'text-center',
+				{headerName: "시간 별 매출액", field: "ordAmt", width: 120, cellClass: 'text-right',
 					cellRenderer: function(params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-				{headerName: "판매 개수", field: "sellQty", width: 120, cellClass: 'text-left',
+				{headerName: "비교(A)", field: "compOrdAmt", width: 120, cellClass: 'text-right',
 					cellRenderer: function(params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-				{headerName: "YOY(%)", field: "yoyRate", width: 100, cellClass: 'text-left',
+				{headerName: "달성율(%)", field: "cplRate", width: 120, cellClass: 'text-right',
 					cellRenderer: function(params) {
-						return params.value +'%';
+						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
 			]
 		},
-		{ headerName: "매출 현황", field: "", width: 100, cellClass: 'text-center',
+		{ headerName: "주문 현황", field: "", width: 100, cellClass: 'text-center',
 			children: [
-				{headerName: "자사몰 매출액(A)", field: "selfmallAmt", width: 120, cellClass: 'text-right',
+				{headerName: "주문자수", field: "ordCust", width: 150, cellClass: 'text-right',
 					cellRenderer: function (params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-				{headerName: "제휴몰 매출액(B)", field: "extmallAmt", width: 150, cellClass: 'text-right',
+				{headerName: "주문 수", field: "ordCnt", width: 150, cellClass: 'text-right',
 					cellRenderer: function (params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-				{headerName: "취/반품액(C)", field: "cnclAmt", width: 150, cellClass: 'text-right',
+				{headerName: "판매수", field: "sellQty", width: 150, cellClass: 'text-right',
 					cellRenderer: function (params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-			]
-		},
-		{ headerName: "정상이월 결제비중", field: "", width: 100, cellClass: 'text-center',
-			children: [
-				{headerName: "정상", field: "totAmt10", width: 150, cellClass: 'text-right',
+				{headerName: "객단가", field: "custPrice", width: 150, cellClass: 'text-right',
 					cellRenderer: function (params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-				{headerName: "이월", field: "totAmt20", width: 120, cellClass: 'text-right',
+				{headerName: "취/반품갯수", field: "cnclQty", width: 150, cellClass: 'text-right',
 					cellRenderer: function (params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
 				},
-				{headerName: "정상비", field: "amtRate10", width: 120, cellClass: 'text-right',
+				{headerName: "취/반품액", field: "cnclAmt", width: 150, cellClass: 'text-right',
 					cellRenderer: function (params) {
 						return !gagajf.isNull(params.value) ? params.value.addComma() : '0';
 					}
-				}
+				},
 			]
 		},
 	];
 
-	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
 
 	// Row Click
 	gridOptions.onCellClicked = function(event) {
@@ -372,38 +356,98 @@
 	// 합계 생성
 	let fnCreateTotal = function() {
 
+		// Draw chart
+		fnDrawChart(gagaAgGrid.getAllRowData(gridOptions));
+		$("#chartDiv").show();
+
 		let totInfo = {};
-		totInfo.brandCd     = 'TOTAL';
-		totInfo.totAmt      = 0;
-		totInfo.sellQty     = 0;
-		totInfo.selfmallAmt = 0;
-		totInfo.extmallAmt  = 0;
-		totInfo.cnclAmt     = 0;
-		totInfo.totAmt10    = 0;
-		totInfo.totAmt20    = 0;
-		totInfo.amtRate10   = 0;
-		totInfo.yoyRate     = 0;
-		totInfo.yoyTotOrdAmt= 0;
+		totInfo.hour       = 'TOTAL';
+		totInfo.ordAmt     = 0;
+		totInfo.compOrdAmt = 0;
+		totInfo.cplRate    = 0;
+		totInfo.ordCust    = 0;
+		totInfo.ordCnt     = 0;
+		totInfo.sellQty    = 0;
+		totInfo.custPrice  = 0;
+		totInfo.cnclQty    = 0;
+		totInfo.cnclAmt	   = 0;
+
 
 		gridOptions.api.forEachNode(function(rowNode, index) {
 			if (!rowNode.group) {
-				if( typeof rowNode.data.totAmt      == 'number') { totInfo.totAmt       += rowNode.data.totAmt      ; }
-				if( typeof rowNode.data.sellQty     == 'number') { totInfo.sellQty      += rowNode.data.sellQty     ; }
-				if( typeof rowNode.data.selfmallAmt == 'number') { totInfo.selfmallAmt  += rowNode.data.selfmallAmt ; }
-				if( typeof rowNode.data.extmallAmt  == 'number') { totInfo.extmallAmt   += rowNode.data.extmallAmt  ; }
-				if( typeof rowNode.data.cnclAmt     == 'number') { totInfo.cnclAmt      += rowNode.data.cnclAmt     ; }
-				if( typeof rowNode.data.totAmt10    == 'number') { totInfo.totAmt10     += rowNode.data.totAmt10    ; }
-				if( typeof rowNode.data.totAmt20    == 'number') { totInfo.totAmt20     += rowNode.data.totAmt20    ; }
-				if( typeof rowNode.data.amtRate10   == 'number') { totInfo.amtRate10    += rowNode.data.amtRate10   ; }
-				if( typeof rowNode.data.yoyTotOrdAmt== 'number') { totInfo.yoyTotOrdAmt += rowNode.data.yoyTotOrdAmt; }
+				if( typeof rowNode.data.ordAmt     == 'number') { totInfo.ordAmt      += rowNode.data.ordAmt     ; }
+				if( typeof rowNode.data.compOrdAmt == 'number') { totInfo.compOrdAmt  += rowNode.data.compOrdAmt ; }
+				if( typeof rowNode.data.cplRate    == 'number') { totInfo.cplRate     += rowNode.data.cplRate    ; }
+				if( typeof rowNode.data.ordCust    == 'number') { totInfo.ordCust     += rowNode.data.ordCust    ; }
+				if( typeof rowNode.data.ordCnt     == 'number') { totInfo.ordCnt      += rowNode.data.ordCnt     ; }
+				if( typeof rowNode.data.sellQty    == 'number') { totInfo.sellQty     += rowNode.data.sellQty    ; }
+				if( typeof rowNode.data.custPrice  == 'number') { totInfo.custPrice   += rowNode.data.custPrice  ; }
+				if( typeof rowNode.data.cnclQty    == 'number') { totInfo.cnclQty     += rowNode.data.cnclQty    ; }
+				if( typeof rowNode.data.cnclAmt	   == 'number') { totInfo.cnclAmt	  += rowNode.data.cnclAmt	 ; }
 			}
 		});
 
-		totInfo.yoyRate = (totInfo.totAmt / totInfo.yoyTotOrdAmt * 100 - 100).toFixed(1);
-
 		gagaAgGrid.setPinnedRowData(gridOptions, totInfo, 'top');
 	}
 
+	// 그래프 그리기
+	var chart1;
+	var fnDrawChart = function(data) {
+		let xList = [];
+		let totOrdAmtList = [];
+		let compOrdAmtList = [];
+
+		for(var i in data){
+			xList.push(data[i].hour);
+			totOrdAmtList.push(data[i].ordAmt);
+			compOrdAmtList.push(data[i].compOrdAmt);
+		}
+
+		chart1 = c3.generate({
+			bindto: "#chart",
+			padding: {
+				bottom: 20 //adjust chart padding bottom
+			},
+			data: {
+				x: 'x',
+				json: {
+					x: xList,
+					결제액: totOrdAmtList,
+					비교기간결제액: compOrdAmtList
+				},
+				types: {
+					결제액: 'bar',
+					비교기간결제액: 'line'
+				}
+			},
+			color: {
+				pattern: ['#48C9B0', '#FF7043']
+			},
+			legend: { padding: 15 }, //범례 item 우측 간격
+			axis: {
+				x: {
+					type: 'category',
+					padding: { left: 0.5, right: 0.5 }
+				}
+			},
+			tooltip: {
+				format: {
+					title: function (d) {
+						return '시간별 주문 통계 Chart';
+					}
+				}
+			}
+		});
+	}
+
+	// LNB 또는 GNB 클릭시 차트 넓이 변경
+	var chartResize = function() {
+		setTimeout(function () {
+			// 모든 차트 ID객체에 적용
+			chart1.resize();
+		}, 300);
+	}
+
 	// 초기화 클릭시
 	$('#btnInit').on('click', function() {
 		$('#searchForm')[0].reset();
@@ -423,6 +467,9 @@
 	$(document).ready(function() {
 		cfnCreateCalendar('#terms', 'startDt', 'endDt', true, '주문', undefined, ['btnToday']);
 		$('.btnYesterday').trigger('click');
+		cfnCreateCalendar('#compTerms', 'compStDt', 'compEdDt', true, '주문', undefined, ['btnToday']);
+		$('.btnYesterday').trigger('click');
+
 
 		// Create a agGrid
 		gagaAgGrid.createGrid('gridList', gridOptions);