| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510 |
- <?php
- use common\helpers\ComponentHelper;
- ComponentHelper::loadComponentView('components/count-to', __DIR__);
- ComponentHelper::loadComponentView('components/list', __DIR__);
- ComponentHelper::loadComponentView('components/my-table', __DIR__);
- ComponentHelper::loadComponentView('components/mini-echarts', __DIR__);
- ComponentHelper::loadComponentView('components/screen-contain', __DIR__);
- ComponentHelper::loadComponentView('components/header-time', __DIR__);
- ?>
- <style>
- .screen-container {
- min-width: 100%;
- }
-
- #flow-analysis{
- height: 100%;
- }
- .flow-analysis {
- min-height: 700px;
- }
- .flow-analysis .header {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 80px;
- color: #F8F8F8;
- }
- .count-to {
- font-size: 60px;
- margin-left: 24px;
- }
- .fa-content {
- padding: 50px 80px;
- justify-content: space-between;
- flex-wrap: wrap;
- }
- .fa-content-left {
- padding: 27px 30px 30px;
- }
- .fa-content-left,
- .fa-content-right {
- /* width: 482px; */
- width: 30%;
- }
- .fa-content-right{
- display: flex;
- flex-direction: column;
- }
- .fa-content-center {
- /* width: 617px; */
- width: 37%;
- margin: 0 23px;
- position: relative;
- }
- .center-tabs{
- position: absolute;
- width: 100%;
- bottom: 0;
- }
- .echrats-item-bg {
- background: linear-gradient(137deg, #0034E4 0%, #14141A 20%, rgba(7, 7, 9, 0.89) 80%, #0034E4 100%);
- border: 1px solid #0034E4;
- border-radius: 16px;
- }
- .fa-content-right>div {
- width: 100%;
- height: 379px;
- /* height: 227px; */
- padding-top: 20px;
- margin-bottom: 15px;
- /* flex: 1; */
- }
- .fa-content-right>div:last-child {
- margin-bottom: 0;
- }
- #echarts3,
- #echarts2 {
- width: 100%;
- height: 100%;
- }
- .commodity-flow-title {
- font-size: 30px;
- font-family: Source Han Sans CN;
- font-weight: 500;
- color: #F8F8F8;
- margin-bottom: 23px;
- }
- .fcl-title {
- font-size: 30px;
- font-family: Source Han Sans CN;
- font-weight: 500;
- line-height: 30px;
- color: #F8F8F8;
- margin-bottom: 27px;
- }
- .item {
- /* width: 203px; */
- flex-basis: 47%;
- height: 92px;
- background: linear-gradient(90deg, rgba(0, 52, 228, 0.4) 0%, rgba(0, 0, 3, 0) 100%);
- border-radius: 8px;
- margin-bottom: 20px;
- padding-left: 30px;
- }
- .item-number {
- font-size: 26px;
- font-family: DIN;
- font-weight: bold;
- line-height: 32px;
- color: #F8F8F8;
- }
- .item-label {
- font-size: 15px;
- font-family: Source Han Sans CN;
- font-weight: 400;
- line-height: 25px;
- color: #CCCFDA;
- opacity: 1;
- }
- .item-img {
- width: 60px;
- height: 45px;
- /* border-top: 2px solid #0034E4;
- background: linear-gradient(180deg, rgba(0, 52, 228, 0.56) 0%, rgba(0, 52, 228, 0) 100%); */
- margin-bottom: 6px;
- }
- .test-echrats {
- width: 100%;
- height: 100%;
- }
- .echarts3-text{
- font-size: 16px;
- flex: 1;
- text-align: center;
- }
- .echarts3-num{
- font-size: 28px;
- line-height: 50px;
- }
- .echarts3-left-bor{
- width: 12px;
- height: 12px;
- display: inline-block;
- border-radius: 50%;
- line-height: 16px;
- }
- .echarts3-bottom{
- margin: 20px 0;
- }
- </style>
- <div id="flow-analysis" v-cloak>
- <screen-contain text-left="流量分析" :is-fix="false">
- <template v-slot:right>
- <!-- <div flex style="padding: 0 10px;">
- <div flex>
- <div style="font-size: 38px;">9:34</div>
- <div style="font-size: 16px;flex-direction: column;margin-left :10px " flex="main:center">
- <div style="width: 100%;">星期五 上午</div>
- <div>2021年7月23日</div>
- </div>
- </div>
- </div> -->
- <header-time></header-time>
- </template>
- <div class="flow-analysis">
- <div class="header">
- <div style="font-size: 45px;">平台总人数</div>
- <count-to :end-val="totalCount" :duration="10000" style="margin: 0 20px" class="count-to"></count-to>
- <div style="font-size: 18px;">
- <div>访问数:<span>{{echartsData.flow_datas?echartsData.flow_datas.total_visitors:'-'}}</span></div>
- <div>流量数:<span>{{echartsData.flow_datas?echartsData.flow_datas.total_views:'-'}}</span></div>
- </div>
- </div>
- <div class="fa-content" flex>
- <div class="fa-content-left echrats-item-bg">
- <div class="fcl-title">流量数据</div>
- <div flex="wrap:wrap main:justify">
- <div class="item" flex="cross:center main:justify" v-for="(item,index) in flowList" :key="index" :style=" index >= flowList.length - 2 ? 'margin-bottom:0': '' ">
- <div>
- <div class="item-number">{{echartsData.flow_datas?numSystemVal(echartsData.flow_datas[item.key], item.key):'-'}}</div>
- <div class="item-label">{{item.text}}</div>
- </div>
- <div flex="wrap:wrap main:right">
- <div class="item-img">
- <mini-echarts></mini-echarts>
- </div>
- <!-- <div>
- <span style="color: #1BBC26;"><i class="el-icon-arrow-down"></i>1.2%</span>
- <span style="color: #C12727;"><i class="el-icon-arrow-up"></i>1.2%</span>
- </div> -->
- </div>
- </div>
- </div>
- </div>
- <div class="fa-content-center">
- <div style="height: 469px;margin-bottom:15px">
- <div id="echarts2"></div>
- </div>
- <div class="echrats-item-bg center-tabs" flex style="height: 284px;padding: 20px;flex-direction: column;">
- <div class="commodity-flow-title">地区订单数</div>
- <div style="flex:1;height:0">
- <my-table :data="orderSort" :options="orderOptions">
- <template v-slot:sort="{ item,index }">
- <div>{{index+1}}</div>
- </template>
- </my-table>
- </div>
- </div>
- </div>
- <div class="fa-content-right">
- <div class="echrats-item-bg">
- <div class="fcl-title" style="padding-left: 30px;">新老客户占比</div>
- <div style="height: 190px;" id="echarts3"></div>
- <div class="echarts3-bottom" flex>
- <div class="echarts3-text">
- <div class="echarts3-num">{{echartsData.flow_datas?echartsData.flow_datas.new_customers:'-'}}</div>
- <div>
- <span style="background: #ED7453;" class="echarts3-left-bor"></span>
- 新客户人数
- </div>
- </div>
- <div class="echarts3-text">
- <div class="echarts3-num">{{echartsData.flow_datas?echartsData.flow_datas.regular_customers:'-'}}</div>
- <div>
- <span style="background: #0034E4;" class="echarts3-left-bor"></span>
- 老客户人数
- </div>
- </div>
- </div>
- </div>
- <div class="echrats-item-bg" flex style="height: 405px;padding: 30px 30px ;flex-direction: column;">
- <div class="commodity-flow-title">商品流量排行</div>
- <div style="flex:1;height:0">
- <my-table :data="echartsData.good_rankings" :options="goodsOptions">
- <template v-slot:sort="{ item,index }">
- <div>{{index+1}}</div>
- </template>
- </my-table>
- </div>
- </div>
- </div>
- </div>
- </div>
- </screen-contain>
- </div>
- <!-- <script src="https://cdn.jsdelivr.net/npm/echarts@5.2.2/dist/echarts.min.js"></script> -->
- <script src="/resources/unpkg/echarts@5.2.2/dist/echarts.min.js"></script>
- <script src="/resources/js/china.js"></script>
- <script>
- const app = new Vue({
- el: '#flow-analysis',
- data() {
- return {
- flowList: [{
- key: 'total_users',
- text: '注册人数'
- }, {
- key: 'visitors_rate',
- text: '访客占比'
- }, {
- key: 'number_of_orders',
- text: '下单人数'
- }, {
- key: 'total_pay_people',
- text: '支付人数'
- }, {
- key: 'total_pay_orders',
- text: '支付订单'
- }, {
- key: 'total_pay_money',
- text: '支付金额'
- }, {
- key: 'customer_unit_price',
- text: '客单价'
- }, {
- key: 'access_pay_rate',
- text: '访问-支付转化率'
- }, {
- key: 'access_place_order_rate',
- text: '访问-下单转化率'
- }, {
- key: 'repurchase_people',
- text: '复购人数'
- }, {
- key: 'repurchase_money',
- text: '复购金额'
- }, {
- key: 'share_people',
- text: '分享人数'
- },],
- orderOptions: [{
- props: "sort",
- label: '排行',
- slot: true,
- textAlign: 'left',
- width: 50,
- }, {
- props: "province_name",
- // width: 200,
- label: '地区名称',
- textAlign: 'left'
- }, {
- props: "total_orders",
- label: '订单数',
- },],
- goodsOptions: [{
- props: "sort",
- label: '排行',
- slot: true,
- textAlign: 'left',
- width: 50,
- }, {
- props: "goods_name",
- label: '商品名称',
- textAlign: 'left'
- }, {
- props: "total_views",
- label: '浏览量',
- }, ],
- echartsData: {},
- totalCount: 0,
- orderSort: [],
- }
- },
- methods: {
- getEchartsData(){
- let that = this;
- request({
- params: {
- r: 'mall/data-census/flowan-alyse',
- },
- method: 'get'
- }).then(e => {
- if (e.data.code === 0) {
- console.info(e.data.data);
- this.echartsData = e.data.data;
- this.totalCount = e.data.data.flow_datas.total_users;
- this.orderSort.push(...e.data.data.region_datas.sort((a,b) => { return b.total_orders-a.total_orders}).slice(0,10));
-
- } else {
- this.$message.error(e.data.msg);
- }
- this.echarts3Init()
- this.echarts2Init()
- });
- },
- echarts3Init() {
- var chartDom = document.getElementById('echarts3');
- var myChart = echarts.init(chartDom);
- var option = {
- tooltip: {
- trigger: 'item'
- },
- color: ['#0034E4', '#ED7453'],
- series: [{
- name: '会员等级分布',
- type: 'pie',
- radius: ['50%', '70%'],
- avoidLabelOverlap: false,
- label: {
- show: true,
- position: 'outside',
- color: '#fff',
- formatter: (params) => {
- return params.value + '%\n' + params.name;
- }
- },
- labelLine: {
- show: true,
- length: 15,
- lineStyle: {
- color: '#fff'
- }
- },
- data: [{
- value: this.echartsData.pie_chart_datas.data[1],
- name: this.echartsData.pie_chart_datas.names[1],
- },
- {
- value: this.echartsData.pie_chart_datas.data[0],
- name: this.echartsData.pie_chart_datas.names[0],
- }
- ]
- }]
- };
- option && myChart.setOption(option);
- },
- echarts2Init() {
- // 基于准备好的dom,初始化echarts实例
- var mapChart = echarts.init(document.getElementById('echarts2'));
- // 地图数据
- let newData = [];
- this.echartsData.map_order_datas.forEach(item => {
- item.name = item.name.split('省')[0];
- item.name = item.name.split('市')[0];
- item.name = item.name.split('特别行政区')[0];
- item.name = item.name.split('壮族自治区')[0];
- item.name = item.name.split('回族自治区')[0];
- item.name = item.name.split('维吾尔自治区')[0];
- item.name = item.name.split('自治区')[0];
- if(!item.value){
- newData.push(item)
- }
- });
- this.echartsData.map_order_datas = this.echartsData.map_order_datas.filter(v => {return v.value > 0})
- console.log(newData);
- var option = {
- tooltip: {
- trigger: 'item',
- formatter: (params) => {
- return params.name + ': ' + (params.value || 0);
- }
- },
- visualMap: {
- show: false,
- x: 'left',
- y: 'bottom',
- splitList: [
- {
- start: 0,
- end: 80
- }, {
- start: 80,
- end: 90
- },
- {
- start: 90,
- end: 100
- }, {
- start: 100,
- // end: 99999999
- },
-
- ],
- /* inRange: {
- color: ['#1e60ff', '#0540c3', '#0032c1', '#002390']
- }, */
- // color: ['#002390','#1E60FF', '#0540c3', '#0032c1']
- color: ['#0032c1','#0540c3', '#1E60FF']
- },
- series: [{
- type: 'map',
- mapType: 'china',
- roam: false,
- label: {
- normal: {
- show: false
- },
- emphasis: {
- show: false
- }
- },
- itemStyle: {
- areaColor: '#002390',
- borderColor: '#4478F5'
- },
- data: this.echartsData.map_order_datas,
- },]
- };
- mapChart.setOption(option);
- },
- numSystemVal(val, key) {
- if (val * 1 < 10000) {
- val = val * 1
- } else {
- if ((val * 1) % 10000 == 0) {
- val = parseInt((val * 1) / 10000) + 'W'
- } else {
- val = parseInt((val * 1) / 10000) + 'W+'
- }
- }
- let rateKeys = ['visitors_rate', 'access_pay_rate', 'access_place_order_rate'];
- if (-1 != rateKeys.indexOf(key) && val > 0) {
- val *= 100;
- val = val.toFixed(2)
- val += '%';
- }
- return val
- }
- },
- mounted() {
- this.getEchartsData();
- }
- })
- </script>
|