|
@@ -1,8 +1,8 @@
|
|
|
<template>
|
|
|
- <div class="RealOnline">
|
|
|
+ <div class="Content">
|
|
|
<el-breadcrumb separator-class="el-icon-arrow-right">
|
|
|
<el-breadcrumb-item>新媒体</el-breadcrumb-item>
|
|
|
- <el-breadcrumb-item>用户分析</el-breadcrumb-item>
|
|
|
+ <el-breadcrumb-item>应用分析</el-breadcrumb-item>
|
|
|
<el-breadcrumb-item>版本分析</el-breadcrumb-item>
|
|
|
</el-breadcrumb>
|
|
|
<el-card class="box-card">
|
|
@@ -43,25 +43,6 @@
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="版本">
|
|
|
- <el-select
|
|
|
- multiple
|
|
|
- collapse-tags
|
|
|
- clearable
|
|
|
- v-model="form.version"
|
|
|
- placeholder="请选择版本"
|
|
|
- @change="changeversion"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in version"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
- :disabled="item.disabled"
|
|
|
- >
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
<el-form-item label="渠道">
|
|
|
<el-select
|
|
|
multiple
|
|
@@ -81,15 +62,17 @@
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="来源">
|
|
|
+ <el-form-item label="版本">
|
|
|
<el-select
|
|
|
+ multiple
|
|
|
collapse-tags
|
|
|
clearable
|
|
|
- v-model="form.client"
|
|
|
- placeholder="请选择来源"
|
|
|
+ v-model="form.version"
|
|
|
+ placeholder="请选择版本"
|
|
|
+ @change="changeversion"
|
|
|
>
|
|
|
<el-option
|
|
|
- v-for="item in client"
|
|
|
+ v-for="item in version"
|
|
|
:key="item.value"
|
|
|
:label="item.label"
|
|
|
:value="item.value"
|
|
@@ -100,115 +83,201 @@
|
|
|
</el-form-item>
|
|
|
<el-form-item style="float: right">
|
|
|
<el-button type="primary" @click="onSubmit">查询</el-button>
|
|
|
- <el-button type="primary" @click="onExport">导出</el-button>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
</el-card>
|
|
|
<br />
|
|
|
<el-card class="box-card">
|
|
|
- <div class="head" v-if="oriData.total">
|
|
|
- <div
|
|
|
- v-for="(item, i) in oriData.total"
|
|
|
- :key="i + item.key"
|
|
|
- class="head-item"
|
|
|
- @click="
|
|
|
- () =>
|
|
|
- item.key !== 'downloads' &&
|
|
|
- type !== item.key &&
|
|
|
- changeData(item.key, item.name)
|
|
|
- "
|
|
|
- :style="{
|
|
|
- borderTopColor: type === item.key ? '#396fff' : '#fff',
|
|
|
- }"
|
|
|
+ <div style="text-align: right">
|
|
|
+ <el-button-group>
|
|
|
+ <el-button size="small" type="primary"> 新用户数 </el-button>
|
|
|
+ <el-button size="small" type="primary"> 启动次数 </el-button>
|
|
|
+ </el-button-group>
|
|
|
+ </div>
|
|
|
+ <br />
|
|
|
+ <div ref="regionChart"></div>
|
|
|
+ <br />
|
|
|
+ <div style="text-align: right">
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ style="margin-left: 0.5em"
|
|
|
+ type="primary"
|
|
|
+ @click="onExport"
|
|
|
>
|
|
|
- <div>{{ item.name }}</div>
|
|
|
- <div class="value">
|
|
|
- <!-- oriData.total.activeUser -->
|
|
|
- <countTo
|
|
|
- v-if="!item.isNum"
|
|
|
- :startVal="0"
|
|
|
- :endVal="item.value - 0"
|
|
|
- :duration="1500"
|
|
|
- ></countTo>
|
|
|
- <span v-if="item.isNum" v-text="item.value"></span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ 导出
|
|
|
+ </el-button>
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="realLineChart" ref="realLineChart"></div>
|
|
|
+ <br />
|
|
|
+ <br />
|
|
|
<el-table
|
|
|
- v-if="this.oriData && this.oriData.list && this.oriData.list.length"
|
|
|
- :data="showList"
|
|
|
+ :data="table.records || []"
|
|
|
style="width: 100%"
|
|
|
- :header-cell-style="{ backgroundColor: '#f4f5f7', color: '#606266' }"
|
|
|
+ @sort-change="tableChange"
|
|
|
+ :header-cell-style="{
|
|
|
+ backgroundColor: '#f4f5f7',
|
|
|
+ color: '#606266',
|
|
|
+ }"
|
|
|
>
|
|
|
- <el-table-column prop="dt" label="日期" />
|
|
|
- <el-table-column prop="activeUser" label="活跃用户">
|
|
|
+ <el-table-column
|
|
|
+ prop="contentId"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ label="内容ID"
|
|
|
+ show-overflow-tooltip
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
|
- <countTo
|
|
|
- :startVal="scope.row.activeUser"
|
|
|
- :endVal="scope.row.activeUser"
|
|
|
- :duration="100"
|
|
|
- ></countTo>
|
|
|
+ <span v-text="scope.row.contentId || '-'"></span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="newUser" label="新增用户">
|
|
|
+ <el-table-column
|
|
|
+ prop="title"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ width="300"
|
|
|
+ label="标题"
|
|
|
+ show-overflow-tooltip
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-text="scope.row.title || '-'"></span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="应用名称"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
+ <template #default>
|
|
|
+ <span>{{ form.app || "-" }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="publishTime"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ label="发布时间"
|
|
|
+ show-overflow-tooltip
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-text="scope.row.publishTime || '-'"></span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="平均阅读时长"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-orders="['descending', null]"
|
|
|
+ prop="cduration"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-text="timeFormat(scope.row.cduration)"></span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="阅读次数"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-orders="['descending', null]"
|
|
|
+ prop="cpv"
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
|
<countTo
|
|
|
- :startVal="scope.row.newUser"
|
|
|
- :endVal="scope.row.newUser"
|
|
|
+ :startVal="0"
|
|
|
+ :endVal="scope.row.cpv || 0"
|
|
|
:duration="100"
|
|
|
></countTo>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="totalUser" label="累计用户">
|
|
|
+ <el-table-column
|
|
|
+ label="点赞次数"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-orders="['descending', null]"
|
|
|
+ prop="csupport"
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
|
<countTo
|
|
|
- :startVal="scope.row.totalUser"
|
|
|
- :endVal="scope.row.totalUser"
|
|
|
+ :startVal="0"
|
|
|
+ :endVal="scope.row.csupport || 0"
|
|
|
:duration="100"
|
|
|
></countTo>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="startTimes" label="启动次数">
|
|
|
+ <el-table-column
|
|
|
+ label="收藏次数"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-orders="['descending', null]"
|
|
|
+ prop="ccollect"
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
|
<countTo
|
|
|
- :startVal="scope.row.startTimes"
|
|
|
- :endVal="scope.row.startTimes"
|
|
|
+ :startVal="0"
|
|
|
+ :endVal="scope.row.ccollect || 0"
|
|
|
:duration="100"
|
|
|
></countTo>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="duration" label="人均使用时长">
|
|
|
+ <el-table-column
|
|
|
+ label="分享次数"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-orders="['descending', null]"
|
|
|
+ prop="cshare"
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
|
- {{ timeFormat(scope.row.durationUser) }}
|
|
|
+ <countTo
|
|
|
+ :startVal="0"
|
|
|
+ :endVal="scope.row.cshare || 0"
|
|
|
+ :duration="100"
|
|
|
+ ></countTo>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="duration" label="次均使用时长">
|
|
|
+ <el-table-column
|
|
|
+ label="观看用户数"
|
|
|
+ header-align="center"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-orders="['descending', null]"
|
|
|
+ prop="cuser"
|
|
|
+ >
|
|
|
<template #default="scope">
|
|
|
- {{ timeFormat(scope.row.durationTimes) }}
|
|
|
+ <countTo
|
|
|
+ :startVal="0"
|
|
|
+ :endVal="scope.row.cuser || 0"
|
|
|
+ :duration="100"
|
|
|
+ ></countTo>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
- <div v-if="oriData.list && oriData.list.length">
|
|
|
- <el-pagination
|
|
|
- v-if="Math.ceil(oriData.list.length / 10) > 1"
|
|
|
- :current-page="page"
|
|
|
- layout="prev, pager, next"
|
|
|
- :total="oriData.list.length"
|
|
|
- @current-change="pagechange"
|
|
|
- />
|
|
|
- </div>
|
|
|
+ <br />
|
|
|
+ <el-pagination
|
|
|
+ layout="prev, pager, next"
|
|
|
+ :page-size="form.size"
|
|
|
+ :current-page="form.page"
|
|
|
+ :total="table.total"
|
|
|
+ background
|
|
|
+ @current-change="changePage"
|
|
|
+ />
|
|
|
</el-card>
|
|
|
</div>
|
|
|
</template>
|
|
|
-
|
|
|
<script>
|
|
|
// @ is an alias to /src
|
|
|
-import { getRule, getAppList, getHistory, getSearchData } from "@/api/index";
|
|
|
+import {
|
|
|
+ getRule,
|
|
|
+ getAppList,
|
|
|
+ getSearchData,
|
|
|
+ getContentChart,
|
|
|
+ getContentPage,
|
|
|
+} from "@/api/index";
|
|
|
|
|
|
import countTo from "@/components/counto/vue-countTo.vue";
|
|
|
-
|
|
|
import * as echarts from "echarts/core";
|
|
|
import { LineChart } from "echarts/charts";
|
|
|
import {
|
|
@@ -229,58 +298,55 @@ echarts.use([
|
|
|
LegendComponent,
|
|
|
]);
|
|
|
|
|
|
-// import config from "@/config/index";
|
|
|
+import config from "@/config/index";
|
|
|
let chart = undefined;
|
|
|
export default {
|
|
|
- name: "RealOnline",
|
|
|
+ name: "Version",
|
|
|
data() {
|
|
|
return {
|
|
|
- type: "",
|
|
|
lastParams: {},
|
|
|
- page: 1,
|
|
|
+ table: {},
|
|
|
form: {
|
|
|
app: "",
|
|
|
version: [],
|
|
|
channel: [],
|
|
|
date: [],
|
|
|
- client: ""
|
|
|
},
|
|
|
cycle: [],
|
|
|
- oriData: {},
|
|
|
showList: [],
|
|
|
- version: [],
|
|
|
channel: [],
|
|
|
- client: []
|
|
|
+ version: [],
|
|
|
};
|
|
|
},
|
|
|
async mounted() {
|
|
|
if (chart && chart.dispose) chart.dispose();
|
|
|
- const { source, appV, appC, clentV, appli, appCLi, appVLi, clentli } =
|
|
|
+ const { source, appV, appC, appli, appVLi, appCLi } =
|
|
|
await this.getAppListFunc();
|
|
|
const keys = {
|
|
|
value: "mname",
|
|
|
label: "mname",
|
|
|
};
|
|
|
- let client = clentli.find(r=>r.mdefault).mcode.toString();
|
|
|
this.cycle = this.verifyList(appli, source, keys, false);
|
|
|
this.channel = this.verifyList(appCLi, appC, keys, true);
|
|
|
this.version = this.verifyList(appVLi, appV, keys, true);
|
|
|
- this.client = this.verifyList(clentli, clentV, {
|
|
|
- value: "mcode",
|
|
|
- label: "mname",
|
|
|
- }, true);
|
|
|
this.form = {
|
|
|
// app: (this.cycle[0] || { value: "" }).value,
|
|
|
app: "起点新闻",
|
|
|
version: [(this.version[0] || { value: "" }).value],
|
|
|
- client,
|
|
|
channel: [(this.channel[0] || { value: "" }).value],
|
|
|
date: [new Date(Date.now() - 604800000), new Date(Date.now() - 86400000)],
|
|
|
+ page: 1,
|
|
|
+ size: 20,
|
|
|
};
|
|
|
this.onSubmit();
|
|
|
},
|
|
|
computed: {},
|
|
|
methods: {
|
|
|
+ tableChange() {
|
|
|
+ this.form.page = 1;
|
|
|
+ this.lastParams.page = 1;
|
|
|
+ getContentPage(this.lastParams).then(r => (this.table = r || {}));
|
|
|
+ },
|
|
|
verifyList(list, verify, obj, more) {
|
|
|
if (!obj) return;
|
|
|
let li = list || [];
|
|
@@ -296,19 +362,9 @@ export default {
|
|
|
}
|
|
|
return out;
|
|
|
},
|
|
|
- pagechange(p) {
|
|
|
- this.page = p;
|
|
|
- this.pushShowList();
|
|
|
- },
|
|
|
- pushShowList() {
|
|
|
- let s = this.page - 1 < 0 ? 0 : (this.page - 1) * 10;
|
|
|
- let e = this.page * 10;
|
|
|
- let li = JSON.parse(JSON.stringify(this.oriData.list || []));
|
|
|
- let out = [];
|
|
|
- for (let i = s; i < e; i++) {
|
|
|
- li[i] && out.push(li[i]);
|
|
|
- }
|
|
|
- this.showList = out;
|
|
|
+ changePage(e) {
|
|
|
+ this.form.page = e;
|
|
|
+ this.onSubmit();
|
|
|
},
|
|
|
onSubmit() {
|
|
|
this.lastParams = {
|
|
@@ -317,90 +373,43 @@ export default {
|
|
|
end: this.FormData(this.form.date[1]),
|
|
|
manufacturer: this.form.channel == -1 ? undefined : this.form.channel,
|
|
|
version: this.form.version == -1 ? undefined : this.form.version,
|
|
|
- lib: this.form.client == -1 ? undefined : this.form.client,
|
|
|
+ page: this.form.page,
|
|
|
+ pageSize: this.form.size,
|
|
|
};
|
|
|
- getHistory(this.lastParams)
|
|
|
- .then(r => {
|
|
|
- if (!this.$refs.realLineChart) return;
|
|
|
- let oriData = r || {};
|
|
|
- const total = oriData.total || {},
|
|
|
- keys = Object.keys(total),
|
|
|
- color = ["rgb(244, 127, 146)", "rgb(17, 160, 248)"],
|
|
|
- p = [];
|
|
|
- let tab = undefined,
|
|
|
- tabName = undefined;
|
|
|
- for (let i = 0; i < keys.length; i++) {
|
|
|
- const v = keys[i];
|
|
|
- if (!total[v].value && total[v].value !== 0) continue;
|
|
|
- let isNum = /duration/g.test(v);
|
|
|
- let value = "";
|
|
|
- if (isNum && typeof total[v].value === "number")
|
|
|
- value = this.timeFormat(total[v].value);
|
|
|
- else value = total[v].value;
|
|
|
- if (!tab && v !== "downloads") {
|
|
|
- tab = v;
|
|
|
- tabName = total[v].name;
|
|
|
- }
|
|
|
- p.push({
|
|
|
- name: total[v].name,
|
|
|
- value,
|
|
|
- color: color[i % 2],
|
|
|
- key: v,
|
|
|
- isNum,
|
|
|
- });
|
|
|
- }
|
|
|
- this.oriData = {
|
|
|
- list: oriData.list || [],
|
|
|
- total: p,
|
|
|
- };
|
|
|
- this.changeData(tab, tabName);
|
|
|
- chart.hideLoading();
|
|
|
- this.page = 1;
|
|
|
- this.pushShowList();
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- this.oriData = {};
|
|
|
- this.pushShowList();
|
|
|
- chart && chart.clear() && chart.hideLoading();
|
|
|
- });
|
|
|
- },
|
|
|
- changeData(type, title) {
|
|
|
- this.type = type;
|
|
|
- const keyList = [],
|
|
|
- valueList = [];
|
|
|
- (this.oriData.list || []).map(v => {
|
|
|
- keyList.push(v.dt);
|
|
|
- valueList.push(v[this.type]);
|
|
|
+ getContentPage(this.lastParams).then(r => (this.table = r || {}));
|
|
|
+ getContentChart({
|
|
|
+ app: this.form.app,
|
|
|
+ start: this.FormData(this.form.date[0]),
|
|
|
+ end: this.FormData(this.form.date[1]),
|
|
|
+ version: this.form.version == -1 ? undefined : this.form.version,
|
|
|
+ }).then(resChart => {
|
|
|
+ let keyList = [],
|
|
|
+ valueList = [],
|
|
|
+ titles = [];
|
|
|
+ if ((resChart || []).length && chart && chart.clear)
|
|
|
+ return chart.clear();
|
|
|
+ this.createImage(keyList, valueList, titles);
|
|
|
});
|
|
|
- chart && chart.clear();
|
|
|
- this.createImage(keyList, valueList, title);
|
|
|
},
|
|
|
createImage(keyList, valueList, title) {
|
|
|
- !chart && (chart = echarts.init(this.$refs.realLineChart));
|
|
|
+ !chart && (chart = echarts.init(this.$refs.regionChart));
|
|
|
chart.resize({
|
|
|
- height: (this.$refs.realLineChart.offsetWidth * 4) / 16,
|
|
|
+ height: (this.$refs.regionChart.offsetWidth * 4) / 16,
|
|
|
});
|
|
|
- const _this = this;
|
|
|
chart.setOption({
|
|
|
tooltip: {
|
|
|
trigger: "axis",
|
|
|
- formatter(v) {
|
|
|
- const item = v[0] || {};
|
|
|
- let val = item.data || 0;
|
|
|
- if (_this.type === "duration") val = _this.timeFormat(val);
|
|
|
- return item.axisValue + "<br />" + title + ":" + val;
|
|
|
- },
|
|
|
},
|
|
|
toolbox: {
|
|
|
feature: {
|
|
|
saveAsImage: {
|
|
|
type: "jpg",
|
|
|
- name: "趋势",
|
|
|
+ name: "内容分析-" + this.form.app,
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
legend: {
|
|
|
- data: [title],
|
|
|
+ data: title,
|
|
|
},
|
|
|
grid: {
|
|
|
left: "3%",
|
|
@@ -420,64 +429,37 @@ export default {
|
|
|
axisLabel: {
|
|
|
formatter(v) {
|
|
|
let val = v;
|
|
|
- if (_this.type === "duration") val = _this.timeFormat(val);
|
|
|
- else {
|
|
|
- if (val >= 100000000) {
|
|
|
- val = (val / 100000000).toFixed(2) + "亿";
|
|
|
- } else if (val >= 10000) {
|
|
|
- val = (val / 10000).toFixed(2) + "万";
|
|
|
- }
|
|
|
+ if (val >= 100000000) {
|
|
|
+ val = (val / 100000000).toFixed(2) + "亿";
|
|
|
+ } else if (val >= 10000) {
|
|
|
+ val = (val / 10000).toFixed(2) + "万";
|
|
|
}
|
|
|
return val;
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: title,
|
|
|
- data: valueList,
|
|
|
+ series: valueList.map((v, i) => {
|
|
|
+ return {
|
|
|
+ name: title[i],
|
|
|
+ data: v,
|
|
|
symbolSize: 0,
|
|
|
lineStyle: {
|
|
|
width: 1,
|
|
|
},
|
|
|
type: "line",
|
|
|
smooth: true,
|
|
|
- color: "rgba(58,132,255,.9)",
|
|
|
- areaStyle: {
|
|
|
- color: {
|
|
|
- type: "linear",
|
|
|
- x: 0,
|
|
|
- y: 0,
|
|
|
- x2: 0,
|
|
|
- y2: 1,
|
|
|
- colorStops: [
|
|
|
- {
|
|
|
- offset: 0,
|
|
|
- color: "rgba(58,132,255, 0.8)", // 0% 处的颜色
|
|
|
- },
|
|
|
- {
|
|
|
- offset: 1,
|
|
|
- color: "rgba(58,132,255, 0.1)", // 100% 处的颜色
|
|
|
- },
|
|
|
- ],
|
|
|
- global: false, // 缺省为 false
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- ],
|
|
|
+ };
|
|
|
+ }),
|
|
|
});
|
|
|
},
|
|
|
async getAppListFunc() {
|
|
|
- const { r, li, appVersion, channel, clientList } =
|
|
|
- await this.getAppListOri();
|
|
|
+ const { r, li, appVersion, channel } = await this.getAppListOri();
|
|
|
let source = { length: 0 },
|
|
|
appli = [];
|
|
|
let appV = { length: 0 },
|
|
|
appVLi = [];
|
|
|
let appC = { length: 0 },
|
|
|
appCLi = [];
|
|
|
- let clentV = { length: 0 },
|
|
|
- clentli = [];
|
|
|
let prvList = r.output.data.prvRolectrl || [];
|
|
|
for (let i = 0; i < prvList.length; i++) {
|
|
|
const v = prvList[i];
|
|
@@ -487,22 +469,17 @@ export default {
|
|
|
(appV[v.detid] = true), (appV.length = appV.length + 1);
|
|
|
if (v.controlid == "CHANNEL")
|
|
|
(appC[v.detid] = true), (appC.length = appC.length + 1);
|
|
|
- if (v.controlid == "CLIENT_TYPE")
|
|
|
- (clentV[v.detid] = true), (clentV.length = clentV.length + 1);
|
|
|
}
|
|
|
if (li.status === "0") appli = li.output.data || [];
|
|
|
if (appVersion.length) appVLi = appVersion || [];
|
|
|
if (channel.length) appCLi = channel || [];
|
|
|
- if (clientList.length) clentli = clientList || [];
|
|
|
return {
|
|
|
source,
|
|
|
appV,
|
|
|
appC,
|
|
|
appli,
|
|
|
- clentV,
|
|
|
appVLi,
|
|
|
appCLi,
|
|
|
- clentli,
|
|
|
};
|
|
|
},
|
|
|
async getAppListOri() {
|
|
@@ -529,17 +506,12 @@ export default {
|
|
|
gcode: "APP_VERSION",
|
|
|
source: defaultAppName,
|
|
|
});
|
|
|
- // 端列表
|
|
|
- const clientList = await getSearchData({
|
|
|
- gcode: "CLIENT_TYPE",
|
|
|
- source: defaultAppName,
|
|
|
- });
|
|
|
// 应用渠道列表
|
|
|
const channel = await getSearchData({
|
|
|
gcode: "CHANNEL",
|
|
|
source: defaultAppName,
|
|
|
});
|
|
|
- return { r, li, appVersion, channel, clientList };
|
|
|
+ return { r, li, appVersion, channel };
|
|
|
},
|
|
|
disabledDate(time) {
|
|
|
const first = new Date("2021-06-21 00:00:00");
|
|
@@ -612,6 +584,29 @@ export default {
|
|
|
version: [-1],
|
|
|
};
|
|
|
});
|
|
|
+ getSearchData({
|
|
|
+ gcode: "CHANNEL",
|
|
|
+ source: this.form.app,
|
|
|
+ }).then(r => {
|
|
|
+ let channel = [
|
|
|
+ {
|
|
|
+ label: "不限",
|
|
|
+ value: -1,
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ r.map(v => {
|
|
|
+ if ((appV.length && appV[v.mcode]) || appV.length === 0)
|
|
|
+ channel.push({
|
|
|
+ value: v.mname,
|
|
|
+ label: v.mname,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ this.channel = channel;
|
|
|
+ this.form = {
|
|
|
+ ...this.form,
|
|
|
+ channel: [-1],
|
|
|
+ };
|
|
|
+ });
|
|
|
});
|
|
|
},
|
|
|
changeversion(v) {
|
|
@@ -645,42 +640,24 @@ export default {
|
|
|
const E = this.form.date[1]
|
|
|
? this.FormData(this.form.date[1])
|
|
|
: undefined;
|
|
|
- let p = this.lastParams.app
|
|
|
- ? this.lastParams
|
|
|
- : {
|
|
|
- app: this.form.app,
|
|
|
- start: S,
|
|
|
- end: E,
|
|
|
- manufacturer:
|
|
|
- this.form.channel == -1 ? undefined : this.form.channel,
|
|
|
- version: this.form.version == -1 ? undefined : this.form.version,
|
|
|
- };
|
|
|
- getHistory(p).then(r => {
|
|
|
- // 生成数据
|
|
|
- let strcsv =
|
|
|
- "data:text/csv;charset=utf-8,日期,活跃用户,新增用户,累计用户,人均使用时长,次均使用时长\r\n";
|
|
|
- (r.list || []).map(v => {
|
|
|
- strcsv += [
|
|
|
- v.dt,
|
|
|
- v.activeUser,
|
|
|
- v.newUser,
|
|
|
- v.totalUser,
|
|
|
- this.timeFormat(v.durationUser),
|
|
|
- this.timeFormat(v.durationTimes),
|
|
|
- "\r\n",
|
|
|
- ].join(",");
|
|
|
- });
|
|
|
- // 导出
|
|
|
- let link = document.createElement("a");
|
|
|
- link.id = "download-csv";
|
|
|
- link.setAttribute("href", encodeURI(strcsv));
|
|
|
- link.setAttribute(
|
|
|
- "download",
|
|
|
- p.app + "用户趋势" + S + "_" + E + ".csv"
|
|
|
- );
|
|
|
- // document.body.appendChild(link);
|
|
|
- link.click();
|
|
|
- });
|
|
|
+ const app = this.lastParams.app || this.form.app;
|
|
|
+ const version =
|
|
|
+ this.form.version == -1 ? undefined : this.form.version.join(",");
|
|
|
+ const manufacturer =
|
|
|
+ this.lastParams.manufacturer || this.form.channel.join(",");
|
|
|
+ let url =
|
|
|
+ config.base.leverAudience +
|
|
|
+ "/cxzx-program/new-media/content/export?start=" +
|
|
|
+ S +
|
|
|
+ "&end=" +
|
|
|
+ E +
|
|
|
+ "&app=" +
|
|
|
+ app;
|
|
|
+ version && (url += "&version=" + version);
|
|
|
+ manufacturer &&
|
|
|
+ manufacturer !== -1 &&
|
|
|
+ (url += "&manufacturer=" + manufacturer);
|
|
|
+ window.open(url);
|
|
|
},
|
|
|
},
|
|
|
components: {
|
|
@@ -690,26 +667,19 @@ export default {
|
|
|
</script>
|
|
|
|
|
|
<style>
|
|
|
-.RealOnline {
|
|
|
+.Content {
|
|
|
margin: 10px 15px;
|
|
|
}
|
|
|
-.RealOnline .has-seconds .el-time-spinner__wrapper:last-child {
|
|
|
- display: none;
|
|
|
-}
|
|
|
-.head {
|
|
|
- display: flex;
|
|
|
- font-weight: 500;
|
|
|
+.libTitle {
|
|
|
+ color: tomato;
|
|
|
+ font-weight: 700;
|
|
|
+ font-size: 14px;
|
|
|
}
|
|
|
-.head .head-item {
|
|
|
- flex: 1;
|
|
|
- text-align: center;
|
|
|
- font-size: 0.8em;
|
|
|
- border-top: 3px solid #fff;
|
|
|
- padding-top: 10px;
|
|
|
+.btn-next i,
|
|
|
+.btn-prev i {
|
|
|
+ margin: 0 auto;
|
|
|
}
|
|
|
-.head .value {
|
|
|
- margin: 15px 0;
|
|
|
- color: #396fff;
|
|
|
- font-size: 25px;
|
|
|
+.caret-wrapper .ascending {
|
|
|
+ display: none;
|
|
|
}
|
|
|
</style>
|