|
@@ -0,0 +1,561 @@
|
|
|
+<template>
|
|
|
+ <div class="defaultComponent">
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="card">
|
|
|
+ <div class="cardtit">话题列表</div>
|
|
|
+ <div class="huati">
|
|
|
+ <div v-for="o in huati" :key="o" class="text">
|
|
|
+ {{ o.name }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="18">
|
|
|
+ <div class="card">
|
|
|
+ <div class="cardtit">传播数据</div>
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="6" style="padding: 10px;text-align: center">
|
|
|
+ <el-card>
|
|
|
+ <div class="numTitle">{{ numform(shujuTotal.playCount) }}</div>
|
|
|
+ <div class="numValue">总传播量</div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row>
|
|
|
+ <el-col
|
|
|
+ :span="4"
|
|
|
+ style="padding: 10px;text-align: center"
|
|
|
+ v-for="(item, i) in shuju"
|
|
|
+ :key="i"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="numTitle"
|
|
|
+ :style="'color:' + c[item % (c.length - 1)]"
|
|
|
+ >
|
|
|
+ {{ numform(item) }}
|
|
|
+ </div>
|
|
|
+ <div class="numValue" v-text="i"></div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="16">
|
|
|
+ <div class="card">
|
|
|
+ <div class="cardtit">传播量趋势</div>
|
|
|
+ <div ref="trendChartEle"></div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <div class="card">
|
|
|
+ <div class="cardtit">传播平台占比</div>
|
|
|
+ <div ref="platformChartEle"></div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <div class="card">
|
|
|
+ <div class="cardtit">
|
|
|
+ 部门传播量排行
|
|
|
+ <el-button-group style="float:right;margin-right: 5px">
|
|
|
+ <el-button
|
|
|
+ :type="typeName === 'ALL' ? 'primary' : 'default'"
|
|
|
+ size="small"
|
|
|
+ @click="rangClick('ALL')"
|
|
|
+ >
|
|
|
+ 全部
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ :type="typeName === 'MONTH' ? 'primary' : 'default'"
|
|
|
+ size="small"
|
|
|
+ @click="rangClick('MONTH')"
|
|
|
+ >
|
|
|
+ 月
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ :type="typeName === 'WEEK' ? 'primary' : 'default'"
|
|
|
+ size="small"
|
|
|
+ @click="rangClick('WEEK')"
|
|
|
+ >
|
|
|
+ 周
|
|
|
+ </el-button>
|
|
|
+ </el-button-group>
|
|
|
+ </div>
|
|
|
+ <div ref="departmentChartEle"></div>
|
|
|
+ </div>
|
|
|
+ <div class="card">
|
|
|
+ <div class="cardtit">热点报道</div>
|
|
|
+ <div style="padding: 10px">
|
|
|
+ <el-table :data="hotList" style="width: 100%">
|
|
|
+ <el-table-column show-overflow-tooltip prop="host" label="部门">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ show-overflow-tooltip
|
|
|
+ prop="subTopic"
|
|
|
+ label="热点话题"
|
|
|
+ >
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ show-overflow-tooltip
|
|
|
+ prop="playCount"
|
|
|
+ label="传播量"
|
|
|
+ >
|
|
|
+ <template v-slot="scope">
|
|
|
+ {{ numform(scope.row.playCount) }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="card">
|
|
|
+ <div class="cardtit">
|
|
|
+ 发稿任务统计
|
|
|
+ <el-select
|
|
|
+ size="small"
|
|
|
+ v-model="select"
|
|
|
+ @change="changeselect"
|
|
|
+ placeholder="请选择频道"
|
|
|
+ style="width: 10em; float: right; margin-right: 10px"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in selectOption"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.depName"
|
|
|
+ :value="item.depName"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-date-picker
|
|
|
+ v-model="T"
|
|
|
+ type="daterange"
|
|
|
+ @change="change"
|
|
|
+ style="float: right; margin-right: 10px"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ range-separator="-"
|
|
|
+ size="small"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div style="padding: 20px">
|
|
|
+ <el-table :data="userlist" style="width: 100%">
|
|
|
+ <el-table-column show-overflow-tooltip prop="depName" label="部门">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column show-overflow-tooltip prop="name" label="账号">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column show-overflow-tooltip prop="platform" label="平台">
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ show-overflow-tooltip
|
|
|
+ prop="publishTime"
|
|
|
+ label="发稿时间"
|
|
|
+ >
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <el-pagination
|
|
|
+ style="margin-top: 5px"
|
|
|
+ background
|
|
|
+ layout="total, prev, pager, next"
|
|
|
+ :total="total"
|
|
|
+ :current-page="page"
|
|
|
+ @current-change="pagechange"
|
|
|
+ >
|
|
|
+ </el-pagination>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+// @ is an alias to /src
|
|
|
+import {
|
|
|
+ guijiTopic,
|
|
|
+ guijiSpread,
|
|
|
+ guijiTrend,
|
|
|
+ guijiDepartment,
|
|
|
+ guijiHottopic,
|
|
|
+ guijiBumenList,
|
|
|
+ guijiFagao,
|
|
|
+} from "@/api/index";
|
|
|
+
|
|
|
+import * as echarts from "echarts/core";
|
|
|
+import { LineChart } from "echarts/charts";
|
|
|
+import {
|
|
|
+ GridComponent,
|
|
|
+ ToolboxComponent,
|
|
|
+ VisualMapComponent,
|
|
|
+ LegendComponent,
|
|
|
+} from "echarts/components";
|
|
|
+import { LabelLayout, UniversalTransition } from "echarts/features";
|
|
|
+import { CanvasRenderer } from "echarts/renderers";
|
|
|
+echarts.use([
|
|
|
+ GridComponent,
|
|
|
+ LineChart,
|
|
|
+ CanvasRenderer,
|
|
|
+ ToolboxComponent,
|
|
|
+ VisualMapComponent,
|
|
|
+ LabelLayout,
|
|
|
+ UniversalTransition,
|
|
|
+ LegendComponent,
|
|
|
+]);
|
|
|
+let lineH = 0;
|
|
|
+export default {
|
|
|
+ name: "defaultComponent",
|
|
|
+ props: ["item"],
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ pageSize: 10,
|
|
|
+ page: 1,
|
|
|
+ total: 0,
|
|
|
+ typeName: "ALL",
|
|
|
+ huati: [],
|
|
|
+ shuju: {},
|
|
|
+ hotList: [],
|
|
|
+ selectOption: [],
|
|
|
+ userlist: [],
|
|
|
+ chart1: undefined,
|
|
|
+ chart2: undefined,
|
|
|
+ chart3: undefined,
|
|
|
+ T: [],
|
|
|
+ select: "",
|
|
|
+ shujuTotal: {
|
|
|
+ playCount: 0,
|
|
|
+ },
|
|
|
+ c: ["#FB6161", "#EC72DC", "#F98E53", "#49BED0", "#4BCA8B"],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ filters: {},
|
|
|
+ mounted() {
|
|
|
+ this.page = 1;
|
|
|
+ this.pageSize = 10;
|
|
|
+ let D = new Date(),
|
|
|
+ Year = D.getFullYear(),
|
|
|
+ Month = D.getMonth() + 1,
|
|
|
+ Day = D.getDate();
|
|
|
+ let oD = new Date(Date.now() - 86400000 * 30),
|
|
|
+ oYear = oD.getFullYear(),
|
|
|
+ oMonth = oD.getMonth() + 1,
|
|
|
+ oDay = oD.getDate();
|
|
|
+ Month > 9 ? "" : Month = '0' + Month;
|
|
|
+ Day > 9 ? "" : Day = '0' + Day;
|
|
|
+ oMonth > 9 ? "" : oMonth = '0' + oMonth;
|
|
|
+ oDay > 9 ? "" : oDay = '0' + oDay;
|
|
|
+ this.T = [
|
|
|
+ [oYear, oMonth, oDay].join("-"),
|
|
|
+ [Year, Month, Day].join("-"),
|
|
|
+ ];
|
|
|
+ console.log(this.T);
|
|
|
+
|
|
|
+ Promise.all([
|
|
|
+ guijiTopic({
|
|
|
+ activityId: this.item.activityId,
|
|
|
+ }),
|
|
|
+ guijiSpread({
|
|
|
+ topic: this.item.realName,
|
|
|
+ }),
|
|
|
+ guijiTrend({
|
|
|
+ topic: this.item.realName,
|
|
|
+ }),
|
|
|
+ guijiDepartment({
|
|
|
+ depRange: this.typeName,
|
|
|
+ title: this.item.realName,
|
|
|
+ }),
|
|
|
+ guijiHottopic({
|
|
|
+ topic: this.item.realName,
|
|
|
+ }),
|
|
|
+ guijiBumenList(),
|
|
|
+ ]).then(li => {
|
|
|
+ this.huati = li[0] || [];
|
|
|
+ this.shujuTotal = li[1][0] || {};
|
|
|
+ let shuju = {};
|
|
|
+ for (let i = 1; i < (li[1] || []).length; i++) {
|
|
|
+ const v = (li[1] || [])[i] || {};
|
|
|
+ if (!shuju[v.platform]) {
|
|
|
+ shuju[v.platform] = v.playCount || 0;
|
|
|
+ } else {
|
|
|
+ shuju[v.platform] += v.playCount || 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.shuju = shuju;
|
|
|
+ this.hotList = li[4] || [];
|
|
|
+ this.selectOption = li[5] || [];
|
|
|
+ this.selectOption = [{ depName: "全部", id: 0 }, ...this.selectOption];
|
|
|
+ this.select = this.selectOption[0].depName;
|
|
|
+ this.trendChart(li[2] || []);
|
|
|
+ this.platformChar(shuju || {});
|
|
|
+ this.departmentChar(li[3] || []);
|
|
|
+ this.getRult();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ computed: {},
|
|
|
+ methods: {
|
|
|
+ numform(text) {
|
|
|
+ let num = text;
|
|
|
+ if (isNaN(text)) num = "0";
|
|
|
+ if (text >= 100000000) num = (text / 100000000).toFixed(2) - 0 + "亿";
|
|
|
+ else if (text >= 10000) num = (text / 10000).toFixed(2) - 0 + "万";
|
|
|
+ else num = num + "";
|
|
|
+ return num;
|
|
|
+ },
|
|
|
+ rangClick(type) {
|
|
|
+ guijiDepartment({
|
|
|
+ depRange: type,
|
|
|
+ title: this.item.realName,
|
|
|
+ }).then(res => {
|
|
|
+ this.typeName = type;
|
|
|
+ this.departmentChar(res || []);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ trendChart(li) {
|
|
|
+ this.chart1 = echarts.init(this.$refs.trendChartEle);
|
|
|
+ lineH = (this.$refs.trendChartEle.offsetWidth * 9) / 16;
|
|
|
+ this.chart1.resize({
|
|
|
+ height: (this.$refs.trendChartEle.offsetWidth * 9) / 16,
|
|
|
+ });
|
|
|
+ const keys = [],
|
|
|
+ val = [];
|
|
|
+ (li || []).map(v => {
|
|
|
+ keys.push(v.dt);
|
|
|
+ val.push(v.playCount);
|
|
|
+ });
|
|
|
+ this.chart1.setOption({
|
|
|
+ tooltip: {
|
|
|
+ trigger: "item",
|
|
|
+ formatter: v => {
|
|
|
+ return v.name + ":" + this.numform(v.data);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: "category",
|
|
|
+ data: keys,
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: "value",
|
|
|
+ axisLabel: {
|
|
|
+ formatter: v => {
|
|
|
+ return this.numform(v);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ data: val,
|
|
|
+ type: "line",
|
|
|
+ smooth: true,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+ },
|
|
|
+ platformChar(obj) {
|
|
|
+ this.chart2 = echarts.init(this.$refs.platformChartEle);
|
|
|
+ let w = this.$refs.platformChartEle.offsetWidth || 0;
|
|
|
+ this.chart2.resize({
|
|
|
+ height: lineH,
|
|
|
+ });
|
|
|
+ const val = [];
|
|
|
+ Object.keys(obj).map(v => {
|
|
|
+ val.push({
|
|
|
+ name: v,
|
|
|
+ value: obj[v],
|
|
|
+ });
|
|
|
+ });
|
|
|
+ this.chart2.setOption({
|
|
|
+ tooltip: {
|
|
|
+ trigger: "item",
|
|
|
+ formatter: v => {
|
|
|
+ return v.name + ":" + this.numform(v.value);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: "pie",
|
|
|
+ radius: [20, 60],
|
|
|
+ left: "center",
|
|
|
+ width: 400,
|
|
|
+ itemStyle: {
|
|
|
+ borderColor: "#fff",
|
|
|
+ borderWidth: 1,
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ alignTo: "edge",
|
|
|
+ formatter: "{name|{b}}\n{time|{d} %}",
|
|
|
+ minMargin: 5,
|
|
|
+ edgeDistance: 10,
|
|
|
+ lineHeight: 15,
|
|
|
+ rich: {
|
|
|
+ time: {
|
|
|
+ fontSize: 10,
|
|
|
+ color: "#999",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ length: 15,
|
|
|
+ length2: 0,
|
|
|
+ maxSurfaceAngle: 80,
|
|
|
+ },
|
|
|
+ labelLayout: function(params) {
|
|
|
+ const isLeft = params.labelRect.x < w / 2;
|
|
|
+ const points = params.labelLinePoints;
|
|
|
+ // Update the end point.
|
|
|
+ points[2][0] = isLeft
|
|
|
+ ? params.labelRect.x
|
|
|
+ : params.labelRect.x + params.labelRect.width;
|
|
|
+ return {
|
|
|
+ labelLinePoints: points,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ data: val,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+ },
|
|
|
+ departmentChar(li) {
|
|
|
+ if (!this.chart3) {
|
|
|
+ this.chart3 = echarts.init(this.$refs.departmentChartEle);
|
|
|
+ this.chart3.resize({
|
|
|
+ height: (this.$refs.departmentChartEle.offsetWidth * 9) / 16,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ const val = [],
|
|
|
+ key = [];
|
|
|
+ let l = li.sort((a, b) => {
|
|
|
+ return a.readCount - b.readCount;
|
|
|
+ });
|
|
|
+
|
|
|
+ l.map(v => {
|
|
|
+ key.push(v.depName);
|
|
|
+ val.push(v.readCount);
|
|
|
+ });
|
|
|
+ this.chart3.setOption({
|
|
|
+ tooltip: {
|
|
|
+ trigger: "item",
|
|
|
+ formatter: v => {
|
|
|
+ return v.name + ":" + this.numform(v.value);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: "value",
|
|
|
+ axisLabel: {
|
|
|
+ formatter: v => {
|
|
|
+ return this.numform(v);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ data: key,
|
|
|
+ type: "category",
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: "bar",
|
|
|
+ itemStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
|
+ { offset: 0, color: "#6fccd0" },
|
|
|
+ { offset: 0.3, color: "#48b1e5" },
|
|
|
+ { offset: 1, color: "#1890ff" },
|
|
|
+ ]),
|
|
|
+ },
|
|
|
+ data: val,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+ },
|
|
|
+ pagechange(p) {
|
|
|
+ this.page = p || 1;
|
|
|
+ this.getRult();
|
|
|
+ },
|
|
|
+ getRult() {
|
|
|
+ let p = {
|
|
|
+ page: this.page,
|
|
|
+ pageSize: this.pageSize,
|
|
|
+ endTime: this.T[1],
|
|
|
+ startTime: this.T[0],
|
|
|
+ title: this.item.realName,
|
|
|
+ };
|
|
|
+ this.select && this.select !== "全部" && (p.depName = this.select);
|
|
|
+ guijiFagao(p).then(res => {
|
|
|
+ const { total, data } = res;
|
|
|
+ this.userlist = data || [];
|
|
|
+ this.total = total;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ changeselect() {
|
|
|
+ this.getRult();
|
|
|
+ },
|
|
|
+ change(v) {
|
|
|
+ this.T = v;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ beforeUnmount: function() {},
|
|
|
+ components: {},
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+.defaultComponent {
|
|
|
+ padding-top: 5px;
|
|
|
+ min-width: 1100px;
|
|
|
+}
|
|
|
+.defaultComponent .card {
|
|
|
+ border-radius: 5px;
|
|
|
+ background: #fff;
|
|
|
+ padding: 8px 0 11px 0;
|
|
|
+ margin: 0 5px 5px 5px;
|
|
|
+ box-shadow: 0 0 5px #eee;
|
|
|
+}
|
|
|
+.defaultComponent .cardtit {
|
|
|
+ border-left: 3px solid #1a89b3;
|
|
|
+ padding-left: 5px;
|
|
|
+ height: 25px;
|
|
|
+ line-height: 25px;
|
|
|
+}
|
|
|
+.defaultComponent .huati {
|
|
|
+ height: 12em;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+.defaultComponent .text {
|
|
|
+ color: #666;
|
|
|
+ cursor: pointer;
|
|
|
+ border-radius: 10px;
|
|
|
+ padding: 10px 24px;
|
|
|
+ font-size: 14px;
|
|
|
+ padding-right: 20px;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ overflow: hidden;
|
|
|
+ word-break: break-all;
|
|
|
+}
|
|
|
+.defaultComponent .numTitle {
|
|
|
+ font-size: 24px;
|
|
|
+ height: 1em;
|
|
|
+ line-height: 1em;
|
|
|
+ color: #1a89b3;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+.defaultComponent .numValue {
|
|
|
+ margin-top: 8px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #919191;
|
|
|
+}
|
|
|
+.defaultComponent .el-table {
|
|
|
+ color: #3b3b3b;
|
|
|
+}
|
|
|
+.defaultComponent .el-table__header-wrapper {
|
|
|
+ border-radius: 5px;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+.defaultComponent .has-gutter th {
|
|
|
+ background: #eceff5;
|
|
|
+ color: #3b3b3b;
|
|
|
+}
|
|
|
+</style>
|