Files
hubez-admin/frontend/src/modules/stats/views/BsnmMonthList.vue

519 lines
16 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">사업자별 통계</h3>
<p class="breadcrumb">발송통계 &gt; 사업자별 통계</p>
</div>
<div class="top_tab">
<a href="javascript:void(0);" class="on">월별통계</a>
<a href="javascript:void(0);" @click="toMove('bsnmDayList')">일별통계</a>
</div>
<div class="search_wrap">
<div class="input_box cal">
<label for="right" class="label txt">조회기간</label>
<p>최대 3개월까지 조회 가능합니다.</p>
<div class="term">
<div class="group" style="width: 500px">
<span class="custom_input icon_date">
<vuejs-datepicker
:language="ko"
:format="customFormatter"
:disabled-dates="disabledSDate"
:minimumView="sDateDiv"
:maximumView="sDateDiv"
v-model="startDate"
@selected="selectedStartDate"
@closed="closeDate('start')"
></vuejs-datepicker> </span
>~
<span class="custom_input icon_date">
<vuejs-datepicker
:language="ko"
:format="customFormatter"
:disabled-dates="disabledEDate"
:minimumView="sDateDiv"
:maximumView="sDateDiv"
v-model="endDate"
@selected="selectedEndDate(0)"
@closed="closeDate('end')"
></vuejs-datepicker>
</span>
</div>
</div>
</div>
<div class="input_box id">
<label for="name" class="label">고객사명</label>
<input
class="search-box"
type="text"
id="name"
placeholder="검색어 입력"
v-model.trim="grid.params.custNm"
maxlength="100"
@keypress.enter="search"
/>
</div>
<div class="input_box">
<label for="name" class="label">사업자번호</label>
<input
class="search-box"
type="text"
id="name"
placeholder="검색어 입력"
v-model.trim="grid.params.bizrno"
@keypress.enter="search"
@keypress="onlyNum"
@input="onlyNum"
minlength="10"
maxlength="10"
/>
</div>
<button type="button" class="button grey" @click="search">조회</button>
</div>
<div class="info">
<div class="count">집계결과</div>
<div class="button_group">
<button type="button" class="button blue download" @click="monthExcelDown()">엑셀 다운로드</button>
</div>
</div>
<div class="table calculate scroll">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="grid.url"
:pagePerRows="grid.pagePerRows"
:initialRequest="grid.initialRequest"
:pagination="grid.pagination"
:isCheckbox="grid.isCheckbox"
:columns="grid.columns"
:noDataStr="grid.noDataStr"
:addCls="grid.addCls"
:header="grid.header"
></custom-grid>
</div>
<common-modal ref="commmonModal"></common-modal>
</div>
</div>
</template>
<script>
import moment from 'moment';
import statsApi from '../service/statsApi.js';
import customGrid from '@/components/CustomGrid';
import xlsx from '@/common/excel';
import commonModal from '@/components/modal/commonModal';
import { utils_mixin, chkPattern2 } from '../service/mixins';
export default {
name: 'bsnmMonthList',
mixins: [utils_mixin, chkPattern2],
data() {
return {
// 달력 데이터
ko: vdp_translation_ko.js,
periodDay: 7,
sDateDiv: 'month',
startDate: new Date(),
endDate: new Date(),
startDt: '',
endDt: '',
startYear: '',
startMonth: '',
endYear: '',
endMonth: '',
row: {},
list: [],
totalCnt: '',
pageType: 'BSNM_MONTH',
// 테이블 리스트 데이터
perPageCnt: 50,
options: [
{ text: '20', value: 20 },
{ text: '50', value: 50 },
{ text: '100', value: 100 },
],
totalItems: 0,
grid: {
url: '/api/v1/bo/stats/bsnmMonthList',
pagePerRows: 20,
pagination: true,
isCheckbox: false, // true:첫번째 컬럼 앞에 체크박스 생성 / false:체크박스 제거
initialRequest: false,
addCls: 'box_OFvis',
header: [
[
{ header: '날짜', childNames: [] },
{ header: '고객사명', childNames: [] },
{ header: '사업자번호', childNames: [] },
{ header: '전체', childNames: ['sndCnt', 'succCntRt'] },
{ header: 'SMS', childNames: ['sndCntS', 'succCntRtS'] },
{ header: 'LMS', childNames: ['sndCntL', 'succCntRtL'] },
{ header: 'MMS', childNames: ['sndCntM', 'succCntRtM'] },
{ header: '알림톡', childNames: ['sndCntR', 'succCntRtR'] },
],
],
columns: [
{ name: 'sumYm', header: '날짜', align: 'center', width: '8%' },
{ name: 'custNm', header: '고객사명', align: 'center', width: '12%' },
{
name: 'bizrno',
header: '사업자번호',
align: 'center',
width: '8%',
// , formatter: props => {
// let result = props.bizrno.substring(0, 3) + '-' + props.bizrno.substring(3, 5) + '-' + props.bizrno.substring(5, 10)
// return result;
// }
},
{
name: 'sndCnt',
header: '발송건수',
align: 'center',
cls: 'td_line',
formatter: (props) => {
let result = props.sndCnt.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return result;
},
width: '7%',
},
{
name: 'succCntRt',
header: '성공건수/(%)',
align: 'center',
cls: 'td_line',
formatter: (props) => {
return (
'<p>' +
props.succCnt.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') +
'</p>\n<p>(' +
props.succRt +
'%)</p>'
);
},
width: '7%',
},
{
name: 'sndCntS',
header: '발송건수',
align: 'center',
cls: 'td_line',
formatter: (props) => {
let result = props.sndCntS.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return result;
},
width: '7%',
},
{
name: 'succCntRtS',
header: '성공건수/(%)',
align: 'center',
cls: 'td_line',
formatter: (props) => {
return (
'<p>' +
props.succCntS.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') +
'</p>\n<p>(' +
props.succRtS +
'%)</p>'
);
},
width: '7%',
},
{
name: 'sndCntL',
header: '발송건수',
align: 'center',
cls: 'td_line',
formatter: (props) => {
let result = props.sndCntL.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return result;
},
width: '7%',
},
{
name: 'succCntRtL',
header: '성공건수/(%)',
align: 'center',
cls: 'td_line',
formatter: (props) => {
return (
'<p>' +
props.succCntL.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') +
'</p>\n<p>(' +
props.succRtL +
'%)</p>'
);
},
width: '7%',
},
{
name: 'sndCntM',
header: '발송건수',
align: 'center',
cls: 'td_line',
formatter: (props) => {
let result = props.sndCntM.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return result;
},
width: '7%',
},
{
name: 'succCntRtM',
header: '성공건수/(%)',
align: 'center',
cls: 'td_line',
formatter: (props) => {
return (
'<p>' +
props.succCntM.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') +
'</p>\n<p>(' +
props.succRtM +
'%)</p>'
);
},
width: '7%',
},
{
name: 'sndCntR',
header: '발송건수',
align: 'center',
cls: 'td_line',
formatter: (props) => {
let result = props.sndCntR.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return result;
},
width: '7%',
},
{
name: 'succCntRtR',
header: '성공건수/(%)',
align: 'center',
cls: 'td_line',
formatter: (props) => {
return (
'<p>' +
props.succCntR.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') +
'</p>\n<p>(' +
props.succRtR +
')</p>'
);
},
width: '7%',
},
],
noDataStr: '검색 결과가 없습니다.',
params: {
startMon: '',
endMon: '',
},
excelHeader: [],
},
};
},
components: {
customGrid: customGrid,
commonModal,
vuejsDatepicker,
},
created() {
this.setPeriodDay(0);
this.getExcelHeader();
},
destroyed() {
this.grid.params.custNm = '';
this.grid.params.bizrno = '';
},
mounted() {
let page = 1;
// 페이지 정보 및 검색 조건
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
// store에 저장된 페이지 정보 및 검색 조건을 불러오기
let isKeep = false;
if (getCondition) {
this.grid.pagePerRows = getCondition.perPage;
this.grid.params = getCondition.params;
page = getCondition.page;
isKeep = true;
}
this.search(isKeep);
},
beforeRouteLeave(to, from, next) {
const getP = this.$refs.table.getPagination();
this.$store.commit('searchcondition/updateSearchCondition', {
page: getP._currentPage,
perPage: this.perPageCnt,
params: this.grid.params,
});
// 라우트 하기전 실행
next();
},
methods: {
search: function (isKeep) {
this.grid.params = {
startMon: moment(this.startDate).format('YYYYMM'),
endMon: moment(this.endDate).format('YYYYMM'),
custNm: this.grid.params.custNm,
bizrno: this.grid.params.bizrno,
};
if (
moment(this.grid.params.startMon).isBefore(
moment(this.grid.params.endMon).subtract(2, 'months').format('YYYYMM')
)
) {
this.row.title = '발송통계';
this.row.msg1 = '검색 기간은 최대 3개월까지 선택 가능 합니다.';
this.$refs.commmonModal.alertModalOpen(this.row);
return false;
}
this.$refs.table.search(this.grid.params, isKeep);
this.sendStoreData();
},
toMove(routeName) {
this.$router.push({ name: routeName, params: { page: 1, searchText: '' } });
},
setPeriodDay(day) {
this.periodDay = day;
this.endDate = new Date();
this.initSetStartDate();
this.closeDate('start');
this.closeDate('end');
},
selectedStartDate(day) {
if (day != undefined && day != null) {
this.periodDay = day;
}
if (this.startDate > this.endDate) {
this.startDate = this.endDate;
}
const todayDate = new Date();
let selectDay = new Date(day);
let after3Month = new Date(selectDay.setMonth(selectDay.getMonth() + 2));
if (after3Month > todayDate) {
this.endDate = new Date();
} else {
this.endDate = after3Month;
}
},
selectedEndDate(day) {
if (day != undefined && day != null) {
this.periodDay = day;
}
},
closeDate(type) {
if (type != undefined && type != null) {
if (type == 'start') {
this.disabledSDate = { from: new Date() };
this.disabledEDate = { to: this.startDate, from: this.endDate };
} else if (type == 'end') {
let stDate = new Date(this.startDate);
let fromDate = new Date(stDate.setMonth(stDate.getMonth() + 2));
let endDate = this.endDate;
const nowDate = new Date();
let selectedEndDate = endDate.getMonth() + 2;
if (Number(selectedEndDate) > Number(nowDate.getMonth())) {
this.disabledSDate = { from: new Date() };
this.disabledEDate = { to: this.startDate, from: new Date() };
} else {
this.disabledSDate = { from: new Date() };
this.disabledEDate = { to: this.startDate, from: fromDate };
}
}
}
},
customFormatter: function (date) {
if (this.sDateDiv == 'month') {
return moment(date).format('YYYY-MM');
} else if (this.sDateDiv == 'year') {
return moment(date).format('YYYY');
} else {
return moment(date).format('YYYY-MM-DD');
}
},
changePerPage: function () {
// 페이지당 조회할 개수
this.grid.pagePerRows = this.perPageCnt;
this.search(true);
},
sendStoreData: function () {
const getP = this.$refs.table.getPagination();
this.$store.commit('searchcondition/updateSearchCondition', {
page: getP._currentPage,
perPage: this.perPageCnt,
params: this.grid.params,
});
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
},
initSetStartDate() {
let initStartDate = new Date();
initStartDate.setMonth(Number(moment(initStartDate).format('MM')) - 3);
this.startDate = initStartDate;
},
getExcelHeader() {
// 헤더를 mockup으로 관리한다.
statsApi.getExcelHeader(this.pageType).then((res) => {
this.excelHeader = res;
});
},
async getExcelDataDown() {
try {
let response;
response = await statsApi.bsnmMonthListExcel(this.grid.params);
const result = response.data;
// entity code 변환
result.data.list = result.data.list.map((item) => {
return {
...item,
custNm: this.fromHtmlEntities(item.custNm),
};
});
if (result != null && result.retCode == '0000') {
return result.data;
} else {
return false;
}
} catch (err) {
return false;
}
}, // end of getExcelDataDown
async monthExcelDown() {
if (this.$refs.table.getData().length <= 0) {
this.row.title = '사업자별 월별통계';
this.row.msg1 = '조회된 데이터가 없습니다.';
this.$refs.commmonModal.alertModalOpen(this.row);
return false;
}
let today = moment().format('YYYYMMDDHHmmss');
const saveFileName = `사업자별 월별통계_${today}.xls`;
const data = await this.getExcelDataDown();
let options = {
header: this.excelHeader,
dataOrder: 'header',
};
xlsx.export(data.list, saveFileName, options).then(() => {});
},
fromHtmlEntities(str) {
return (str + '').replace(/&#\d+;/gm, function (s) {
return String.fromCharCode(s.match(/\d+/gm)[0]);
});
},
},
};
</script>