|
@@ -1,864 +1,845 @@
|
|
|
<template>
|
|
|
- <div class="search-form">
|
|
|
- <!-- 站点选择和时间筛选 -->
|
|
|
- <a-row class="r1" :gutter="8">
|
|
|
- <a-col :xl="7" :xxl="6">
|
|
|
- <div class="choose-site">
|
|
|
- <span class="t1">站点:</span>
|
|
|
- <select-site @set-site-info="changeSite" select-width="100%" />
|
|
|
- </div>
|
|
|
- </a-col>
|
|
|
- <a-col :xl="8" :xxl="6">
|
|
|
- <div class="choose-site">
|
|
|
- <span class="t1">统计时间:</span>
|
|
|
- <a-range-picker @change="onChangeDatePicker" :disabledDate="disabledDate" :value="rangeDate" style="width: 70%" />
|
|
|
- </div>
|
|
|
- </a-col>
|
|
|
- <a-col :xl="9" :xxl="12">
|
|
|
- <a-button-group class="time-btn-group">
|
|
|
- <a-button :class="queryParam.dateType == '' ? 'active' : ''" @click="setTime('')">全部时间</a-button>
|
|
|
- <a-button :class="queryParam.dateType == 'thirtyDay' ? 'active' : ''" @click="setTime('thirtyDay')">近30天</a-button>
|
|
|
- <a-button :class="queryParam.dateType == 'sevenDay' ? 'active' : ''" @click="setTime('sevenDay')">近一周</a-button>
|
|
|
- <a-button :class="queryParam.dateType == 'yesterday' ? 'active' : ''" @click="setTime('yesterday')">昨日</a-button>
|
|
|
- <a-button :class="queryParam.dateType == 'today' ? 'active' : ''" @click="setTime('today')">今日</a-button>
|
|
|
- </a-button-group>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </div>
|
|
|
- <a-spin :spinning="loading" tip="加载中...">
|
|
|
- <a-row class="r2">
|
|
|
- <a-col :span="6">
|
|
|
- <p class="t1">访客数(UV)</p>
|
|
|
- <p class="t3">{{ flowIndexNums.uv.toLocaleString() }}</p>
|
|
|
- </a-col>
|
|
|
- <a-col :span="6">
|
|
|
- <p class="t1">浏览量(PV)</p>
|
|
|
- <p class="t3">{{ flowIndexNums.pv.toLocaleString() }}</p>
|
|
|
- </a-col>
|
|
|
- <a-col :span="6">
|
|
|
- <p class="t1">会话数</p>
|
|
|
- <p class="t3">{{ flowIndexNums.sessions.toLocaleString() }}</p>
|
|
|
- </a-col>
|
|
|
- <a-col :span="6">
|
|
|
- <p class="t1">询盘数</p>
|
|
|
- <p class="t3">{{ flowIndexNums.enquiry.toLocaleString() }}</p>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- <a-row>
|
|
|
- <a-col :span="24">
|
|
|
- <a-card style="margin: 10px" title="核心数据">
|
|
|
- <a-row class="r5" :gutter="[20,20]">
|
|
|
- <a-row class="r5-1">
|
|
|
- <a-col :span="24">
|
|
|
- <area-chart v-if="coreDataChart.x.length > 0"
|
|
|
- :dataSource="coreDataChart"></area-chart>
|
|
|
- <a-empty v-else style="float: right;width: 100%;margin-top: 110px;"></a-empty>
|
|
|
+ <div class="traffic-analysis-page">
|
|
|
+ <div class="search-form">
|
|
|
+ <!-- 站点选择和时间筛选 -->
|
|
|
+ <a-row class="r1 search-form-container" :gutter="8">
|
|
|
+ <a-col :xl="7" :xxl="6">
|
|
|
+ <div class="choose-site">
|
|
|
+ <span class="t1">站点:</span>
|
|
|
+ <select-site @set-site-info="changeSite" select-width="100%" />
|
|
|
+ </div>
|
|
|
+ </a-col>
|
|
|
+ <a-col :xl="8" :xxl="6">
|
|
|
+ <div class="choose-site">
|
|
|
+ <span class="t1">统计时间:</span>
|
|
|
+ <a-range-picker @change="onChangeDatePicker" :disabledDate="disabledDate" :value="rangeDate" style="width: 70%" />
|
|
|
+ </div>
|
|
|
+ </a-col>
|
|
|
+ <a-col :xl="9" :xxl="12">
|
|
|
+ <a-button-group class="time-btn-group">
|
|
|
+ <a-button :class="queryParam.dateType == '' ? 'active' : ''" @click="setTime('')">全部时间</a-button>
|
|
|
+ <a-button :class="queryParam.dateType == 'thirtyDay' ? 'active' : ''" @click="setTime('thirtyDay')">近30天</a-button>
|
|
|
+ <a-button :class="queryParam.dateType == 'sevenDay' ? 'active' : ''" @click="setTime('sevenDay')">近一周</a-button>
|
|
|
+ <a-button :class="queryParam.dateType == 'yesterday' ? 'active' : ''" @click="setTime('yesterday')">昨日</a-button>
|
|
|
+ <a-button :class="queryParam.dateType == 'today' ? 'active' : ''" @click="setTime('today')">今日</a-button>
|
|
|
+ </a-button-group>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </div>
|
|
|
+ <a-spin :spinning="loading" tip="加载中...">
|
|
|
+ <a-row class="r2">
|
|
|
+ <a-col :span="6">
|
|
|
+ <p class="t1">访客数(UV)</p>
|
|
|
+ <p class="t3">{{ flowIndexNums.uv.toLocaleString() }}</p>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="6">
|
|
|
+ <p class="t1">浏览量(PV)</p>
|
|
|
+ <p class="t3">{{ flowIndexNums.pv.toLocaleString() }}</p>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="6">
|
|
|
+ <p class="t1">会话数</p>
|
|
|
+ <p class="t3">{{ flowIndexNums.sessions.toLocaleString() }}</p>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="6">
|
|
|
+ <p class="t1">询盘数</p>
|
|
|
+ <p class="t3">{{ flowIndexNums.enquiry.toLocaleString() }}</p>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ <a-row>
|
|
|
+ <a-col :span="24">
|
|
|
+ <a-card style="margin: 10px" title="核心数据">
|
|
|
+ <a-row class="r5" :gutter="[20, 20]">
|
|
|
+ <a-row class="r5-1">
|
|
|
+ <a-col :span="24">
|
|
|
+ <area-chart v-if="coreDataChart.x.length > 0" :dataSource="coreDataChart" />
|
|
|
+ <a-empty v-else style="float: right; width: 100%; margin-top: 110px" />
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-row>
|
|
|
+ <a-row class="r2">
|
|
|
+ <a-col style="width: 20%">
|
|
|
+ <p class="t1">日均访问量</p>
|
|
|
+ <p class="t3">{{ statistics.averageVisit.toLocaleString() }}</p>
|
|
|
+ </a-col>
|
|
|
+ <a-col style="width: 20%">
|
|
|
+ <p class="t1">平均访问时长</p>
|
|
|
+ <p class="t3">{{ statistics.averageVisitDuration }}</p>
|
|
|
+ </a-col>
|
|
|
+ <a-col style="width: 20%">
|
|
|
+ <p class="t1">访客平均访问页面数</p>
|
|
|
+ <p class="t3">{{ statistics.averageVisitPage.toLocaleString() }}</p>
|
|
|
+ </a-col>
|
|
|
+ <a-col style="width: 20%">
|
|
|
+ <p class="t1">跳出率</p>
|
|
|
+ <p class="t3">{{ statistics.bounceRate }}</p>
|
|
|
+ </a-col>
|
|
|
+ <a-col style="width: 20%">
|
|
|
+ <p class="t1">UV到询盘转化率</p>
|
|
|
+ <p class="t3">{{ statistics.conversionRate }}</p>
|
|
|
</a-col>
|
|
|
</a-row>
|
|
|
- </a-row>
|
|
|
- <a-row class="r2">
|
|
|
- <a-col style="width: 20%;">
|
|
|
- <p class="t1">日均访问量</p>
|
|
|
- <p class="t3">{{ statistics.averageVisit.toLocaleString() }}</p>
|
|
|
- </a-col>
|
|
|
- <a-col style="width: 20%;">
|
|
|
- <p class="t1">平均访问时长</p>
|
|
|
- <p class="t3">{{ statistics.averageVisitDuration }}</p>
|
|
|
- </a-col>
|
|
|
- <a-col style="width: 20%;">
|
|
|
- <p class="t1">访客平均访问页面数</p>
|
|
|
- <p class="t3">{{ statistics.averageVisitPage.toLocaleString() }}</p>
|
|
|
- </a-col>
|
|
|
- <a-col style="width: 20%;">
|
|
|
- <p class="t1">跳出率</p>
|
|
|
- <p class="t3">{{ statistics.bounceRate }}</p>
|
|
|
- </a-col>
|
|
|
- <a-col style="width: 20%;">
|
|
|
- <p class="t1">UV到询盘转化率</p>
|
|
|
- <p class="t3">{{ statistics.conversionRate }}</p>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-card>
|
|
|
- </a-col>
|
|
|
- <a-col :span="24">
|
|
|
- <a-card style="margin: 10px" title="访客数地域分布">
|
|
|
- <a-row class="r5">
|
|
|
- <a-col :span="18">
|
|
|
- <map-adweb v-if="countryMapData.length > 0" :dataSource="countryMapData"
|
|
|
- height="400"></map-adweb>
|
|
|
- <a-empty v-else style="margin-top: 50px;">
|
|
|
- </a-empty>
|
|
|
- </a-col>
|
|
|
-
|
|
|
- <a-col :span="6">
|
|
|
- <a-table
|
|
|
- :rowKey="(record,index)=>{return index}"
|
|
|
- class="chartTable"
|
|
|
- :scroll="{ y: 500 }"
|
|
|
- :pagination=false
|
|
|
- :columns="chartDetailDataCol"
|
|
|
- :data-source="chartDetailData"
|
|
|
- :showHeader="false">
|
|
|
- <template #bodyCell="{ column, record }">
|
|
|
- <template v-if="column.key === 'flagSlot' ">
|
|
|
- <span class="img-box">
|
|
|
- <span :class="'flag-icon flag-icon-'+record.countryCode"></span>
|
|
|
- </span>
|
|
|
+ </a-card>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="24">
|
|
|
+ <a-card style="margin: 10px" title="访客数地域分布">
|
|
|
+ <a-row class="r5">
|
|
|
+ <a-col :span="18">
|
|
|
+ <map-adweb v-if="countryMapData.length > 0" :dataSource="countryMapData" height="400" />
|
|
|
+ <a-empty v-else style="margin-top: 50px" />
|
|
|
+ </a-col>
|
|
|
+
|
|
|
+ <a-col :span="6">
|
|
|
+ <a-table
|
|
|
+ :rowKey="
|
|
|
+ (record, index) => {
|
|
|
+ return index;
|
|
|
+ }
|
|
|
+ "
|
|
|
+ class="chartTable"
|
|
|
+ :scroll="{ y: 500 }"
|
|
|
+ :pagination="false"
|
|
|
+ :columns="chartDetailDataCol"
|
|
|
+ :data-source="chartDetailData"
|
|
|
+ :showHeader="false"
|
|
|
+ >
|
|
|
+ <template #bodyCell="{ column, record }">
|
|
|
+ <template v-if="column.key === 'flagSlot'">
|
|
|
+ <span class="img-box">
|
|
|
+ <span :class="'flag-icon flag-icon-' + record.countryCode"></span>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'numSlot'"> {{ record.totalUsers }} | {{ record.totalUsersProportion }} </template>
|
|
|
</template>
|
|
|
- <template v-if="column.key === 'numSlot' ">
|
|
|
- {{ record.totalUsers }} | {{ record.totalUsersProportion }}
|
|
|
+ </a-table>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-card>
|
|
|
+ </a-col>
|
|
|
+
|
|
|
+ <a-col :span="12">
|
|
|
+ <a-card style="margin: 10px" title="访客数设备分布">
|
|
|
+ <a-row class="r5" :gutter="[20, 20]">
|
|
|
+ <a-col :span="24">
|
|
|
+ <DeviceStatsUV :deviceStats="deviceStats" />
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-card>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="12">
|
|
|
+ <a-card style="margin: 10px" title="浏览量设备分布">
|
|
|
+ <a-row class="r5" :gutter="[20, 20]">
|
|
|
+ <a-col :span="24">
|
|
|
+ <DeviceStatsPV :deviceStats="deviceStats" />
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-card>
|
|
|
+ </a-col>
|
|
|
+
|
|
|
+ <!-- 来源媒介 -->
|
|
|
+ <a-col :span="24">
|
|
|
+ <a-card style="margin: 10px" title="来源媒介">
|
|
|
+ <a-row class="r5" :gutter="[20, 20]">
|
|
|
+ <a-col :span="24">
|
|
|
+ <a-table :columns="mediaListColumns" :data-source="mediaDatasource" size="middle" rowKey="type" :pagination="false">
|
|
|
+ <template #filterDropdown>
|
|
|
+ <div style="padding: 10px">
|
|
|
+ affiliate:通过联属营销计划点击链接的用户<br />
|
|
|
+ cpc:(每次点击费用的缩写)点击付费广告的用户<br />
|
|
|
+ organic:点击搜索引擎中的链接的用户<br />
|
|
|
+ referral:点击网站上的链接(例如,视频说明中的链接)的用户<br />
|
|
|
+ (none):直接流量
|
|
|
+ </div>
|
|
|
</template>
|
|
|
- </template>
|
|
|
- </a-table>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-card>
|
|
|
- </a-col>
|
|
|
-
|
|
|
- <a-col :span="12">
|
|
|
- <a-card style="margin: 10px" title="访客数设备分布">
|
|
|
- <a-row class="r5" :gutter="[20,20]">
|
|
|
- <a-col :span="24">
|
|
|
- <DeviceStatsUV :deviceStats="deviceStats"></DeviceStatsUV>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-card>
|
|
|
- </a-col>
|
|
|
- <a-col :span="12">
|
|
|
- <a-card style="margin: 10px" title="浏览量设备分布">
|
|
|
- <a-row class="r5" :gutter="[20,20]">
|
|
|
- <a-col :span="24">
|
|
|
- <DeviceStatsPV :deviceStats="deviceStats"></DeviceStatsPV>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-card>
|
|
|
- </a-col>
|
|
|
-
|
|
|
- <!-- 来源媒介 -->
|
|
|
- <a-col :span="24">
|
|
|
-
|
|
|
- <a-card style="margin: 10px" title="来源媒介">
|
|
|
- <a-row class="r5" :gutter="[20,20]">
|
|
|
- <a-col :span="24">
|
|
|
- <a-table
|
|
|
- :columns="mediaListColumns"
|
|
|
- :data-source="mediaDatasource"
|
|
|
- size="middle"
|
|
|
- rowKey="type"
|
|
|
- :pagination="false">
|
|
|
- <div style="padding: 10px;" slot="filterDropdown">
|
|
|
- affiliate:通过联属营销计划点击链接的用户<br />
|
|
|
- cpc:(每次点击费用的缩写)点击付费广告的用户<br />
|
|
|
- organic:点击搜索引擎中的链接的用户<br />
|
|
|
- referral:点击网站上的链接(例如,视频说明中的链接)的用户<br />
|
|
|
- (none):直接流量
|
|
|
- </div>
|
|
|
- <a-icon slot="filterIcon" type='question-circle'
|
|
|
- :style="{ fontSize:'16px',color: '#108ee9' }" />
|
|
|
- <template #bodyCell="{ column, record, index, text }">
|
|
|
- <template v-if="column.key === 'typeSlotFirst' ">
|
|
|
- {{ record.type.split("/")[0] }}
|
|
|
+ <template #filterIcon>
|
|
|
+ <a-icon type="question-circle" :style="{ fontSize: '16px', color: '#108ee9' }" />
|
|
|
</template>
|
|
|
- <template v-if="column.key === 'typeSlotLast' ">
|
|
|
- <a-popover>
|
|
|
- <template slot="content">
|
|
|
- <template v-if="record.type.split('/')[1] === ' affiliate'">
|
|
|
- 通过联属营销计划点击链接的用户
|
|
|
- </template>
|
|
|
- <template v-if="record.type.split('/')[1] === ' cpc'">
|
|
|
- (每次点击费用的缩写)点击付费广告的用户
|
|
|
- </template>
|
|
|
- <template v-if="record.type.split('/')[1] === ' organic'">
|
|
|
- 点击搜索引擎中的链接的用户
|
|
|
- </template>
|
|
|
- <template v-if="record.type.split('/')[1] === ' referral'">
|
|
|
- 点击网站上的链接(例如,视频说明中的链接)的用户
|
|
|
+ <template #bodyCell="{ column, record, index, text }">
|
|
|
+ <template v-if="column.key === 'typeSlotFirst'">
|
|
|
+ {{ record.type.split('/')[0] }}
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'typeSlotLast'">
|
|
|
+ <a-popover>
|
|
|
+ <template #content>
|
|
|
+ <template v-if="record.type.split('/')[1] === ' affiliate'"> 通过联属营销计划点击链接的用户 </template>
|
|
|
+ <template v-if="record.type.split('/')[1] === ' cpc'"> (每次点击费用的缩写)点击付费广告的用户 </template>
|
|
|
+ <template v-if="record.type.split('/')[1] === ' organic'"> 点击搜索引擎中的链接的用户 </template>
|
|
|
+ <template v-if="record.type.split('/')[1] === ' referral'"> 点击网站上的链接(例如,视频说明中的链接)的用户 </template>
|
|
|
+ <template v-if="record.type.split('/')[1] === ' (none)'"> 直接流量 </template>
|
|
|
</template>
|
|
|
- <template v-if="record.type.split('/')[1] === ' (none)'">
|
|
|
- 直接流量
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- {{ record.type.split("/")[1] }}
|
|
|
- </a-popover>
|
|
|
- </template>
|
|
|
- <template v-if="column.key === 'avgSessionDurationSlot' ">
|
|
|
- <span style="margin-left: 30px;">{{ record.avgSessionDuration }} s</span>
|
|
|
+ {{ record.type.split('/')[1] }}
|
|
|
+ </a-popover>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'avgSessionDurationSlot'">
|
|
|
+ <span style="margin-left: 30px">{{ record.avgSessionDuration }} s</span>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
- </template>
|
|
|
-
|
|
|
- </a-table>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-card>
|
|
|
- </a-col>
|
|
|
-
|
|
|
- <!-- 最多访问TOP10 -->
|
|
|
- <a-col :span="24">
|
|
|
- <a-card style="margin: 10px" title="最多访问TOP10">
|
|
|
- <a-row class="r5" :gutter="[20,20]">
|
|
|
- <a-col :span="24">
|
|
|
- <a-table
|
|
|
- :columns="mostAccessColumns"
|
|
|
- :data-source="mostAccessDatasource"
|
|
|
- size="middle"
|
|
|
- rowKey="type"
|
|
|
- :pagination="false">
|
|
|
- <template #bodyCell="{ column, record, index, text }">
|
|
|
- <template v-if="column.key ==='pagePathSlot' ">
|
|
|
- <a-popover>
|
|
|
- <template slot="content">
|
|
|
- {{ text }}
|
|
|
- </template>
|
|
|
- <a :href="text" target="_blank">
|
|
|
- <div
|
|
|
- style="width: 700px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
|
|
|
+ </a-table>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-card>
|
|
|
+ </a-col>
|
|
|
+
|
|
|
+ <!-- 最多访问TOP10 -->
|
|
|
+ <a-col :span="24">
|
|
|
+ <a-card style="margin: 10px" title="最多访问TOP10">
|
|
|
+ <a-row class="r5" :gutter="[20, 20]">
|
|
|
+ <a-col :span="24">
|
|
|
+ <a-table :columns="mostAccessColumns" :data-source="mostAccessDatasource" size="middle" rowKey="type" :pagination="false">
|
|
|
+ <template #bodyCell="{ column, record, index, text }">
|
|
|
+ <template v-if="column.key === 'pagePathSlot'">
|
|
|
+ <a-popover>
|
|
|
+ <template #content>
|
|
|
{{ text }}
|
|
|
- </div>
|
|
|
- </a>
|
|
|
- </a-popover>
|
|
|
- </template>
|
|
|
- <template v-if="column.key ==='centerSlot' ">
|
|
|
- <span style="margin-left: 20px;">{{ text }}</span>
|
|
|
- </template>
|
|
|
- <template v-if="column.key ==='avgTimeOnPageSlot' ">
|
|
|
- <span style="margin-left: 30px;">{{ text }} s</span>
|
|
|
+ </template>
|
|
|
+ <a :href="text" target="_blank">
|
|
|
+ <div style="width: 700px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
|
|
|
+ {{ text }}
|
|
|
+ </div>
|
|
|
+ </a>
|
|
|
+ </a-popover>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'centerSlot'">
|
|
|
+ <span style="margin-left: 20px">{{ text }}</span>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'avgTimeOnPageSlot'">
|
|
|
+ <span style="margin-left: 30px">{{ text }} s</span>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
- </template>
|
|
|
- </a-table>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-card>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-spin>
|
|
|
+ </a-table>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-card>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-spin>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" name="data-trafficAnalysis" setup>
|
|
|
-import selectSite from "@/components/Adweb/selectSite.vue";
|
|
|
-import areaChart from "./chart/areaChart.vue";
|
|
|
-import { computed, reactive, ref } from "vue";
|
|
|
-import { getAction } from "@/api/manage/manage";
|
|
|
-import MapAdweb from "@/components/chart/mapAdweb.vue";
|
|
|
-import DeviceStatsPV from "./components/DeviceStatsPV.vue";
|
|
|
-import DeviceStatsUV from "./components/DeviceStatsUV.vue";
|
|
|
-import "flag-icon-css/css/flag-icons.css";
|
|
|
-import dayjs from 'dayjs';
|
|
|
-
|
|
|
-
|
|
|
-const queryParam = reactive<any>({});
|
|
|
-queryParam.limit = 10;
|
|
|
-queryParam.siteCode = localStorage.getItem("siteCode");
|
|
|
-const loading = ref(false);
|
|
|
-const chartDetailDataCol = ref([
|
|
|
- {
|
|
|
- title: "国旗",
|
|
|
- align: "center",
|
|
|
- key: "flagSlot",
|
|
|
- width: 30,
|
|
|
- scopedSlots: { customRender: "flagSlot" }
|
|
|
- },
|
|
|
- {
|
|
|
- title: "国家",
|
|
|
- align: "left",
|
|
|
- dataIndex: "countryName",
|
|
|
- customRender: function(text, record) {
|
|
|
- return text === null ? record.country : text;
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: "数量",
|
|
|
- align: "right",
|
|
|
- key: "numSlot",
|
|
|
- scopedSlots: { customRender: "numSlot" }
|
|
|
- }
|
|
|
-]);
|
|
|
-// 来源媒介列表
|
|
|
-const mediaListColumns = ref([
|
|
|
- {
|
|
|
- title: "来源",
|
|
|
- key: "typeSlotFirst",
|
|
|
- scopedSlots: {
|
|
|
- customRender: "typeSlotFirst"
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: "媒介",
|
|
|
- key: "typeSlotLast",
|
|
|
- scopedSlots: {
|
|
|
- filterDropdown: "filterDropdown",
|
|
|
- filterIcon: "filterIcon",
|
|
|
- customRender: "typeSlotLast"
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: "访客数(UV)",
|
|
|
- dataIndex: "totalUsers"
|
|
|
- },
|
|
|
- {
|
|
|
- title: "占比",
|
|
|
- dataIndex: "totalUsersProportion"
|
|
|
- },
|
|
|
- {
|
|
|
- title: "新访客数",
|
|
|
- dataIndex: "newUsers"
|
|
|
- },
|
|
|
- {
|
|
|
- title: "新客占比",
|
|
|
- dataIndex: "newUsersRatio"
|
|
|
- },
|
|
|
- {
|
|
|
- title: "浏览量(PV)",
|
|
|
- dataIndex: "pageViews"
|
|
|
- },
|
|
|
- {
|
|
|
- title: "平均访问页面数",
|
|
|
- dataIndex: "pageViewsPerSession"
|
|
|
- },
|
|
|
- {
|
|
|
- title: "会话数",
|
|
|
- dataIndex: "sessions"
|
|
|
- },
|
|
|
- {
|
|
|
- title: "平均会话时长",
|
|
|
- key: "avgSessionDurationSlot",
|
|
|
- sortDirections: ["descend", "ascend"],
|
|
|
- sorter: (a, b) => a.avgSessionDuration - b.avgSessionDuration,
|
|
|
- scopedSlots: {
|
|
|
- customRender: "avgSessionDurationSlot"
|
|
|
- }
|
|
|
+ import selectSite from '@/components/Adweb/selectSite.vue';
|
|
|
+ import areaChart from './chart/areaChart.vue';
|
|
|
+ import { computed, reactive, ref } from 'vue';
|
|
|
+ import { getAction } from '@/api/manage/manage';
|
|
|
+ import MapAdweb from '@/components/chart/mapAdweb.vue';
|
|
|
+ import DeviceStatsPV from './components/DeviceStatsPV.vue';
|
|
|
+ import DeviceStatsUV from './components/DeviceStatsUV.vue';
|
|
|
+ import 'flag-icon-css/css/flag-icons.css';
|
|
|
+ import dayjs from 'dayjs';
|
|
|
+
|
|
|
+ const queryParam = reactive<any>({});
|
|
|
+ queryParam.limit = 10;
|
|
|
+ queryParam.siteCode = localStorage.getItem('siteCode');
|
|
|
+ const loading = ref(false);
|
|
|
+ const chartDetailDataCol = ref([
|
|
|
+ {
|
|
|
+ title: '国旗',
|
|
|
+ align: 'center',
|
|
|
+ key: 'flagSlot',
|
|
|
+ width: 30,
|
|
|
+ scopedSlots: { customRender: 'flagSlot' },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '国家',
|
|
|
+ align: 'left',
|
|
|
+ dataIndex: 'countryName',
|
|
|
+ customRender: function (text, record) {
|
|
|
+ return text === null ? record.country : text;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '数量',
|
|
|
+ align: 'right',
|
|
|
+ key: 'numSlot',
|
|
|
+ scopedSlots: { customRender: 'numSlot' },
|
|
|
+ },
|
|
|
+ ]);
|
|
|
+ // 来源媒介列表
|
|
|
+ const mediaListColumns = ref([
|
|
|
+ {
|
|
|
+ title: '来源',
|
|
|
+ key: 'typeSlotFirst',
|
|
|
+ scopedSlots: {
|
|
|
+ customRender: 'typeSlotFirst',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '媒介',
|
|
|
+ key: 'typeSlotLast',
|
|
|
+ scopedSlots: {
|
|
|
+ filterDropdown: 'filterDropdown',
|
|
|
+ filterIcon: 'filterIcon',
|
|
|
+ customRender: 'typeSlotLast',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '访客数(UV)',
|
|
|
+ dataIndex: 'totalUsers',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '占比',
|
|
|
+ dataIndex: 'totalUsersProportion',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '新访客数',
|
|
|
+ dataIndex: 'newUsers',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '新客占比',
|
|
|
+ dataIndex: 'newUsersRatio',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '浏览量(PV)',
|
|
|
+ dataIndex: 'pageViews',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '平均访问页面数',
|
|
|
+ dataIndex: 'pageViewsPerSession',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '会话数',
|
|
|
+ dataIndex: 'sessions',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '平均会话时长',
|
|
|
+ key: 'avgSessionDurationSlot',
|
|
|
+ sortDirections: ['descend', 'ascend'],
|
|
|
+ sorter: (a, b) => a.avgSessionDuration - b.avgSessionDuration,
|
|
|
+ scopedSlots: {
|
|
|
+ customRender: 'avgSessionDurationSlot',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 最多访问TOP10列表
|
|
|
+ const mostAccessColumns = ref([
|
|
|
+ {
|
|
|
+ title: '来源',
|
|
|
+ dataIndex: 'pagePath',
|
|
|
+ scopedSlots: {
|
|
|
+ customRender: 'pagePathSlot',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '浏览量(PV)',
|
|
|
+ dataIndex: 'pageViews',
|
|
|
+ defaultSortOrder: 'descend',
|
|
|
+ sorter: (a, b) => a.pageViews - b.pageViews,
|
|
|
+ width: 160,
|
|
|
+ scopedSlots: {
|
|
|
+ customRender: 'centerSlot',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '浏览量占比',
|
|
|
+ dataIndex: 'pvProportion',
|
|
|
+ width: 160,
|
|
|
+ scopedSlots: {
|
|
|
+ customRender: 'centerSlot',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // {
|
|
|
+ // title: '平均页面停留时间',
|
|
|
+ // dataIndex: 'avgTimeOnPage',
|
|
|
+ // sortDirections: ['descend', 'ascend'],
|
|
|
+ // width: 160,
|
|
|
+ // scopedSlots: {
|
|
|
+ // customRender: 'avgTimeOnPageSlot',
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ ]);
|
|
|
+
|
|
|
+ function changeSite(selectedSiteInfo: any) {
|
|
|
+ queryParam.siteCode = selectedSiteInfo.code;
|
|
|
+ localStorage.setItem('siteCode', queryParam.siteCode);
|
|
|
+ reloadData();
|
|
|
}
|
|
|
-]);
|
|
|
-
|
|
|
-// 最多访问TOP10列表
|
|
|
-const mostAccessColumns = ref([
|
|
|
- {
|
|
|
- title: "来源",
|
|
|
- dataIndex: "pagePath",
|
|
|
- scopedSlots: {
|
|
|
- customRender: "pagePathSlot"
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: "浏览量(PV)",
|
|
|
- dataIndex: "pageViews",
|
|
|
- defaultSortOrder: "descend",
|
|
|
- sorter: (a, b) => a.pageViews - b.pageViews,
|
|
|
- width: 160,
|
|
|
- scopedSlots: {
|
|
|
- customRender: "centerSlot"
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: "浏览量占比",
|
|
|
- dataIndex: "pvProportion",
|
|
|
- width: 160,
|
|
|
- scopedSlots: {
|
|
|
- customRender: "centerSlot"
|
|
|
- }
|
|
|
+
|
|
|
+ //重新刷新页面数据
|
|
|
+ function reloadData() {
|
|
|
+ loading.value = true;
|
|
|
+ getFlowIndexNumber();
|
|
|
+ getCountryMapData();
|
|
|
+ getMediaList();
|
|
|
+ getMostAccessList();
|
|
|
+ getDeviceStats();
|
|
|
}
|
|
|
- // {
|
|
|
- // title: '平均页面停留时间',
|
|
|
- // dataIndex: 'avgTimeOnPage',
|
|
|
- // sortDirections: ['descend', 'ascend'],
|
|
|
- // width: 160,
|
|
|
- // scopedSlots: {
|
|
|
- // customRender: 'avgTimeOnPageSlot',
|
|
|
- // }
|
|
|
- // },
|
|
|
-]);
|
|
|
-
|
|
|
-function changeSite(selectedSiteInfo: any) {
|
|
|
- queryParam.siteCode = selectedSiteInfo.code;
|
|
|
- localStorage.setItem("siteCode", queryParam.siteCode);
|
|
|
- reloadData();
|
|
|
-}
|
|
|
-
|
|
|
-//重新刷新页面数据
|
|
|
-function reloadData() {
|
|
|
- loading.value = true;
|
|
|
- getFlowIndexNumber();
|
|
|
- getCountryMapData();
|
|
|
- getMediaList();
|
|
|
- getMostAccessList();
|
|
|
- getDeviceStats();
|
|
|
-}
|
|
|
-
|
|
|
-const flowIndexNums = ref({
|
|
|
- uv: 0,
|
|
|
- pv: 0,
|
|
|
- sessions: 0,
|
|
|
- enquiry: 0
|
|
|
-});
|
|
|
-const coreDataChart = ref({
|
|
|
- x: [],
|
|
|
- uv: [],
|
|
|
- pv: [],
|
|
|
- enquiry: []
|
|
|
-});
|
|
|
-const statistics = ref({
|
|
|
- averageVisit: 0,
|
|
|
- averageVisitDuration: 0,
|
|
|
- averageVisitPage: 0,
|
|
|
- bounceRate: "0%",
|
|
|
- conversionRate: "0%"
|
|
|
-});
|
|
|
-
|
|
|
-//访客量、浏览量、询盘数量、折线图以及统计
|
|
|
-const getFlowIndexNumber = async () => {
|
|
|
- try {
|
|
|
- const res = await getAction("/dmp-data/site-overview/stats", queryParam);
|
|
|
- if (!res.result) {
|
|
|
- flowIndexNums.value = {
|
|
|
- uv: 0,
|
|
|
- pv: 0,
|
|
|
- sessions: 0,
|
|
|
- enquiry: 0
|
|
|
- };
|
|
|
- coreDataChart.value = {
|
|
|
- x: [],
|
|
|
- uv: [],
|
|
|
- pv: [],
|
|
|
- enquiry: []
|
|
|
- };
|
|
|
- statistics.value = {
|
|
|
- averageVisit: 0,
|
|
|
- averageVisitDuration: 0,
|
|
|
- averageVisitPage: 0,
|
|
|
- bounceRate: "0%",
|
|
|
- conversionRate: "0%"
|
|
|
- };
|
|
|
- loading.value = false;
|
|
|
- return;
|
|
|
- }
|
|
|
|
|
|
- flowIndexNums.value.uv = res.result.totalUsers;
|
|
|
- flowIndexNums.value.pv = res.result.pageViews;
|
|
|
- flowIndexNums.value.sessions = res.result.sessions;
|
|
|
- flowIndexNums.value.enquiry = res.result.enquires;
|
|
|
- const r = res.result.dailyStats;
|
|
|
- const x = [], pv = [], uv = [], enquiry = [];
|
|
|
- if (r != null && r.length > 0) {
|
|
|
- for (let item of r) {
|
|
|
- x.push(item.date);
|
|
|
- pv.push(item.pageViews);
|
|
|
- uv.push(item.totalUsers);
|
|
|
- enquiry.push(item.enquires);
|
|
|
+ const flowIndexNums = ref({
|
|
|
+ uv: 0,
|
|
|
+ pv: 0,
|
|
|
+ sessions: 0,
|
|
|
+ enquiry: 0,
|
|
|
+ });
|
|
|
+ const coreDataChart = ref({
|
|
|
+ x: [],
|
|
|
+ uv: [],
|
|
|
+ pv: [],
|
|
|
+ enquiry: [],
|
|
|
+ });
|
|
|
+ const statistics = ref({
|
|
|
+ averageVisit: 0,
|
|
|
+ averageVisitDuration: 0,
|
|
|
+ averageVisitPage: 0,
|
|
|
+ bounceRate: '0%',
|
|
|
+ conversionRate: '0%',
|
|
|
+ });
|
|
|
+
|
|
|
+ //访客量、浏览量、询盘数量、折线图以及统计
|
|
|
+ const getFlowIndexNumber = async () => {
|
|
|
+ try {
|
|
|
+ const res = await getAction('/dmp-data/site-overview/stats', queryParam);
|
|
|
+ if (!res.result) {
|
|
|
+ flowIndexNums.value = {
|
|
|
+ uv: 0,
|
|
|
+ pv: 0,
|
|
|
+ sessions: 0,
|
|
|
+ enquiry: 0,
|
|
|
+ };
|
|
|
+ coreDataChart.value = {
|
|
|
+ x: [],
|
|
|
+ uv: [],
|
|
|
+ pv: [],
|
|
|
+ enquiry: [],
|
|
|
+ };
|
|
|
+ statistics.value = {
|
|
|
+ averageVisit: 0,
|
|
|
+ averageVisitDuration: 0,
|
|
|
+ averageVisitPage: 0,
|
|
|
+ bounceRate: '0%',
|
|
|
+ conversionRate: '0%',
|
|
|
+ };
|
|
|
+ loading.value = false;
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
+ flowIndexNums.value.uv = res.result.totalUsers;
|
|
|
+ flowIndexNums.value.pv = res.result.pageViews;
|
|
|
+ flowIndexNums.value.sessions = res.result.sessions;
|
|
|
+ flowIndexNums.value.enquiry = res.result.enquires;
|
|
|
+ const r = res.result.dailyStats;
|
|
|
+ const x = [],
|
|
|
+ pv = [],
|
|
|
+ uv = [],
|
|
|
+ enquiry = [];
|
|
|
+ if (r != null && r.length > 0) {
|
|
|
+ for (let item of r) {
|
|
|
+ x.push(item.date);
|
|
|
+ pv.push(item.pageViews);
|
|
|
+ uv.push(item.totalUsers);
|
|
|
+ enquiry.push(item.enquires);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ coreDataChart.value.x = x;
|
|
|
+ coreDataChart.value.pv = pv;
|
|
|
+ coreDataChart.value.uv = uv;
|
|
|
+ coreDataChart.value.enquiry = enquiry;
|
|
|
+
|
|
|
+ statistics.value.averageVisit = res.result.dailyTotalUsers;
|
|
|
+ statistics.value.averageVisitDuration = res.result.avgTimeOnPage;
|
|
|
+ statistics.value.averageVisitPage = res.result.pageViewsPerSession;
|
|
|
+ statistics.value.bounceRate = res.result.bounceRate;
|
|
|
+ statistics.value.conversionRate = res.result.enquiryConversionRate;
|
|
|
+ loading.value = false;
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const chartDetailData = ref([]);
|
|
|
+ const countryMapData = ref([]);
|
|
|
+
|
|
|
+ //访客数地域分布
|
|
|
+ const getCountryMapData = async () => {
|
|
|
+ try {
|
|
|
+ const res = await getAction('/dmp-data/country/stats', queryParam);
|
|
|
+ if (res.code === 200) {
|
|
|
+ chartDetailData.value = res.result;
|
|
|
+ countryMapData.value = chartDetailData.value.map((entry) => ({
|
|
|
+ name: entry.countryName,
|
|
|
+ value: entry.totalUsers,
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const mediaDatasource = ref([]);
|
|
|
+
|
|
|
+ const deviceStats = ref([]); // 设备统计数据
|
|
|
+
|
|
|
+ // 新增获取设备统计数据的函数
|
|
|
+ const getDeviceStats = async () => {
|
|
|
+ try {
|
|
|
+ const res = await getAction('/dmp-data/device/stats', queryParam);
|
|
|
+ if (res.code === 200) {
|
|
|
+ deviceStats.value = res.result; // Update the deviceStats with the response
|
|
|
+ } else {
|
|
|
+ deviceStats.value = []; // Reset if there's an error
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ //来源媒介列表、最多访问top10列表
|
|
|
+ const getMediaList = async () => {
|
|
|
+ try {
|
|
|
+ const res = await getAction('/dmp-data/source-medium/stats', queryParam);
|
|
|
+ if (res.code == 200) {
|
|
|
+ mediaDatasource.value = res.result;
|
|
|
+ } else {
|
|
|
+ mediaDatasource.value = [];
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const mostAccessDatasource = ref([]);
|
|
|
+
|
|
|
+ //
|
|
|
+ const getMostAccessList = async () => {
|
|
|
+ try {
|
|
|
+ const res = await getAction('/dmp-data/page-path/stats', queryParam);
|
|
|
+ if (res.code == 200) {
|
|
|
+ mostAccessDatasource.value = res.result;
|
|
|
+ } else {
|
|
|
+ mostAccessDatasource.value = [];
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
}
|
|
|
- coreDataChart.value.x = x;
|
|
|
- coreDataChart.value.pv = pv;
|
|
|
- coreDataChart.value.uv = uv;
|
|
|
- coreDataChart.value.enquiry = enquiry;
|
|
|
-
|
|
|
- statistics.value.averageVisit = res.result.dailyTotalUsers;
|
|
|
- statistics.value.averageVisitDuration = res.result.avgTimeOnPage;
|
|
|
- statistics.value.averageVisitPage = res.result.pageViewsPerSession;
|
|
|
- statistics.value.bounceRate = res.result.bounceRate;
|
|
|
- statistics.value.conversionRate = res.result.enquiryConversionRate;
|
|
|
- loading.value = false;
|
|
|
- } catch (error) {
|
|
|
- console.error(error);
|
|
|
- }
|
|
|
-};
|
|
|
-const chartDetailData = ref([]);
|
|
|
-const countryMapData = ref([]);
|
|
|
-
|
|
|
-//访客数地域分布
|
|
|
-const getCountryMapData = async () => {
|
|
|
- try {
|
|
|
- const res = await getAction("/dmp-data/country/stats", queryParam);
|
|
|
- if (res.code === 200) {
|
|
|
- chartDetailData.value = res.result;
|
|
|
- countryMapData.value = chartDetailData.value.map(entry => ({
|
|
|
- name: entry.countryName,
|
|
|
- value: entry.totalUsers
|
|
|
- }));
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error(error);
|
|
|
- }
|
|
|
-};
|
|
|
-const mediaDatasource = ref([]);
|
|
|
-
|
|
|
-const deviceStats = ref([]); // 设备统计数据
|
|
|
-
|
|
|
-// 新增获取设备统计数据的函数
|
|
|
-const getDeviceStats = async () => {
|
|
|
- try {
|
|
|
- const res = await getAction("/dmp-data/device/stats", queryParam);
|
|
|
- if (res.code === 200) {
|
|
|
- deviceStats.value = res.result; // Update the deviceStats with the response
|
|
|
- } else {
|
|
|
- deviceStats.value = []; // Reset if there's an error
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error(error);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-//来源媒介列表、最多访问top10列表
|
|
|
-const getMediaList = async () => {
|
|
|
- try {
|
|
|
- const res = await getAction("/dmp-data/source-medium/stats", queryParam);
|
|
|
- if (res.code == 200) {
|
|
|
- mediaDatasource.value = res.result;
|
|
|
- } else {
|
|
|
- mediaDatasource.value = [];
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error(error);
|
|
|
- }
|
|
|
-};
|
|
|
-const mostAccessDatasource = ref([]);
|
|
|
-
|
|
|
-//
|
|
|
-const getMostAccessList = async () => {
|
|
|
- try {
|
|
|
- const res = await getAction("/dmp-data/page-path/stats", queryParam);
|
|
|
- if (res.code == 200) {
|
|
|
- mostAccessDatasource.value = res.result;
|
|
|
- } else {
|
|
|
- mostAccessDatasource.value = [];
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error(error);
|
|
|
- }
|
|
|
-};
|
|
|
+ };
|
|
|
|
|
|
-const rangeDate = ref([]);
|
|
|
+ const rangeDate = ref([]);
|
|
|
|
|
|
-const onChangeDatePicker = (date, dateString) => {
|
|
|
- if (dateString.length > 0) {
|
|
|
- rangeDate.value = date;
|
|
|
- queryParam.start = dateString[0];
|
|
|
- queryParam.end = dateString[1];
|
|
|
- queryParam.dateType = undefined;
|
|
|
- reloadData();
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-//日期选择只能今天之前
|
|
|
-function disabledDate(current) {
|
|
|
- return current && current > dayjs();
|
|
|
-}
|
|
|
-
|
|
|
-const setTime = (time) => {
|
|
|
- queryParam.dateType = time;
|
|
|
- queryParam.start = "";
|
|
|
- queryParam.end = "";
|
|
|
-
|
|
|
- if (time == "") {
|
|
|
- rangeDate.value = undefined;
|
|
|
- } else if (time == "sevenDay") {
|
|
|
- rangeDate.value = [dayjs().add(-7, 'd'), dayjs().add(-1, 'd')];
|
|
|
- } else if (time == "thirtyDay") {
|
|
|
- rangeDate.value = [dayjs().add(-30, 'd'), dayjs().add(-1, 'd')];
|
|
|
- } else if (time == "yesterday") {
|
|
|
- rangeDate.value = [dayjs().add(-1, 'd'), dayjs().add(-1, 'd')];
|
|
|
- } else if (time == "today") {
|
|
|
- rangeDate.value = [dayjs(), dayjs()];
|
|
|
+ const onChangeDatePicker = (date, dateString) => {
|
|
|
+ if (dateString.length > 0) {
|
|
|
+ rangeDate.value = date;
|
|
|
+ queryParam.start = dateString[0];
|
|
|
+ queryParam.end = dateString[1];
|
|
|
+ queryParam.dateType = undefined;
|
|
|
+ reloadData();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ //日期选择只能今天之前
|
|
|
+ function disabledDate(current) {
|
|
|
+ return current && current > dayjs();
|
|
|
}
|
|
|
|
|
|
- reloadData();
|
|
|
-};
|
|
|
+ const setTime = (time) => {
|
|
|
+ queryParam.dateType = time;
|
|
|
+ queryParam.start = '';
|
|
|
+ queryParam.end = '';
|
|
|
+
|
|
|
+ if (time == '') {
|
|
|
+ rangeDate.value = undefined;
|
|
|
+ } else if (time == 'sevenDay') {
|
|
|
+ rangeDate.value = [dayjs().add(-7, 'd'), dayjs().add(-1, 'd')];
|
|
|
+ } else if (time == 'thirtyDay') {
|
|
|
+ rangeDate.value = [dayjs().add(-30, 'd'), dayjs().add(-1, 'd')];
|
|
|
+ } else if (time == 'yesterday') {
|
|
|
+ rangeDate.value = [dayjs().add(-1, 'd'), dayjs().add(-1, 'd')];
|
|
|
+ } else if (time == 'today') {
|
|
|
+ rangeDate.value = [dayjs(), dayjs()];
|
|
|
+ }
|
|
|
|
|
|
+ reloadData();
|
|
|
+ };
|
|
|
</script>
|
|
|
<style lang="less" scoped>
|
|
|
-.self-pop {
|
|
|
- .ant-popover-inner-content {
|
|
|
- background: rgb(245, 243, 254);
|
|
|
+ .self-pop {
|
|
|
+ .ant-popover-inner-content {
|
|
|
+ background: rgb(245, 243, 254);
|
|
|
|
|
|
- p {
|
|
|
- font-size: 13px;
|
|
|
+ p {
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- .ant-popover-arrow {
|
|
|
- border-color: rgb(245, 243, 254) !important;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.img-box {
|
|
|
- width: 22px;
|
|
|
- height: 15px;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
-
|
|
|
- img {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.ant-alert {
|
|
|
- /deep/ .ant-btn {
|
|
|
- border-radius: 0;
|
|
|
- margin-left: 10px;
|
|
|
+ .ant-popover-arrow {
|
|
|
+ border-color: rgb(245, 243, 254) !important;
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-.theme-color {
|
|
|
- color: @primary-color;
|
|
|
-}
|
|
|
-
|
|
|
-.r1 {
|
|
|
- margin: 20px;
|
|
|
-
|
|
|
- .choose-site {
|
|
|
+ .img-box {
|
|
|
+ width: 22px;
|
|
|
+ height: 15px;
|
|
|
display: flex;
|
|
|
- }
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
|
|
|
- .t1 {
|
|
|
- font-size: 18px;
|
|
|
- font-weight: 400;
|
|
|
- letter-spacing: 0px;
|
|
|
- line-height: 32px;
|
|
|
- margin-left: 10px;
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- .ant-form-item {
|
|
|
- flex: 1;
|
|
|
+ .ant-alert {
|
|
|
+ /deep/ .ant-btn {
|
|
|
+ border-radius: 0;
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- .ant-calendar-picker {
|
|
|
- margin-right: 20px;
|
|
|
+ .theme-color {
|
|
|
+ color: @primary-color;
|
|
|
}
|
|
|
|
|
|
+ .r1 {
|
|
|
+ margin: 20px;
|
|
|
|
|
|
- /deep/ .ant-btn {
|
|
|
- background: transparent;
|
|
|
- margin-right: 10px;
|
|
|
- padding: 4px 15px;
|
|
|
- border: 1px solid #d9d9d9;
|
|
|
- border-radius: 4px;
|
|
|
- transition: all 0.3s;
|
|
|
+ .choose-site {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
|
|
|
- &:hover {
|
|
|
- color: @primary-color;
|
|
|
- border-color: @primary-color;
|
|
|
+ .t1 {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 400;
|
|
|
+ letter-spacing: 0px;
|
|
|
+ line-height: 32px;
|
|
|
+ margin-left: 10px;
|
|
|
}
|
|
|
|
|
|
- &.active {
|
|
|
- color: @primary-color;
|
|
|
- background: #e6f7ff;
|
|
|
- border-color: @primary-color;
|
|
|
+ .ant-form-item {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ant-calendar-picker {
|
|
|
+ margin-right: 20px;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- .time-btn-group {
|
|
|
/deep/ .ant-btn {
|
|
|
- background: #fff;
|
|
|
+ background: transparent;
|
|
|
+ margin-right: 10px;
|
|
|
padding: 4px 15px;
|
|
|
border: 1px solid #d9d9d9;
|
|
|
+ border-radius: 4px;
|
|
|
transition: all 0.3s;
|
|
|
- margin-right: 0;
|
|
|
-
|
|
|
- &:first-child {
|
|
|
- border-top-left-radius: 4px;
|
|
|
- border-bottom-left-radius: 4px;
|
|
|
- }
|
|
|
-
|
|
|
- &:last-child {
|
|
|
- border-top-right-radius: 4px;
|
|
|
- border-bottom-right-radius: 4px;
|
|
|
- }
|
|
|
-
|
|
|
- &:not(:first-child) {
|
|
|
- margin-left: -1px;
|
|
|
- }
|
|
|
|
|
|
&:hover {
|
|
|
color: @primary-color;
|
|
|
border-color: @primary-color;
|
|
|
- position: relative;
|
|
|
- z-index: 1;
|
|
|
- background: #fff;
|
|
|
}
|
|
|
|
|
|
&.active {
|
|
|
color: @primary-color;
|
|
|
background: #e6f7ff;
|
|
|
border-color: @primary-color;
|
|
|
- position: relative;
|
|
|
- z-index: 2;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-.r2 {
|
|
|
- background: #fff;
|
|
|
- padding: 30px 20px;
|
|
|
- margin: 10px;
|
|
|
+ .time-btn-group {
|
|
|
+ /deep/ .ant-btn {
|
|
|
+ background: #fff;
|
|
|
+ padding: 4px 15px;
|
|
|
+ border: 1px solid #d9d9d9;
|
|
|
+ transition: all 0.3s;
|
|
|
+ margin-right: 0;
|
|
|
+
|
|
|
+ &:first-child {
|
|
|
+ border-top-left-radius: 4px;
|
|
|
+ border-bottom-left-radius: 4px;
|
|
|
+ }
|
|
|
|
|
|
- .ant-col:not(:last-child) {
|
|
|
- border-right: 1px solid #e6e6e6;
|
|
|
- }
|
|
|
+ &:last-child {
|
|
|
+ border-top-right-radius: 4px;
|
|
|
+ border-bottom-right-radius: 4px;
|
|
|
+ }
|
|
|
|
|
|
- p {
|
|
|
- margin: 0;
|
|
|
- text-align: center;
|
|
|
+ &:not(:first-child) {
|
|
|
+ margin-left: -1px;
|
|
|
+ }
|
|
|
|
|
|
- &.t1 {
|
|
|
- color: #333;
|
|
|
- margin-bottom: 15px;
|
|
|
+ &:hover {
|
|
|
+ color: @primary-color;
|
|
|
+ border-color: @primary-color;
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
|
|
|
- img {
|
|
|
- margin-right: 10px;
|
|
|
- width: 15px;
|
|
|
- margin-top: -5px;
|
|
|
+ &.active {
|
|
|
+ color: @primary-color;
|
|
|
+ background: #e6f7ff;
|
|
|
+ border-color: @primary-color;
|
|
|
+ position: relative;
|
|
|
+ z-index: 2;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- &.t2 {
|
|
|
- color: @primary-color;
|
|
|
- font-size: 30px;
|
|
|
- font-weight: 500;
|
|
|
- line-height: 1;
|
|
|
- padding-left: 25px;
|
|
|
- }
|
|
|
-
|
|
|
- &.t3 {
|
|
|
- font-size: 32px;
|
|
|
- font-weight: 700;
|
|
|
- letter-spacing: 0px;
|
|
|
- line-height: 38px;
|
|
|
- color: rgba(13, 62, 122, 1);
|
|
|
- }
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-.r5 {
|
|
|
- background: #fff;
|
|
|
- padding: 10px;
|
|
|
- border-radius: 10px;
|
|
|
- margin: 0 !important;
|
|
|
|
|
|
- .wrap {
|
|
|
- box-shadow: 0px 2px 4px 0px @primary-color;
|
|
|
- padding: 15px;
|
|
|
- border-radius: 10px;
|
|
|
- overflow: hidden;
|
|
|
+ .r2 {
|
|
|
background: #fff;
|
|
|
- transition: all .3s;
|
|
|
+ padding: 30px 20px;
|
|
|
+ margin: 0 10px 10px 10px;
|
|
|
|
|
|
- &.blue {
|
|
|
- box-shadow: 0px 2px 4px 0px @primary-color;
|
|
|
+ .ant-col:not(:last-child) {
|
|
|
+ border-right: 1px solid #e6e6e6;
|
|
|
}
|
|
|
|
|
|
- &.effect:hover {
|
|
|
- box-shadow: none;
|
|
|
- background: rgb(241, 248, 255);
|
|
|
- }
|
|
|
+ p {
|
|
|
+ margin: 0;
|
|
|
+ text-align: center;
|
|
|
|
|
|
- img {
|
|
|
- width: 15px;
|
|
|
- }
|
|
|
+ &.t1 {
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 15px;
|
|
|
|
|
|
- .fr {
|
|
|
- float: right;
|
|
|
- width: calc(100% - 15px);
|
|
|
- text-align: center;
|
|
|
+ img {
|
|
|
+ margin-right: 10px;
|
|
|
+ width: 15px;
|
|
|
+ margin-top: -5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- p:last-child {
|
|
|
+ &.t2 {
|
|
|
+ color: @primary-color;
|
|
|
font-size: 30px;
|
|
|
- text-align: center;
|
|
|
- margin-top: 10px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 1;
|
|
|
+ padding-left: 25px;
|
|
|
+ }
|
|
|
|
|
|
+ &.t3 {
|
|
|
+ font-size: 32px;
|
|
|
+ font-weight: 700;
|
|
|
+ letter-spacing: 0px;
|
|
|
+ line-height: 38px;
|
|
|
+ color: rgba(13, 62, 122, 1);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /deep/ .ant-table-thead > tr > th {
|
|
|
- background: rgb(241, 248, 255);
|
|
|
- border: none;
|
|
|
- color: #000;
|
|
|
+ .r5 {
|
|
|
+ background: #fff;
|
|
|
padding: 10px;
|
|
|
- }
|
|
|
+ border-radius: 10px;
|
|
|
+ margin: 0 !important;
|
|
|
|
|
|
- /deep/ .ant-table-tbody .ant-table-row td {
|
|
|
- padding: 10px;
|
|
|
- color: #000;
|
|
|
- }
|
|
|
+ .wrap {
|
|
|
+ box-shadow: 0px 2px 4px 0px @primary-color;
|
|
|
+ padding: 15px;
|
|
|
+ border-radius: 10px;
|
|
|
+ overflow: hidden;
|
|
|
+ background: #fff;
|
|
|
+ transition: all 0.3s;
|
|
|
+
|
|
|
+ &.blue {
|
|
|
+ box-shadow: 0px 2px 4px 0px @primary-color;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.effect:hover {
|
|
|
+ box-shadow: none;
|
|
|
+ background: rgb(241, 248, 255);
|
|
|
+ }
|
|
|
|
|
|
- .r5-1 {
|
|
|
- display: inline-block;
|
|
|
- width: 100%;
|
|
|
- margin-top: 30px;
|
|
|
+ img {
|
|
|
+ width: 15px;
|
|
|
+ }
|
|
|
|
|
|
- .fl {
|
|
|
- float: left;
|
|
|
- position: relative;
|
|
|
+ .fr {
|
|
|
+ float: right;
|
|
|
+ width: calc(100% - 15px);
|
|
|
+ text-align: center;
|
|
|
|
|
|
- .ant-btn {
|
|
|
- border-radius: 0;
|
|
|
- border: none;
|
|
|
- margin-right: 10px;
|
|
|
+ p:last-child {
|
|
|
+ font-size: 30px;
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .fr {
|
|
|
- float: right;
|
|
|
- line-height: 2;
|
|
|
+ /deep/ .ant-table-thead > tr > th {
|
|
|
+ background: rgb(241, 248, 255);
|
|
|
+ border: none;
|
|
|
+ color: #000;
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
|
|
|
- span {
|
|
|
- margin-right: 30px;
|
|
|
+ /deep/ .ant-table-tbody .ant-table-row td {
|
|
|
+ padding: 10px;
|
|
|
+ color: #000;
|
|
|
+ }
|
|
|
|
|
|
- i {
|
|
|
- display: inline-block;
|
|
|
- width: 25px;
|
|
|
- height: 3px;
|
|
|
- background: #544BEB;
|
|
|
- position: relative;
|
|
|
- top: -4px;
|
|
|
- margin-right: 20px;
|
|
|
+ .r5-1 {
|
|
|
+ display: inline-block;
|
|
|
+ width: 100%;
|
|
|
+ margin-top: 30px;
|
|
|
+
|
|
|
+ .fl {
|
|
|
+ float: left;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .ant-btn {
|
|
|
+ border-radius: 0;
|
|
|
+ border: none;
|
|
|
+ margin-right: 10px;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- &:last-child i {
|
|
|
- background: #F0B358;
|
|
|
+ .fr {
|
|
|
+ float: right;
|
|
|
+ line-height: 2;
|
|
|
+
|
|
|
+ span {
|
|
|
+ margin-right: 30px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ display: inline-block;
|
|
|
+ width: 25px;
|
|
|
+ height: 3px;
|
|
|
+ background: #544beb;
|
|
|
+ position: relative;
|
|
|
+ top: -4px;
|
|
|
+ margin-right: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:last-child i {
|
|
|
+ background: #f0b358;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- .box {
|
|
|
- border-radius: 10px;
|
|
|
- text-align: center;
|
|
|
- min-height: 180px;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: center;
|
|
|
+ .box {
|
|
|
+ border-radius: 10px;
|
|
|
+ text-align: center;
|
|
|
+ min-height: 180px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
|
|
|
- p {
|
|
|
- color: #fff;
|
|
|
+ p {
|
|
|
+ color: #fff;
|
|
|
|
|
|
- img {
|
|
|
- width: 19px;
|
|
|
- margin: -5px 10px 0 0;
|
|
|
+ img {
|
|
|
+ width: 19px;
|
|
|
+ margin: -5px 10px 0 0;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- .num {
|
|
|
- font-size: 30px;
|
|
|
- margin-bottom: 10px;
|
|
|
- }
|
|
|
+ .num {
|
|
|
+ font-size: 30px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
|
|
|
- &.b1 {
|
|
|
- background: rgb(233, 107, 95);
|
|
|
- }
|
|
|
+ &.b1 {
|
|
|
+ background: rgb(233, 107, 95);
|
|
|
+ }
|
|
|
|
|
|
- &.b2 {
|
|
|
- background: rgb(88, 204, 168);
|
|
|
- }
|
|
|
+ &.b2 {
|
|
|
+ background: rgb(88, 204, 168);
|
|
|
+ }
|
|
|
|
|
|
- &.b3 {
|
|
|
- background: rgb(124, 152, 252);
|
|
|
- }
|
|
|
+ &.b3 {
|
|
|
+ background: rgb(124, 152, 252);
|
|
|
+ }
|
|
|
|
|
|
- &.b4 {
|
|
|
- background: #F0B358;
|
|
|
+ &.b4 {
|
|
|
+ background: #f0b358;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
</style>
|