File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div class="content overflow-y">
<!-- 가입현황차트 -->
<div class="chart-zone mb15">
<div class="flex justify-between align-center mb10">
<div class="admin-sec-title">
<p>회원가입 현황</p>
</div>
<div class="gd-1">
<button class="large-btn green-border-btn" v-if="pageAuth.fileDwnldAuthrtYn == 'Y'" @click="fnDownload">
EXCEL 다운로드</button>
</div>
</div>
<div class="box pd20" style="height:400px">
<div class="flex justify-end align-center mb10">
<div class="gd-1">
<select name="" id="" class="full-select" v-model="search.searchType" @change="changeType">
<option value="day">일별</option>
<option value="month">월별</option>
<option value="year">연도별</option>
</select>
</div>
<div class="flex align-center">
<div>
<input v-if="search.searchType === 'day'" type="date" name="" id="" style="width: 155px;"
v-model="search.startDt" :max="search.endDt" />
<input v-else-if="search.searchType === 'month'" type="month" class="full-input" v-model="search.startDt"
:max="search.endDt" />
<select v-else name="" id="" class="full-select ml0" v-model="search.startDt">
<option v-for="(year, idx) in years" :key="idx" :value=year>{{ year }}</option>
</select>
</div>
<div class="pd10">-</div>
<div>
<input v-if="search.searchType === 'day'" type="date" class="full-input" v-model="search.endDt"
:min="search.startDt" :max="today" />
<input v-else-if="search.searchType === 'month'" type="month" class="full-input" v-model="search.endDt"
:min="search.startDt" :max="thisMonth" />
<select v-else name="" id="" class="full-select ml0" v-model="search.endDt">
<option v-for="(year, idx) in years" :key="idx" :value=year>{{ year }}</option>
</select>
</div>
</div>
<div class="gd-1">
<button class="large-btn blue-border-btn" @click="joinStatsProc">조회</button>
</div>
</div>
<div class="chart-wrap" ref="chartdiv" style="height:calc(100% - 54px)">
<LineChart :chartData="lineChartData" columnX="date" />
</div>
</div>
</div>
<!-- 회원통계 -->
<div class="mb15">
<div class="admin-sec-title">
<p class="mb10">회원통계</p>
</div>
<div class="flex mb20">
<div class="gd-4">
<div class="box pd10">
<p class="box-title mb10">일반회원</p>
<p class="banner-title text-rg">{{ $comma(join.users) }}<span class="small-text gray"> 명</span></p>
</div>
</div>
<div class="gd-4">
<div class="box pd10">
<p class="box-title mb10">기업회원</p>
<p class="banner-title text-rg">{{ $comma(join.couser) }}<span class="small-text gray"> 명</span></p>
</div>
</div>
<div class="gd-4">
<div class="box pd10">
<p class="box-title mb10">기업관리자</p>
<p class="banner-title text-rg">{{ $comma(join.comanager) }}<span class="small-text gray"> 명</span></p>
</div>
</div>
</div>
<div class="flex">
<div class="gd-6">
<div class="box pd10">
<p class="box-title mb10">구독 신청 회원</p>
<p class="banner-title text-rg">{{ $comma(trms.rcptnagre) }}<span class="small-text gray"> 명</span></p>
</div>
</div>
<div class="gd-6">
<div class="box pd10">
<p class="box-title mb10">개인정보동의 회원</p>
<p class="banner-title text-rg">{{ $comma(trms.prvsrls) }}<span class="small-text gray"> 명</span></p>
</div>
</div>
</div>
</div>
<!-- 기업통계 -->
<div class="mb15">
<div class="admin-sec-title point-font2">
<p class="mb10">기업통계</p>
</div>
<div class="flex mb20">
<div style="width: 20%; padding: 0 1rem;">
<div class="box pd10">
<p class="box-title point-font2 mb10">가입한 기업</p>
<p class="banner-title text-rg">{{ $comma(ent.total) }}<span class="small-text gray"> 사</span></p>
</div>
</div>
<div style="width: 20%; padding: 0 1rem;">
<div class="box pd10">
<p class="box-title point-font2 mb10">승인 요청</p>
<p class="banner-title text-rg">{{ $comma(ent.aprv) }}<span class="small-text gray"> 사</span></p>
</div>
</div>
<div style="width: 20%; padding: 0 1rem;">
<div class="box pd10">
<p class="box-title point-font2 mb10">출원 예정사</p>
<p class="banner-title text-rg">{{ $comma(ent.applprnmnt) }}<span class="small-text gray"> 사</span></p>
</div>
</div>
<div style="width: 20%; padding: 0 1rem;">
<div class="box pd10">
<p class="box-title point-font2 mb10">주 출원사</p>
<p class="banner-title text-rg">{{ $comma(ent.main) }}<span class="small-text gray"> 사</span></p>
</div>
</div>
<div style="width: 20%; padding: 0 1rem;">
<div class="box pd10">
<p class="box-title point-font2 mb10">보조 출원사</p>
<p class="banner-title text-rg">{{ $comma(ent.sub) }}<span class="small-text gray"> 사</span></p>
</div>
</div>
</div>
</div>
<!-- 문의현황차트 -->
<div>
<div class="admin-sec-title point-font2">
<p class="mb10">상담 현황</p>
</div>
<div class="flex">
<div class="gd-6 chart-zone mb15">
<div class="box" style="height: 454px">
<div class="border radius pd20 content">
<div class="pb10 border-b mb10">
<p class="box-title">상담 현황</p>
</div>
<div>
<div class="mb15" v-for="(dscsn, idx) in dscsnStatusList" :key="idx">
<div class="flex align-center mb5">
<label for="all" class="detail-bold inline-block">{{ dscsn.cd_nm }}</label>
<p class="small-text ml5">({{ dscsn.count }}/{{ dscsn.allcount }})</p>
</div>
<div class="flex">
<div class="gd-10"><progress id="all" max="100" :value=dscsn.ratio class="content"></progress></div>
<div class="gd-2">
<p class="admin-sec-title text-rg">{{ dscsn.ratio}}%</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="gd-6 chart-zone mb15">
<div class="box" style="height: 454px">
<div class="border radius pd20 content">
<div class="pb10 border-b mb10">
<p class="box-title">추가 검토 필요 건수</p>
</div>
<div ref="pieChartdiv" style="height: 320px;">
<PieChart :chartData="pieChartData" value="count" category="category"></PieChart>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import LineChart from "../../../component/chart/lineChart.vue";
import PieChart from "../../../component/chart/PieChart.vue";
import PaginationButton from '../../../component/pagination/PaginationButton.vue';
import { defaultSearchParams } from "../../../../resources/js/defaultSearchParams";
import queryParams from "../../../../resources/js/queryParams";
// API
import { mainStatsProc, joinStatsProc } from "../../../../resources/api/cntnStats";
const App = {
mixins: [queryParams],
components: {
LineChart,
PieChart,
PaginationButton,
},
data() {
return {
// 페이지 권한 객체
pageAuth: JSON.parse(localStorage.getItem("vuex")).pageAuth,
//오늘날짜
today: this.$today(),
search: { ...defaultSearchParams },
//차트 데이터
lineChartData: [],
pieChartData: [],
//회원통계
join: {},
//정보동의 통계
trms: {},
//기업통계
ent: {},
//연도
years: [],
//상담 현황 통계
dscsnStatusList: [],
};
},
created() {
this.init();
},
methods: {
async init() {
this.resotreQueryParams("queryParams");
this.search.startDt = this.$oneWeekAgo();
this.search.endDt = this.$today();
this.search.searchType = "day"
this.mainStatsProc();
this.joinStatsProc();
},
// 메인 대시보드 통계 불러오기
async mainStatsProc() {
try {
const response = await mainStatsProc();
this.join = response.data.data.join[0];
this.trms = response.data.data.trms[0];
this.ent = response.data.data.ent[0];
this.dscsnStatusList = response.data.data.dscsn;
this.pieChartData = response.data.data.eduRvw;
this.years = response.data.data.joinYears;
} catch (error) {
// alert("에러가 발생했습니다.\n시스템관리자에게 문의하세요.");
alert(this.$getCmmnMessage('err005'));
}
},
async joinStatsProc() {
let data = this.search;
try {
const response = await joinStatsProc(data);
// this.search = response.data.data.pagination;
let datas = [];
for (let data of response.data.data.list) {
let newData = {};
data.name.unshift("전체");
data.count.unshift(data.total)
if (this.search.searchType === 'day') {
newData.date = this.$formatUnixToDate(data.dates);
} else {
newData.date = data.dates;
}
for (let i = 0; i < data.name.length; i++) {
newData[data.name[i]] = data.count[i];
}
datas.push(newData);
}
this.lineChartData = datas;
} catch {
}
},
changeType() {
if (this.search.searchType === 'day') {
this.search.startDt = this.$oneWeekAgo();
this.search.endDt = this.$today()
} else if (this.search.searchType === 'month') {
this.search.startDt = this.$nMonthAgo(this.$today(), 6).substring(0, 7);
this.search.endDt = this.$nMonthAgo(this.$today(), 0).substring(0, 7);
} else {
this.search.startDt = this.years[0]
this.search.endDt = this.years[this.years.length - 1]
}
this.joinStatsProc();
},
// 다운로드
fnDownload() {
const vm = this;
let data = Object.assign({}, vm.search);
data.searchStatus = 'Y'
data.searchFilter = 'join'
vm.$store.commit('setLoading', true);
axios({
url: "/stats/excel.json",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
Authorization: vm.$store.state.authorization,
},
data: data,
responseType: "arraybuffer",
})
.then((response) => {
const url = window.URL.createObjectURL(
new Blob([response.data], {
type: response.headers["content-type"],
})
);
const link = document.createElement("a");
link.href = url;
link.download = '[' + vm.today + ']' + '회원가입 통계';
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(url);
})
.catch((error) => {
// alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
alert(vm.$getCmmnMessage('err005'));
}).finally(function () {
vm.$store.commit('setLoading', false);
});
},
},
mounted() {
}
};
export default App;
</script>