浏览代码

合并V1.1.5

朱鑫波 4 年之前
父节点
当前提交
48a2dfb8d9

+ 93 - 58
src/components/ChartCard.vue

@@ -7,7 +7,12 @@
           <slot name="action"></slot>
         </span>
       </div>
-      <div class="total"><span>{{ total }}</span></div>
+      <div class="total" style="display: flex; justify-content: space-between">
+        <span>{{ total }}</span>
+        <span>
+          <slot name="percentage"></slot>
+        </span>
+      </div>
     </div>
     <div class="chart-card-content">
       <div class="content-fix">
@@ -23,79 +28,93 @@
 </template>
 
 <script>
-  export default {
-    name: "ChartCard",
-    props: {
-      title: {
-        type: String,
-        default: ''
-      },
-      total: {
-        type: String,
-        default: ''
-      },
-      loading: {
-        type: Boolean,
-        default: false
-      }
-    }
-  }
+export default {
+  name: 'ChartCard',
+  props: {
+    title: {
+      type: String,
+      default: '',
+    },
+    total: {
+      type: String,
+      default: '',
+    },
+    loading: {
+      type: Boolean,
+      default: false,
+    },
+  },
+}
 </script>
 
 <style lang="scss" scoped>
-  .chart-card-header {
+.chart-card-header {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+
+  .meta {
     position: relative;
     overflow: hidden;
     width: 100%;
-
-    .meta {
-      position: relative;
-      overflow: hidden;
-      width: 100%;
-      color: rgba(0, 0, 0, .45);
-      font-size: 14px;
-      line-height: 22px;
-    }
+    color: rgba(0, 0, 0, 0.45);
+    font-size: 14px;
+    line-height: 22px;
   }
+}
 
-  .chart-card-action {
-    cursor: pointer;
-    position: absolute;
-    top: 0;
-    right: 0;
-  }
+.chart-card-action {
+  cursor: pointer;
+  position: absolute;
+  top: 0;
+  right: 0;
+}
 
-  .chart-card-footer {
-    border-top: 1px solid #e8e8e8;
-    padding-top: 9px;
-    margin-top: 8px;
+.chart-card-footer {
+  border-top: 1px solid #e8e8e8;
+  padding-top: 9px;
+  margin-top: 8px;
 
-    > * {
-      position: relative;
-    }
+  > * {
+    position: relative;
+  }
 
-    .field {
-      white-space: nowrap;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      margin: 0;
-    }
+  .field {
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    margin: 0;
   }
+}
 
-  .chart-card-content {
-    margin-bottom: 12px;
-    position: relative;
-    height: 46px;
-    width: 100%;
+.chart-card-content {
+  margin-bottom: 12px;
+  position: relative;
+  height: 46px;
+  width: 100%;
 
-    .content-fix {
-      position: absolute;
-      left: 0;
-      bottom: 0;
-      width: 100%;
-    }
+  .content-fix {
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    width: 100%;
   }
+}
+
+.total {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  word-break: break-all;
+  white-space: nowrap;
+  color: #000;
+  margin-top: 4px;
+  margin-bottom: 0;
+  font-size: 30px;
+  line-height: 38px;
+  height: 38px;
+}
 
+@media (min-width: 1600px) {
   .total {
     overflow: hidden;
     text-overflow: ellipsis;
@@ -108,4 +127,20 @@
     line-height: 38px;
     height: 38px;
   }
+}
+
+@media (max-width: 1599px) {
+  .total {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    word-break: break-all;
+    white-space: nowrap;
+    color: #000;
+    margin-top: 4px;
+    margin-bottom: 0;
+    font-size: 18px;
+    line-height: 38px;
+    height: 38px;
+  }
+}
 </style>

+ 39 - 3
src/filters.js

@@ -76,6 +76,42 @@ const filters = {
         s = s < 10 ? '0' + s : s
         return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s
     },
+    //时间秒转化为时间格式
+    formatS: function (s) {
+        var sTime = parseInt(s);// 秒
+        var mTime = 0;// 分
+        var hTime = 0;// 时
+        if (sTime > 60) {//如果秒数大于60,将秒数转换成整数
+            //获取分钟,除以60取整数,得到整数分钟
+            mTime = parseInt(sTime / 60);
+            //获取秒数,秒数取佘,得到整数秒数
+            sTime = parseInt(sTime % 60);
+            //如果分钟大于60,将分钟转换成小时
+            if (mTime > 60) {
+                //获取小时,获取分钟除以60,得到整数小时
+                hTime = parseInt(mTime / 60);
+                //获取小时后取佘的分,获取分钟除以60取佘的分
+                mTime = parseInt(mTime % 60);
+            }
+        }
+        var result = '';
+        if (sTime >= 0 && sTime < 10) {
+            result = "0" + parseInt(sTime) + "";
+        } else {
+            result = "" + parseInt(sTime) + "";
+        }
+        if (mTime >= 0 && mTime < 10) {
+            result = "0" + parseInt(mTime) + ":" + result;
+        } else {
+            result = "" + parseInt(mTime) + ":" + result;
+        }
+        if (hTime >= 0 && hTime < 10) {
+            result = "0" + parseInt(hTime) + ":" + result;
+        } else {
+            result = "" + parseInt(hTime) + ":" + result;
+        }
+        return result;
+    },
     //bidType类型
     bidType(sta) {
         var data = {
@@ -107,9 +143,9 @@ const filters = {
             324: '唤起应用',
             715: '微信复制优化目标',
             716: '多转化事件',
-            396:'注册优化目标',
-            731:'广告观看5次',
-            732:'广告观看10次',
+            396: '注册优化目标',
+            731: '广告观看5次',
+            732: '广告观看10次',
         }
         return data[sta]
     },

二进制
src/views/modules/Statistics/materialReport/image/1.png


二进制
src/views/modules/Statistics/materialReport/image/2.png


二进制
src/views/modules/Statistics/materialReport/image/3.png


二进制
src/views/modules/Statistics/materialReport/image/4.png


二进制
src/views/modules/Statistics/materialReport/image/5.png


+ 801 - 0
src/views/modules/Statistics/materialReport/marterialDetail.vue

@@ -0,0 +1,801 @@
+<style lang="scss" scoped>
+#office-iframe {
+  height: 800px;
+}
+</style>
+<style>
+.info-detail .ant-descriptions-item-content {
+  font-weight: bold;
+}
+.info-detail .ant-descriptions-item-label {
+  color: darkgray;
+  min-width: 80px;
+}
+.info-detail table tr td {
+  border: 0;
+}
+.show-data p {
+  color: black;
+  font-weight: 600;
+}
+.show-data p span {
+  display: inline-block;
+  width: 85px;
+  color: slategrey;
+  font-weight: 500;
+}
+</style>
+<template>
+  <a-row :gutter="10">
+    <a-spin :spinning="spinning">
+      <a-col :sm="6" style="margin-bottom: 20px; z-index: 10">
+        <a-card
+          style="min-height: 100px"
+          :style="{
+            width: (clientWidth / 24) * 6 - 10 + 'px',
+          }"
+        >
+          <video class="video" :src="materialInfo.url" controls="controls" style="width: 100%" v-if="materialInfo">
+            您的浏览器不支持 video 标签。
+          </video>
+          <img :src="noImg" alt="" v-else style="width: 100%" />
+        </a-card>
+      </a-col>
+      <a-col :sm="18" style="margin-bottom: 20px; z-index: 10">
+        <a-card class="info-detail" style="min-height: 300px">
+          <a-descriptions title="视频信息" v-if="materialInfo">
+            <a-descriptions-item label="素材标题" :span="3">
+              {{ materialInfo.materialName ? materialInfo.materialName : '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="素材ID">
+              {{ materialInfo.materialId ? materialInfo.materialId : '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="上线时间">
+              {{ materialInfo.createTime ? materialInfo.createTime.split(' ')[0] : '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="素材类型">
+              {{
+                materialInfo.materialType ? (materialInfo.materialType == '' ? '无' : materialInfo.materialType) : '-'
+              }}
+            </a-descriptions-item>
+            <a-descriptions-item label="视频时长">
+              <span v-if="materialInfo.second">
+                {{ materialInfo.second | formatS }}
+              </span>
+              <span v-else>-</span>
+            </a-descriptions-item>
+            <a-descriptions-item label="视频大小">
+              {{ materialInfo.size ? materialInfo.size : '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="视频尺寸">
+              {{ materialInfo.width ? materialInfo.width + '*' + materialInfo.height : '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="投放媒体">
+              {{ materialInfo.madia || '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="素材渠道">
+              {{ materialInfo.channelType || '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="供应商">
+              {{ materialInfo.supplier || '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="关联项目">
+              {{ materialInfo.projectName || '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="唯一编码" :span="2">
+              {{ materialInfo.code || '-' }}
+            </a-descriptions-item>
+
+            <a-descriptions-item label="设计组长" :span="3" style="margin-top: 10px">
+              {{ materialInfo.leaderName || '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="编导">
+              {{ materialInfo.planName ? (materialInfo.planName == '' ? '无' : materialInfo.planName) : '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="拍摄">
+              {{ materialInfo.shotName ? (materialInfo.shotName == '' ? '无' : materialInfo.shotName) : '-' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="剪辑">
+              {{ materialInfo.clipName ? (materialInfo.clipName == '' ? '无' : materialInfo.clipName) : '-' }}
+            </a-descriptions-item>
+          </a-descriptions>
+        </a-card>
+        <a-card style="min-height: 300px; margin: 10px 0" v-if="dataView && mediaId == 2">
+          <div
+            style="
+              margin-bottom: 20px;
+              color: rgba(0, 0, 0, 0.85);
+              font-weight: bold;
+              font-size: 16px;
+              line-height: 1.5;
+            "
+          >
+            数据概览
+          </div>
+          <a-row :gutter="15">
+            <a-col :xl="6" class="show-data">
+              <h3>素材消耗</h3>
+              <p
+                :style="{ color: dataView.charge[0].charge >= dataView.charge[2].charge ? '#F66C6D' : '#67C239' }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.charge[0].charge | decimalsHandle }}
+              </p>
+              <p><span>项目top</span>{{ dataView.charge[1].charge | decimalsHandle }}</p>
+              <p><span>素材库均值</span>{{ dataView.charge[2].charge | decimalsHandle }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>封面曝光数</h3>
+              <p
+                :style="{
+                  color: dataView.photoShow[0].photoShow >= dataView.photoShow[2].photoShow ? '#F66C6D' : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.photoShow[0].photoShow }}
+              </p>
+              <p><span>项目top</span>{{ dataView.photoShow[1].photoShow }}</p>
+              <p><span>素材库均值</span>{{ dataView.photoShow[2].photoShow }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>封面点击数</h3>
+              <p
+                :style="{
+                  color: dataView.photoClick[0].photoClick >= dataView.photoClick[2].photoClick ? '#F66C6D' : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.photoClick[0].photoClick }}
+              </p>
+              <p><span>项目top</span>{{ dataView.photoClick[1].photoClick }}</p>
+              <p><span>素材库均值</span>{{ dataView.photoClick[2].photoClick }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>素材曝光数</h3>
+              <p
+                :style="{ color: dataView.aclick[0].aclick >= dataView.aclick[2].aclick ? '#F66C6D' : '#67C239' }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.aclick[0].aclick }}
+              </p>
+              <p><span>项目top</span>{{ dataView.aclick[1].aclick }}</p>
+              <p><span>素材库均值</span>{{ dataView.aclick[2].aclick }}</p>
+            </a-col>
+          </a-row>
+          <a-row :gutter="15" style="margin-top: 20px">
+            <a-col :xl="6" class="show-data">
+              <h3>行为数</h3>
+              <p
+                :style="{ color: dataView.bclick[0].bclick >= dataView.bclick[2].bclick ? '#F66C6D' : '#67C239' }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.bclick[0].bclick }}
+              </p>
+              <p><span>项目top</span>{{ dataView.bclick[1].bclick }}</p>
+              <p><span>素材库均值</span>{{ dataView.bclick[2].bclick }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>激活数</h3>
+              <p
+                :style="{
+                  color: dataView.activation[0].activation >= dataView.activation[2].activation ? '#F66C6D' : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.activation[0].activation }}
+              </p>
+              <p><span>项目top</span>{{ dataView.activation[1].activation }}</p>
+              <p><span>素材库均值</span>{{ dataView.activation[2].activation }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>3s播放率</h3>
+              <p
+                :style="{
+                  color: dataView.play3sRate[0].play3sRate >= dataView.play3sRate[2].play3sRate ? '#F66C6D' : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ (dataView.play3sRate[0].play3sRate * 100).toFixed(2) + '%' }}
+              </p>
+              <p><span>项目top</span>{{ (dataView.play3sRate[1].play3sRate * 100).toFixed(2) + '%' }}</p>
+              <p><span>素材库均值</span>{{ (dataView.play3sRate[2].play3sRate * 100).toFixed(2) + '%' }}</p>
+            </a-col>
+          </a-row>
+        </a-card>
+        <a-card style="min-height: 300px; margin: 10px 0" v-if="dataView && mediaId == 1">
+          <div
+            style="
+              margin-bottom: 20px;
+              color: rgba(0, 0, 0, 0.85);
+              font-weight: bold;
+              font-size: 16px;
+              line-height: 1.5;
+            "
+          >
+            数据概览
+          </div>
+          <a-row :gutter="15">
+            <a-col :xl="6" class="show-data">
+              <h3>素材消耗</h3>
+              <p
+                :style="{ color: dataView.cost[0].cost >= dataView.cost[2].cost ? '#F66C6D' : '#67C239' }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.cost[0].cost | decimalsHandle }}
+              </p>
+              <p><span>项目top</span>{{ dataView.cost[1].cost | decimalsHandle }}</p>
+              <p><span>素材库均值</span>{{ dataView.cost[2].cost | decimalsHandle }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>点击数</h3>
+              <p
+                :style="{
+                  color: dataView.click[0].click >= dataView.click[2].click ? '#F66C6D' : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.click[0].click }}
+              </p>
+              <p><span>项目top</span>{{ dataView.click[1].click }}</p>
+              <p><span>素材库均值</span>{{ dataView.click[2].click }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>曝光数</h3>
+              <p
+                :style="{
+                  color:
+                    dataView.materialShow[0].materialShow >= dataView.materialShow[2].materialShow
+                      ? '#F66C6D'
+                      : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.materialShow[0].materialShow }}
+              </p>
+              <p><span>项目top</span>{{ dataView.materialShow[1].materialShow }}</p>
+              <p><span>素材库均值</span>{{ dataView.materialShow[2].materialShow }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>完播率</h3>
+              <p
+                :style="{
+                  color:
+                    dataView.play100Rate[0].play100Rate >= dataView.play100Rate[2].play100Rate ? '#F66C6D' : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ (dataView.play100Rate[0].play100Rate * 100).toFixed(2) + '%' }}
+              </p>
+              <p><span>项目top</span>{{ (dataView.play100Rate[1].play100Rate * 100).toFixed(2) + '%' }}</p>
+              <p><span>素材库均值</span>{{ (dataView.play100Rate[2].play100Rate * 100).toFixed(2) + '%' }}</p>
+            </a-col>
+          </a-row>
+          <a-row :gutter="15" style="margin-top: 20px">
+            <a-col :xl="6" class="show-data">
+              <h3>点赞数</h3>
+              <p
+                :style="{
+                  color:
+                    dataView.likeMaterial[0].likeMaterial >= dataView.likeMaterial[2].likeMaterial
+                      ? '#F66C6D'
+                      : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.likeMaterial[0].likeMaterial }}
+              </p>
+              <p><span>项目top</span>{{ dataView.likeMaterial[1].likeMaterial }}</p>
+              <p><span>素材库均值</span>{{ dataView.likeMaterial[2].likeMaterial }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>评论数</h3>
+              <p
+                :style="{
+                  color:
+                    dataView.commentMaterial[0].commentMaterial >= dataView.commentMaterial[2].commentMaterial
+                      ? '#F66C6D'
+                      : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.commentMaterial[0].commentMaterial }}
+              </p>
+              <p><span>项目top</span>{{ dataView.commentMaterial[1].commentMaterial }}</p>
+              <p><span>素材库均值</span>{{ dataView.commentMaterial[2].commentMaterial }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>转发数</h3>
+              <p
+                :style="{
+                  color:
+                    dataView.shareMaterial[0].shareMaterial >= dataView.shareMaterial[2].shareMaterial
+                      ? '#F66C6D'
+                      : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.shareMaterial[0].shareMaterial }}
+              </p>
+              <p><span>项目top</span>{{ dataView.shareMaterial[1].shareMaterial }}</p>
+              <p><span>素材库均值</span>{{ dataView.shareMaterial[2].shareMaterial }}</p>
+            </a-col>
+            <a-col :xl="6" class="show-data">
+              <h3>关注数</h3>
+              <p
+                :style="{
+                  color: dataView.follow[0].follow >= dataView.follow[2].follow ? '#F66C6D' : '#67C239',
+                }"
+                style="font-size: 18px; font-weight: 700"
+              >
+                {{ dataView.follow[0].follow }}
+              </p>
+              <p><span>项目top</span>{{ dataView.follow[1].follow }}</p>
+              <p><span>素材库均值</span>{{ dataView.follow[2].follow }}</p>
+            </a-col>
+          </a-row>
+        </a-card>
+        <a-card style="min-height: 300px">
+          <div
+            style="
+              margin-bottom: 20px;
+              color: rgba(0, 0, 0, 0.85);
+              font-weight: bold;
+              font-size: 16px;
+              line-height: 1.5;
+            "
+          >
+            数据消耗趋势
+          </div>
+          <div
+            id="echartCircular"
+            ref="echartCircular"
+            style="height: 350px"
+            :style="{ width: (clientWidth / 24) * 18 - 48 - 24 + 'px' }"
+          ></div
+        ></a-card>
+        <!-- <a-card class="search-box" style="min-height: 300px; margin: 20px 0"> </a-card> -->
+      </a-col>
+    </a-spin>
+  </a-row>
+</template>
+
+<script>
+import { getAction, postAction } from '@/api/manage'
+import moment from 'moment'
+import $ from 'jquery'
+import qs from 'qs'
+import UploadToAli from '@femessage/upload-to-ali'
+import uploadFile from '@/components/uploadFile.vue'
+import { mapActions, mapGetters, mapState } from 'vuex'
+var echarts = require('echarts')
+export default {
+  name: 'online-training-list',
+  data() {
+    return {
+      noImg: require('@/assets/noImg.png'),
+      materialInfo: null,
+      dataView: null,
+      clientWidth: 1920,
+      spinning: false,
+      scrollTopAll: 0,
+      scrollTop: 124,
+      mediaId: 0,
+    }
+  },
+  components: {
+    UploadToAli,
+    uploadFile,
+  },
+  watch: {
+    $route: function (n, o) {
+      if (n.query.md5 != o.query.md5 || n.path != o.path) {
+        this.getMaterialInfo()
+      }
+    },
+  },
+  methods: {
+    handlerEchartOption(data) {
+      var option = {
+        noDataLoadingOption: {
+          text: '暂无数据',
+          effect: 'bubble',
+          effectOption: {
+            effect: {
+              n: 0,
+            },
+          },
+        },
+        // title: {
+        //     text: '折线图堆叠'
+        // },
+        tooltip: {
+          trigger: 'axis',
+        },
+        // legend: {
+        //     data: ['邮件营销', '联盟广告', ]
+        // },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true,
+        },
+        legend: {
+          icon: 'circle',
+          top: '5%',
+          right: '5%',
+          itemWidth: 6,
+          itemGap: 20,
+          textStyle: {
+            color: '#556677',
+          },
+        },
+        toolbox: {
+          // feature: {
+          //     saveAsImage: {}
+          // }
+        },
+        xAxis: {
+          type: 'category',
+          data: data.map((item) => {
+            return item.statDate
+          }),
+          boundaryGap: false,
+          // 坐标轴线
+          axisLine: {
+            show: false,
+            lineStyle: {
+              color: '#999',
+            },
+          },
+          // 分割线
+          splitLine: {
+            show: true,
+            lineStyle: {
+              type: 'dashed',
+              color: '#e5e5e5',
+            },
+          },
+        },
+        yAxis: {
+          type: 'value',
+          axisLine: {
+            show: false,
+            lineStyle: {
+              color: '#999',
+            },
+          },
+          splitLine: {
+            lineStyle: {
+              type: 'dashed',
+              color: '#e5e5e5',
+            },
+          },
+        },
+        series: [
+          {
+            smooth: true,
+            name: '消耗',
+            type: 'line',
+            stack: '总量',
+            data: data.map((item) => {
+              return item.cost.toFixed(3)
+            }),
+            symbol: 'circle',
+            symbolSize: 6,
+            lineStyle: {
+              normal: {
+                width: 2,
+                // color: '#0bcd74'
+              },
+            },
+            itemStyle: {
+              borderColor: '#ffffff',
+              borderWidth: 0,
+            },
+          },
+        ],
+      }
+
+      return option
+    },
+    initEchart(idName, optionName) {
+      var that = this
+      const chart = this.$refs[idName]
+      //   console.log(chart)
+      if (chart) {
+        const myChart = echarts.init(document.getElementById(idName))
+        // myChart.showLoading({
+        //     text: "图表数据正在努力加载..."
+        // });
+
+        myChart.setOption(optionName)
+        window.addEventListener('resize', function () {
+          that.clientWidth = document.documentElement.clientWidth - 224
+          myChart.resize()
+        })
+      }
+    },
+    getKuaishou() {
+      var data = JSON.parse(localStorage.getItem('videoInfo'))
+      var params = {
+        mediaId: data.mediaId,
+        md5: data.md5,
+      }
+      var that = this
+      var getProjectIdByMd5 = new Promise(function (resolve, reject) {
+        that.postDataAction('/overView/getProjectIdByMd5', params).then((res) => {
+          if (res.success) {
+            var materialDetailCharge = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailCharge', { md5: data.md5, projectId: res.result })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailPhotoShow = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailPhotoShow', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailPhotoClick = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailPhotoClick', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailAClick = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailAClick', { md5: data.md5, projectId: res.result })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailBClick = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailBClick', { md5: data.md5, projectId: res.result })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailActivation = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailActivation', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailPlay3sRate = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailPlay3sRate', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            Promise.all([
+              materialDetailPlay3sRate,
+              materialDetailCharge,
+              materialDetailPhotoShow,
+              materialDetailPhotoClick,
+              materialDetailAClick,
+              materialDetailBClick,
+              materialDetailActivation,
+            ]).then((item) => {
+              // dataView
+              that.spinning = false
+              that.dataView = {}
+              for (let i = 0; i < item.length; i++) {
+                for (const key in item[i]) {
+                  that.dataView[key] = item[i][key]
+                }
+              }
+            })
+          }
+        })
+      })
+    },
+    getToutiao() {
+      var data = JSON.parse(localStorage.getItem('videoInfo'))
+      var params = {
+        mediaId: data.mediaId,
+        md5: data.md5,
+      }
+      var that = this
+      var getProjectIdByMd5 = new Promise(function (resolve, reject) {
+        that.postDataAction('/overView/getProjectIdByMd5', params).then((res) => {
+          if (res.success) {
+            var materialDetailMaterialShow = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailMaterialShow', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailCost = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailCost', { md5: data.md5, projectId: res.result })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailClick = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailClick', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailPlay100Rate = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailPlay100Rate', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailLikeMaterial = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailLikeMaterial', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailCommentMaterial = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailCommentMaterial', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailShareMaterial = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailShareMaterial', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            var materialDetailFollow = new Promise(function (resolve, reject) {
+              that
+                .postDataAction('/overView/materialDetailFollow', {
+                  md5: data.md5,
+                  projectId: res.result,
+                })
+                .then((res) => {
+                  if (res.success) {
+                    resolve(res.result)
+                  }
+                })
+            })
+            Promise.all([
+              materialDetailCost,
+              materialDetailClick,
+              materialDetailMaterialShow,
+              materialDetailPlay100Rate,
+              materialDetailLikeMaterial,
+              materialDetailCommentMaterial,
+              materialDetailShareMaterial,
+              materialDetailFollow,
+            ]).then((item) => {
+              // dataView
+              console.log(item)
+              that.spinning = false
+              that.dataView = {}
+              for (let i = 0; i < item.length; i++) {
+                for (const key in item[i]) {
+                  that.dataView[key] = item[i][key]
+                }
+              }
+            })
+          }
+        })
+      })
+    },
+    getMaterialInfo() {
+      var data = JSON.parse(localStorage.getItem('videoInfo'))
+      this.spinning = true
+      var params = {
+        mediaId: data.mediaId,
+        md5: data.md5,
+      }
+      this.postDataAction('/overView/materialDetailInfo', params).then((res) => {
+        if (res.success) {
+          if (res.result) {
+            this.materialInfo = res.result
+          } else {
+            // this.$error({
+            //   title: '页面数据加载出错',
+            //   content: '该视频未上传公司素材库,请重新上传之后,可展示视频信息',
+            // })
+          }
+        }
+      })
+      if (data.mediaId == 1) {
+        this.getToutiao()
+      } else if (data.mediaId == 2) {
+        this.getKuaishou()
+      }
+
+      this.postDataAction('/overView/materialDetailChat', params).then((res) => {
+        if (res.success) {
+          this.initEchart('echartCircular', this.handlerEchartOption(res.result))
+        }
+      })
+    },
+    handleScroll() {
+      var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
+      this.scrollTop = scrollTop
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.mediaId = JSON.parse(localStorage.getItem('videoInfo')).mediaId
+      window.addEventListener('scroll', this.handleScroll)
+      this.clientWidth = document.documentElement.clientWidth - 224
+      //   this.$route.query.mediaId
+      //   this.$route.query.md5
+      this.getMaterialInfo()
+    })
+  },
+  created() {},
+}
+</script>

+ 758 - 0
src/views/modules/Statistics/materialReport/marterialList.vue

@@ -0,0 +1,758 @@
+<style>
+.materialReport .chart-card-content {
+  display: none !important;
+}
+</style>
+<style scoped>
+.top-ul-style {
+  width: 100%;
+  padding-left: 0;
+}
+.top-ul-style li {
+  height: 100px;
+  border: 1px solid #f2f2f2;
+  margin-bottom: 5px;
+  padding: 10px;
+  display: flex;
+  justify-content: space-between;
+}
+.li-cost {
+  display: flex;
+  flex-flow: column;
+  justify-content: center;
+  align-content: flex-end;
+}
+.li-cost span {
+  font-size: 16px;
+  font-weight: 500;
+  min-width: 50px;
+  text-align: right;
+}
+</style>
+<template>
+  <div class="materialReport">
+    <div class="card-container">
+      <div class="option" style="justify-content: space-between">
+        <div class="option" style="padding: 0">
+          <div class="item">
+            <span>唯一编码</span>
+            <a-input style="width: 300px" v-model="md5"></a-input>
+          </div>
+        </div>
+
+        <div class="item" style="float: right">
+          <a-button @click="handleSubmit" type="primary" :loading="videoloading">搜索</a-button>
+          <a-button @click="resetSubmit" style="margin-left: 15px" :loading="resetLoading">重置</a-button>
+        </div>
+      </div>
+    </div>
+    <a-row :gutter="24" style="margin-top: 20px">
+      <a-col :xl="24">
+        <a-card title="数据列表" style="width: 100%; min-height: 700px" :bordered="false">
+          <div class="tableTop" style="text-align: end; margin: 0 0 15px 0">
+            <a-button
+              type="primary"
+              class="export"
+              @click="exportExcel"
+              style="margin-right: 10px"
+              :loading="excelLoading"
+              >导出报表</a-button
+            >
+            <a-button type="primary" class="add" @click="customColumns">自定义列</a-button>
+          </div>
+          <a-table
+            size="middle"
+            :columns="columns"
+            :dataSource="tableData"
+            bordered
+            id="outTable"
+            :pagination="ipagination"
+            :scroll="{ x: scrollX }"
+            :loading="loading"
+            ref="accountTable"
+            :customRow="rowClick"
+            :width="tableWidth"
+            @change="sort"
+            style="word-break: break-all; font-size: 16px; font-weight: 600"
+          >
+            <span slot="coverUrl" slot-scope="text, records">
+              <img
+                :src="text || noImg"
+                alt=""
+                style="width: 100%; height: auto"
+                @click.stop="
+                  visibleVideo = true
+                  videoUrlShow = records.url
+                "
+              />
+            </span>
+            <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
+            <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
+            <span slot="clickMaterial" slot-scope="clickMaterial">{{ clickMaterial | formatCurrency }}</span>
+            <span slot="showMaterial" slot-scope="showMaterial">{{ showMaterial | formatCurrency }}</span>
+            <span slot="convertMaterial" slot-scope="convertMaterial">{{ convertMaterial | formatCurrency }}</span>
+            <span slot="play25FeedBreak" slot-scope="play25FeedBreak">{{ play25FeedBreak | formatCurrency }}</span>
+            <span slot="play50FeedBreak" slot-scope="play50FeedBreak">{{ play50FeedBreak | formatCurrency }}</span>
+            <span slot="play75FeedBreak" slot-scope="play75FeedBreak">{{ play75FeedBreak | formatCurrency }}</span>
+            <span slot="play100FeedBreak" slot-scope="play100FeedBreak">{{ play100FeedBreak | formatCurrency }}</span>
+            <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
+            <span slot="downloadFinish" slot-scope="downloadFinish">{{ downloadFinish | formatCurrency }}</span>
+            <span slot="downloadStart" slot-scope="downloadStart">{{ downloadStart | formatCurrency }}</span>
+            <span slot="likeMaterial" slot-scope="likeMaterial">{{ likeMaterial | formatCurrency }}</span>
+            <span slot="shareMaterial" slot-scope="shareMaterial">{{ shareMaterial | formatCurrency }}</span>
+            <span slot="register" slot-scope="register">{{ register | formatCurrency }}</span>
+            <span slot="follow" slot-scope="follow">{{ follow | formatCurrency }}</span>
+            <span slot="formCount" slot-scope="formCount">{{ formCount | formatCurrency }}</span>
+            <span slot="formCountCost" slot-scope="formCountCost">{{ formCountCost | decimalsHandle }}</span>
+            <span slot="aClick" slot-scope="aClick">{{ aClick | formatCurrency }}</span>
+            <span slot="photoShow" slot-scope="photoShow">{{ photoShow | formatCurrency }}</span>
+            <span slot="photoClick" slot-scope="photoClick">{{ photoClick | formatCurrency }}</span>
+            <span slot="bClick" slot-scope="bClick">{{ bClick | formatCurrency }}</span>
+            <span slot="active" slot-scope="active">{{ active | formatCurrency }}</span>
+            <span slot="submit" slot-scope="submit">{{ submit | formatCurrency }}</span>
+            <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
+            <span slot="eventCreditGrantLandingPage" slot-scope="eventCreditGrantLandingPage">{{
+              eventCreditGrantLandingPage | formatCurrency
+            }}</span>
+            <span slot="submitCost" slot-scope="submitCost">{{ submitCost | decimalsHandle }}</span>
+            <span slot="eventCreditGrantLandingPageCost" slot-scope="eventCreditGrantLandingPageCost">{{
+              eventCreditGrantLandingPageCost | decimalsHandle
+            }}</span>
+            <span slot="submitRate" slot-scope="submitRate">{{ submitRate | toPercentage }}</span>
+            <span slot="eventCreditGrantLandingPageRate" slot-scope="eventCreditGrantLandingPageRate">{{
+              eventCreditGrantLandingPageRate | toPercentage
+            }}</span>
+            <span slot="play25FeedBreakRate" slot-scope="play25FeedBreakRate">{{
+              play25FeedBreakRate | toPercentage
+            }}</span>
+            <span slot="playOverRate" slot-scope="playOverRate">{{ playOverRate | toPercentage }}</span>
+            <!-- 新加数据 -->
+
+            <span slot="convertRate" slot-scope="convertRate">{{ convertRate | toPercentage }}</span>
+            <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
+            <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
+            <span slot="cpc" slot-scope="cpc">{{ cpc | decimalsHandle }}</span>
+            <span slot="cpm" slot-scope="cpm">{{ cpm | decimalsHandle }}</span>
+            <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
+            <span slot="installFinishRate" slot-scope="installFinishRate">{{ installFinishRate | toPercentage }}</span>
+            <span slot="validPlayRate" slot-scope="validPlayRate">{{ validPlayRate | toPercentage }}</span>
+            <span slot="activePayCost" slot-scope="activePayCost">{{ activePayCost | decimalsHandle }}</span>
+            <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
+            <span slot="validPlayCost" slot-scope="validPlayCost">{{ validPlayCost | decimalsHandle }}</span>
+            <span slot="activeCost" slot-scope="activeCost">{{ activeCost | decimalsHandle }}</span>
+            <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
+            <span slot="gameAddictionCost" slot-scope="gameAddictionCost">{{
+              gameAddictionCost | decimalsHandle
+            }}</span>
+            <span slot="downloadFinishCost" slot-scope="downloadFinishCost">{{
+              downloadFinishCost | decimalsHandle
+            }}</span>
+            <span slot="downloadStartCost" slot-scope="downloadStartCost">{{
+              downloadStartCost | decimalsHandle
+            }}</span>
+            <span slot="installFinishCost" slot-scope="installFinishCost">{{
+              installFinishCost | decimalsHandle
+            }}</span>
+            <span slot="convertCost" slot-scope="convertCost">{{ convertCost | decimalsHandle }}</span>
+
+            <!--  -->
+            <span slot="downloadStartRate" slot-scope="downloadStartRate">{{ downloadStartRate | toPercentage }}</span>
+            <span slot="downloadFinishRate" slot-scope="downloadFinishRate">{{
+              downloadFinishRate | toPercentage
+            }}</span>
+            <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
+            <span slot="activeRegisterRate" slot-scope="activeRegisterRate">{{
+              activeRegisterRate | toPercentage
+            }}</span>
+            <span slot="gameAddictionRate" slot-scope="gameAddictionRate">{{ gameAddictionRate | toPercentage }}</span>
+            <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
+            <!-- <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span> -->
+          </a-table>
+        </a-card>
+      </a-col>
+    </a-row>
+    <a-modal title="查看视频" v-model="visibleVideo" :width="400" :footer="null">
+      <video class="video" :src="videoUrlShow" controls="controls" style="width: 100%">
+        您的浏览器不支持 video 标签。
+      </video>
+    </a-modal>
+    <customColumn
+      :visible="visible"
+      :listNum="listNum"
+      :fiexColumn="columnsFixd"
+      :mediaType="2"
+      @closeCustomColumn="closeCustomColumn"
+      @changeColumn="changeColumn"
+    />
+  </div>
+</template>
+
+<script>
+import moment from 'moment'
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
+import YoutTable from '@/components/youtTable/YoutTable'
+import ChartCard from '@/components/ChartCard'
+import Trend from '@/components/Trend'
+import { mapGetters } from 'vuex'
+import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl' // 停止除当前外的其他视频播放,及停止所有视频播放的方法
+import customColumn from '../components/customColumn.vue'
+var echarts = require('echarts')
+
+const columnsFixd = [
+  {
+    title: '素材',
+    dataIndex: 'coverUrl',
+    scopedSlots: { customRender: 'coverUrl' },
+    align: 'center',
+    key: 'date',
+    width: 100,
+    fixed: 'left',
+  },
+  {
+    title: '唯一编码',
+    dataIndex: 'signature',
+    align: 'center',
+    width: 100,
+    fixed: 'left',
+  },
+  {
+    title: '素材名称',
+    dataIndex: 'materialName',
+    align: 'center',
+    width: 100,
+    fixed: 'left',
+    customRender: function (text) {
+      if (text) {
+        return text
+      } else {
+        return '-'
+      }
+    },
+  },
+  {
+    title: '所属项目',
+    dataIndex: 'projectName',
+    align: 'center',
+    width: 100,
+    fixed: 'left',
+  },
+]
+
+const initVariableColimns = [
+  {
+    title: '消耗(元)',
+    dataIndex: 'cost',
+    width: 150,
+    tip: '广告在投放期间的花费总额',
+    align: 'center',
+    scopedSlots: { customRender: 'cost' },
+    sorter: () => {},
+  },
+  // {
+  //     title: '折后消耗(元)',
+  //     dataIndex: 'discountCost',
+  //     width:150,
+  //     tip: '广告在投放期间的花费总额',
+  //     align: 'center',
+  //     scopedSlots: { customRender: 'discountCost' },
+  //     sorter: () => {}
+  // },
+  {
+    title: '封面曝光数',
+    dataIndex: 'photoShow',
+    tip: '广告在瀑布流被观看次数',
+    align: 'center',
+    scopedSlots: { customRender: 'photoShow' },
+    sorter: () => {},
+  },
+  {
+    title: '封面点击数',
+    dataIndex: 'photoClick',
+    tip: '用户点击封面进入视频播放页的次数(数据会进行反作弊去重)',
+    align: 'center',
+
+    scopedSlots: { customRender: 'photoClick' },
+    sorter: () => {},
+  },
+  {
+    title: '封面点击率',
+    dataIndex: 'clickRate',
+    tip: '封面点击数占封面展示数百分比',
+    align: 'center',
+    scopedSlots: { customRender: 'clickRate' },
+    sorter: () => {},
+  },
+  {
+    title: '素材曝光数',
+    dataIndex: 'aClick',
+    tip: '用户进入视频播放页观看的次数(数据会进行反作弊去重)',
+    align: 'center',
+
+    scopedSlots: { customRender: 'aClick' },
+    sorter: () => {},
+  },
+  {
+    title: '行为数',
+    dataIndex: 'bClick',
+    tip: '用户在视频播放页单击转化按钮的次数/展示数*100%',
+    align: 'center',
+
+    scopedSlots: { customRender: 'bClick' },
+    sorter: () => {},
+  },
+
+  {
+    title: '行为率',
+    dataIndex: 'bClickRate',
+    tip: '行为数占素材曝光数百分比',
+    align: 'center',
+    scopedSlots: { customRender: 'bClickRate' },
+    sorter: () => {},
+  },
+  {
+    title: '平均千次封面曝光花费(元)',
+    dataIndex: 'cpm',
+    tip: '花费/封面曝光数*1000',
+    align: 'center',
+    scopedSlots: { customRender: 'cpm' },
+    sorter: () => {},
+  },
+  {
+    title: '平均封面点击单价(元)',
+    dataIndex: 'cpc',
+    tip: '花费/封面点击数',
+    align: 'center',
+    scopedSlots: { customRender: 'cpc' },
+    sorter: () => {},
+  },
+  {
+    title: '平均行为单价(元)',
+    dataIndex: 'cpb',
+    tip: '总花费/行为数',
+    align: 'center',
+    scopedSlots: { customRender: 'cpb' },
+    sorter: () => {},
+  },
+]
+export default {
+  components: {
+    YoutTable,
+    ChartCard,
+    Trend,
+    customColumn,
+  },
+  data() {
+    return {
+      excelLoading: false,
+      tableData: [],
+      designTopLoading: false,
+      noImg: require('@/assets/noImg.png'),
+      visibleVideo: false,
+      videoUrlShow: '',
+      cost: '0',
+      costLink: 0,
+      videoTotal: '0',
+      newVideo: 0,
+      hotTotal: '0',
+      xiaoTotal: '0',
+      spinning: false,
+      loading: false,
+      chartList: [],
+      videoList: [],
+      designTopList: [],
+      columns: [...columnsFixd, ...initVariableColimns], //table的表头
+      columnsFixd,
+      ipagination: {
+        current: 1,
+        pageSize: 10,
+        //   pageSizeOptions: ['10', '20', '30'],
+        showTotal: (total, range) => {
+          return range[0] + '-' + range[1] + ' 共' + total + '条'
+        },
+        showQuickJumper: true,
+        // showSizeChanger: true,
+        // pageSizeOptions: ['10', '30', '50'],
+        total: 0,
+        onChange: (current, pageSize) => {
+          // 切换分页时的回调,
+          // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+          this.ipagination.current = current
+          this.ipagination.pageSize = pageSize
+        },
+      },
+
+      dateRanges: {
+        今天: [moment(), moment()],
+        昨天: [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
+        近一周: [moment().subtract(7, 'days'), moment()],
+        近一月: [moment().subtract(1, 'months'), moment()],
+        近半年: [moment().subtract(6, 'months'), moment()],
+        近一年: [moment().subtract(12, 'months'), moment()],
+      },
+      dateValue: [moment().subtract(7, 'days'), moment()],
+      dataDimension: 'a',
+      mediaDimension: 'b',
+      dataDimensionValue: [],
+      dataDimensionList: [],
+      specificLoading: false,
+      order: null,
+      target: null,
+      materialData: null,
+      md5: '',
+      visible: false,
+      listNum: [],
+      scrollX: 1500,
+      tableWidth: '', //设置表格的列宽
+      resetLoading: false,
+      videoloading: false,
+    }
+  },
+  watch: {
+    visibleVideo(n, o) {
+      if (!n) {
+        stopOtherVideo()
+        closeAllVideoFun()
+      }
+    },
+    'ipagination.current': function (n, o) {
+      if (n != o) {
+        this.getMoreVideoList({
+          ...this.materialData,
+        })
+      }
+    },
+  },
+  methods: {
+    rowClick(record, index) {
+      return {
+        on: {
+          click: (e) => {
+            var params = { md5: record.signature, mediaId: 2 }
+            localStorage.setItem('videoInfo', JSON.stringify(params))
+            this.$router.push({
+              path: '/materialReport/marterialDetail',
+            })
+          },
+        },
+      }
+    },
+    moment,
+    closeCustomColumn() {
+      this.visible = false
+    },
+    changeColumn(val) {
+      this.columns = [...val]
+      if (this.columns.length > this.columnsFixd.length && this.columns.length < 8) {
+        this.columns.forEach((element, index) => {
+          if (index < this.columns.length - 1) {
+            if (element.dataIndex == 'coverUrl') {
+              element.width = 100
+              element.fixed = false
+            } else {
+              element.width = 'auto'
+              element.fixed = false
+            }
+          }
+        })
+
+        // this.scrollX=2000+200*(this.columns.length-this.columnsFixd.length)
+      } else if (this.columns.length >= 8) {
+        this.columns.forEach((element, index) => {
+          if (index < this.columnsFixd.length) {
+            element.width = 100
+            element.fixed = 'left'
+          }
+        })
+
+        this.scrollX = 1000 + 200 * (this.columns.length - this.columnsFixd.length)
+      } else {
+        this.scrollX = 0
+        this.columns.forEach((element) => {
+          console.log(element)
+          if (element.dataIndex == 'coverUrl') {
+            element.width = 100
+            element.fixed = false
+          } else {
+            element.width = 'auto'
+            element.fixed = false
+          }
+        })
+      }
+
+      let arr = JSON.stringify(this.columns)
+      this.postDataAction('/toutiao/videoReportDaily/saveOrUpdateColumnJson', {
+        json: arr,
+        columnType: 12,
+      }).then((res) => {
+        // console.log(res)
+      })
+    },
+    customColumns() {
+      this.visible = true
+      this.listNum = [...this.columns]
+    },
+    ...mapGetters(['userInfo']),
+    filterOption(input, option) {
+      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+    },
+    sort(pagination, filters, sorter, { currentDataSource }) {
+      // console.log(pagination, filters, sorter)
+      this.ipagination.current = pagination.current
+      this.ipagination.pageSize = pagination.pageSize
+      if (sorter.order) {
+        this.order = sorter.order ? sorter.order : 'descend'
+        this.target = sorter.columnKey
+        this.getMoreVideoList({
+          ...this.materialData,
+          target: sorter.columnKey,
+          order: sorter.order ? sorter.order : 'descend',
+        })
+      } else {
+        this.order = null
+        this.target = null
+      }
+    },
+    getData() {
+      var data = { ...this.materialData, md5: this.md5 }
+      this.getMoreVideoList(data)
+    },
+
+    getMoreVideoList(data) {
+      this.loading = true
+      var params = { ...data }
+      params.channelType = null
+
+      if (data.target) {
+        params.target = data.target
+        if (data.order == 'descend') {
+          params.order = 'desc'
+        } else {
+          params.order = 'asc'
+        }
+      } else {
+        params.target = this.target
+        params.order = this.order == 'descend' ? 'desc' : this.order == null ? null : 'asc'
+      }
+
+      params.pageSize = this.ipagination.pageSize
+      params.pageNo = this.ipagination.current
+      this.postDataAction('/overView/materialTopViewMore', params).then((res) => {
+        this.loading = false
+        this.resetLoading = false
+        this.videoloading = false
+        if (res.success) {
+          this.tableData = res.result.list
+          this.ipagination.total = res.result.total
+        }
+      })
+    },
+    getDesignTopList(data) {
+      this.designTopLoading = true
+      return new Promise((resolve, reject) => {
+        var params = {
+          // startDate: this.dateValue.length == 2 ? moment(this.dateValue[0]).format('YYYY-MM-DD') : null,
+          // endDate: this.dateValue.length == 2 ? moment(this.dateValue[1]).format('YYYY-MM-DD') : null,
+          // userId: this.userInfo().id,
+          // pageSize: this.ipagination.pageSize,
+          // pageNo: this.ipagination.current,
+          // target: 'cost',
+          // order: 'desc',
+        }
+        params.startDate = this.dateValue.length == 2 ? moment(this.dateValue[0]).format('YYYY-MM-DD') : null
+        params.endDate = this.dateValue.length == 2 ? moment(this.dateValue[1]).format('YYYY-MM-DD') : null
+        params.userId = this.userInfo().id
+        params.pageSize = this.ipagination.pageSize
+        params.pageNo = this.ipagination.current
+
+        if (data) {
+          params.target = data.target
+          if (data.order == 'descend') {
+            params.order = 'desc'
+          } else {
+            params.order = 'asc'
+          }
+        } else {
+          params.target = this.params.order = this.order == 'descend' ? 'desc' : 'asc'
+        }
+        this.postDataAction('/overView/designTop', params).then((res) => {
+          this.designTopLoading = false
+          if (res.success) {
+            this.designTopList = res.result.list
+            this.ipagination.total = res.result.total
+            resolve(res.result)
+          } else {
+            reject(res.message)
+          }
+        })
+      })
+    },
+
+    handleSubmit() {
+      this.videoloading = true
+      this.ipagination.current = 1
+      this.getData()
+    },
+    resetSubmit() {
+      this.ipagination.current = 1
+      this.resetLoading = true
+      this.md5 = ''
+      this.getData()
+    },
+    //导出报表
+    exportExcel() {
+      this.excelLoading = true
+      let column = this.columns.map((item, index) => {
+        return item.dataIndex
+      })
+      let columns = column.splice(4)
+      // "mediaId":"",
+      // "projects":[],
+      // "columns":"",
+      // "startDate":"",
+      // "endDate":"",
+      // "channelType":"",
+      // "md5":"",
+      // "target":"",
+      // "order":""
+      downFilePost('/overView/excel', {
+        ...this.materialData,
+        columns,
+        target: this.target,
+        order: this.order == 'descend' ? 'desc' : 'asc',
+        md5: this.md5,
+      }).then((res) => {
+        let blob = new Blob([res], {
+          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+        })
+        let downloadElement = document.createElement('a')
+        let href = window.URL.createObjectURL(blob) //创建下载的链接
+        downloadElement.href = href
+        downloadElement.download = this.materialData.startDate + '~' + this.materialData.endDate + '素材报表.xlsx' //下载后文件名
+        document.body.appendChild(downloadElement)
+        downloadElement.click() //点击下载
+        document.body.removeChild(downloadElement) //下载完成移除元素
+        window.URL.revokeObjectURL(href) //释放掉blob对象
+        this.excelLoading = false
+      })
+    },
+    tableChange(data) {
+      console.log(data)
+    },
+    //获取echart的值
+    initEchart(idName, optionName) {
+      const chart = this.$refs[idName]
+      //   console.log(chart)
+      if (chart) {
+        const myChart = echarts.init(document.getElementById(idName))
+        // myChart.showLoading({
+        //     text: "图表数据正在努力加载..."
+        // });
+
+        myChart.setOption(optionName)
+        window.addEventListener('resize', function () {
+          myChart.resize()
+        })
+      }
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.postDataAction('/toutiao/videoReportDaily/getColumnJson', {
+        columnType: 12,
+      }).then((res) => {
+        // console.log(res)
+        if (res.success) {
+          // console.log(JSON.parse(res.result))
+          if (res.result) {
+            let columns = JSON.parse(res.result)
+            if (columns.length) {
+              if (columns.length >= columnsFixd.length) {
+                columns.map((item, index) => {
+                  if (index > columnsFixd.length - 1) {
+                    item.sorter = function (a, b) {}
+                  }
+                })
+                columns = columns.slice(columnsFixd.length)
+                this.columns = [...columnsFixd, ...columns]
+
+                // this.tableHandle()
+              }
+
+              // console.log(this.columns)
+            }
+          }
+
+          this.changeColumn(this.columns)
+        }
+      })
+
+      this.materialData = JSON.parse(localStorage.getItem('materialParams'))
+      this.getMoreVideoList(this.materialData)
+    })
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.materialReport {
+  .option {
+    background: white;
+    padding: 20px;
+    display: flex;
+    justify-content: flex-start;
+    flex-wrap: wrap;
+    .item {
+      margin-right: 15px;
+      margin-bottom: 15px;
+      height: 32px;
+      line-height: 32px;
+      flex-shrink: 0;
+      span {
+        margin-right: 10px;
+      }
+    }
+  }
+  .echart {
+    margin-top: 20px;
+    padding: 0 20px 20px;
+    background: white;
+    .echart-header {
+      padding: 20px 0;
+      font-size: 15px;
+      font-weight: 600;
+    }
+  }
+  .tableBody {
+    margin-top: 20px;
+  }
+}
+</style>
+<style>
+.card-container {
+  overflow: hidden;
+  /* padding: 24px; */
+}
+.card-container > .ant-tabs-card > .ant-tabs-content {
+  /* height: 120px; */
+  margin-top: -16px;
+}
+
+.card-container > .ant-tabs-card > .ant-tabs-content > .ant-tabs-tabpane {
+  background: #fff;
+  /* padding: 16px; */
+}
+
+.card-container > .ant-tabs-card > .ant-tabs-bar {
+  border-color: #fff;
+}
+
+.card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
+  border-color: transparent;
+  background: transparent !important;
+}
+
+.card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
+  border-color: #fff;
+  background: #fff !important;
+}
+</style>

+ 706 - 0
src/views/modules/Statistics/materialReport/marterialTtList.vue

@@ -0,0 +1,706 @@
+<style>
+.materialReport .chart-card-content {
+  display: none !important;
+}
+</style>
+<style scoped>
+.top-ul-style {
+  width: 100%;
+  padding-left: 0;
+}
+.top-ul-style li {
+  height: 100px;
+  border: 1px solid #f2f2f2;
+  margin-bottom: 5px;
+  padding: 10px;
+  display: flex;
+  justify-content: space-between;
+}
+.li-cost {
+  display: flex;
+  flex-flow: column;
+  justify-content: center;
+  align-content: flex-end;
+}
+.li-cost span {
+  font-size: 16px;
+  font-weight: 500;
+  min-width: 50px;
+  text-align: right;
+}
+</style>
+<template>
+  <div class="materialReport">
+    <div class="card-container">
+      <div class="option" style="justify-content: space-between">
+        <div class="option" style="padding: 0">
+          <div class="item">
+            <span>唯一编码</span>
+            <a-input style="width: 300px" v-model="md5"></a-input>
+          </div>
+        </div>
+
+        <div class="item" style="float: right">
+          <a-button @click="handleSubmit" type="primary" :loading="videoLoading">搜索</a-button>
+          <a-button @click="resetSubmit" style="margin-left: 15px" :loading="resetLoading">重置</a-button>
+        </div>
+      </div>
+    </div>
+    <a-row :gutter="24" style="margin-top: 20px">
+      <a-col :xl="24">
+        <a-card title="数据列表" style="width: 100%; min-height: 700px" :bordered="false">
+          <div class="tableTop" style="text-align: end; margin: 0 0 15px 0">
+            <a-button type="primary" class="export" @click="exportExcel" style="margin-right: 10px">导出报表</a-button>
+            <a-button type="primary" class="add" @click="customColumns">自定义列</a-button>
+          </div>
+          <a-table
+            size="middle"
+            :columns="columns"
+            :dataSource="tableData"
+            bordered
+            id="outTable"
+            :pagination="ipagination"
+            :scroll="{ x: scrollX }"
+            :loading="loading"
+            ref="accountTable"
+            :width="tableWidth"
+            :customRow="rowClick"
+            @change="sort"
+            style="word-break: break-all; font-size: 16px; font-weight: 600"
+          >
+            <span slot="coverUrl" slot-scope="text, records">
+              <img
+                :src="text || noImg"
+                alt=""
+                style="width: 100%; height: auto"
+                @click.stop="
+                  visibleVideo = true
+                  videoUrlShow = records.url
+                "
+              />
+            </span>
+            <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
+            <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
+            <span slot="clickMaterial" slot-scope="clickMaterial">{{ clickMaterial | formatCurrency }}</span>
+            <span slot="showMaterial" slot-scope="showMaterial">{{ showMaterial | formatCurrency }}</span>
+            <span slot="convertMaterial" slot-scope="convertMaterial">{{ convertMaterial | formatCurrency }}</span>
+            <span slot="play25FeedBreak" slot-scope="play25FeedBreak">{{ play25FeedBreak | formatCurrency }}</span>
+            <span slot="play50FeedBreak" slot-scope="play50FeedBreak">{{ play50FeedBreak | formatCurrency }}</span>
+            <span slot="play75FeedBreak" slot-scope="play75FeedBreak">{{ play75FeedBreak | formatCurrency }}</span>
+            <span slot="play100FeedBreak" slot-scope="play100FeedBreak">{{ play100FeedBreak | formatCurrency }}</span>
+            <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
+            <span slot="downloadFinish" slot-scope="downloadFinish">{{ downloadFinish | formatCurrency }}</span>
+            <span slot="downloadStart" slot-scope="downloadStart">{{ downloadStart | formatCurrency }}</span>
+            <span slot="likeMaterial" slot-scope="likeMaterial">{{ likeMaterial | formatCurrency }}</span>
+            <span slot="shareMaterial" slot-scope="shareMaterial">{{ shareMaterial | formatCurrency }}</span>
+            <span slot="register" slot-scope="register">{{ register | formatCurrency }}</span>
+            <span slot="follow" slot-scope="follow">{{ follow | formatCurrency }}</span>
+            <span slot="formCount" slot-scope="formCount">{{ formCount | formatCurrency }}</span>
+            <span slot="formCountCost" slot-scope="formCountCost">{{ formCountCost | decimalsHandle }}</span>
+            <span slot="aClick" slot-scope="aClick">{{ aClick | formatCurrency }}</span>
+            <span slot="photoShow" slot-scope="photoShow">{{ photoShow | formatCurrency }}</span>
+            <span slot="photoClick" slot-scope="photoClick">{{ photoClick | formatCurrency }}</span>
+            <span slot="bClick" slot-scope="bClick">{{ bClick | formatCurrency }}</span>
+            <span slot="active" slot-scope="active">{{ active | formatCurrency }}</span>
+            <span slot="submit" slot-scope="submit">{{ submit | formatCurrency }}</span>
+            <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
+            <span slot="eventCreditGrantLandingPage" slot-scope="eventCreditGrantLandingPage">{{
+              eventCreditGrantLandingPage | formatCurrency
+            }}</span>
+            <span slot="submitCost" slot-scope="submitCost">{{ submitCost | decimalsHandle }}</span>
+            <span slot="eventCreditGrantLandingPageCost" slot-scope="eventCreditGrantLandingPageCost">{{
+              eventCreditGrantLandingPageCost | decimalsHandle
+            }}</span>
+            <span slot="submitRate" slot-scope="submitRate">{{ submitRate | toPercentage }}</span>
+            <span slot="eventCreditGrantLandingPageRate" slot-scope="eventCreditGrantLandingPageRate">{{
+              eventCreditGrantLandingPageRate | toPercentage
+            }}</span>
+            <span slot="play25FeedBreakRate" slot-scope="play25FeedBreakRate">{{
+              play25FeedBreakRate | toPercentage
+            }}</span>
+            <span slot="playOverRate" slot-scope="playOverRate">{{ playOverRate | toPercentage }}</span>
+            <!-- 新加数据 -->
+
+            <span slot="convertRate" slot-scope="convertRate">{{ convertRate | toPercentage }}</span>
+            <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
+            <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
+            <span slot="cpc" slot-scope="cpc">{{ cpc | decimalsHandle }}</span>
+            <span slot="cpm" slot-scope="cpm">{{ cpm | decimalsHandle }}</span>
+            <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
+            <span slot="installFinishRate" slot-scope="installFinishRate">{{ installFinishRate | toPercentage }}</span>
+            <span slot="validPlayRate" slot-scope="validPlayRate">{{ validPlayRate | toPercentage }}</span>
+            <span slot="activePayCost" slot-scope="activePayCost">{{ activePayCost | decimalsHandle }}</span>
+            <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
+            <span slot="validPlayCost" slot-scope="validPlayCost">{{ validPlayCost | decimalsHandle }}</span>
+            <span slot="activeCost" slot-scope="activeCost">{{ activeCost | decimalsHandle }}</span>
+            <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
+            <span slot="gameAddictionCost" slot-scope="gameAddictionCost">{{
+              gameAddictionCost | decimalsHandle
+            }}</span>
+            <span slot="downloadFinishCost" slot-scope="downloadFinishCost">{{
+              downloadFinishCost | decimalsHandle
+            }}</span>
+            <span slot="downloadStartCost" slot-scope="downloadStartCost">{{
+              downloadStartCost | decimalsHandle
+            }}</span>
+            <span slot="installFinishCost" slot-scope="installFinishCost">{{
+              installFinishCost | decimalsHandle
+            }}</span>
+            <span slot="convertCost" slot-scope="convertCost">{{ convertCost | decimalsHandle }}</span>
+
+            <!--  -->
+            <span slot="downloadStartRate" slot-scope="downloadStartRate">{{ downloadStartRate | toPercentage }}</span>
+            <span slot="downloadFinishRate" slot-scope="downloadFinishRate">{{
+              downloadFinishRate | toPercentage
+            }}</span>
+            <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
+            <span slot="activeRegisterRate" slot-scope="activeRegisterRate">{{
+              activeRegisterRate | toPercentage
+            }}</span>
+            <span slot="gameAddictionRate" slot-scope="gameAddictionRate">{{ gameAddictionRate | toPercentage }}</span>
+            <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
+            <!-- <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span> -->
+          </a-table>
+        </a-card>
+      </a-col>
+    </a-row>
+    <a-modal title="查看视频" v-model="visibleVideo" :width="400" :footer="null">
+      <video class="video" :src="videoUrlShow" controls="controls" style="width: 100%">
+        您的浏览器不支持 video 标签。
+      </video>
+    </a-modal>
+    <customColumn
+      :visible="visible"
+      :listNum="listNum"
+      :fiexColumn="columnsFixd"
+      :mediaType="1"
+      @closeCustomColumn="closeCustomColumn"
+      @changeColumn="changeColumn"
+    />
+  </div>
+</template>
+
+<script>
+import moment from 'moment'
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
+import YoutTable from '@/components/youtTable/YoutTable'
+import ChartCard from '@/components/ChartCard'
+import Trend from '@/components/Trend'
+import { mapGetters } from 'vuex'
+import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl' // 停止除当前外的其他视频播放,及停止所有视频播放的方法
+import customColumn from '../components/customColumn.vue'
+var echarts = require('echarts')
+
+const columnsFixd = [
+  {
+    title: '素材',
+    dataIndex: 'coverUrl',
+    scopedSlots: { customRender: 'coverUrl' },
+    align: 'center',
+    key: 'date',
+    width: 100,
+    fixed: 'left',
+  },
+  {
+    title: '唯一编码',
+    dataIndex: 'signature',
+    align: 'center',
+    width: 100,
+    fixed: 'left',
+  },
+  {
+    title: '素材名称',
+    dataIndex: 'materialName',
+    align: 'center',
+    width: 100,
+    fixed: 'left',
+    customRender: function (text) {
+      if (text) {
+        return text
+      } else {
+        return '-'
+      }
+    },
+  },
+  {
+    title: '所属项目',
+    dataIndex: 'projectName',
+    align: 'center',
+    width: 100,
+    fixed: 'left',
+  },
+]
+
+const initVariableColimns = [
+  {
+    title: '消耗(元)',
+    dataIndex: 'cost',
+    scopedSlots: { customRender: 'cost' },
+    align: 'center',
+    sorter: (a, b) => {},
+  },
+  {
+    title: '点击数',
+    dataIndex: 'clickMaterial',
+    align: 'center',
+    scopedSlots: { customRender: 'clickMaterial' },
+    sorter: (a, b) => {},
+    // (a, b) => a.clickMaterial - b.clickMaterial
+  },
+  {
+    title: '点击率',
+    dataIndex: 'ctr',
+    align: 'center',
+    scopedSlots: { customRender: 'ctr' },
+    sorter: (a, b) => {},
+  },
+
+  {
+    title: '展示数',
+    dataIndex: 'showMaterial',
+    align: 'center',
+
+    scopedSlots: { customRender: 'showMaterial' },
+    sorter: (a, b) => {},
+  },
+  {
+    title: '平均千次展现费用(元)',
+    dataIndex: 'cpm',
+    tip: '广告平均每一千次展现所付出的费用,计算公式是:总花费/展示数*1000',
+    align: 'center',
+
+    scopedSlots: { customRender: 'cpm' },
+    sorter: (a, b) => {},
+  },
+  {
+    title: '平均点击单价(元)',
+    dataIndex: 'cpc',
+    tip: '广告主为每次点击付出的费用成本,计算公式是:总花费/点击数',
+    align: 'center',
+    scopedSlots: { customRender: 'cpc' },
+    sorter: (a, b) => {},
+  },
+]
+export default {
+  components: {
+    YoutTable,
+    ChartCard,
+    Trend,
+    customColumn,
+  },
+  data() {
+    return {
+      tableData: [],
+      designTopLoading: false,
+      resetLoading: false,
+      videoLoading: false,
+      noImg: require('@/assets/noImg.png'),
+      visibleVideo: false,
+      videoUrlShow: '',
+      cost: '0',
+      costLink: 0,
+      videoTotal: '0',
+      newVideo: 0,
+      hotTotal: '0',
+      xiaoTotal: '0',
+      spinning: false,
+      loading: false,
+      chartList: [],
+      videoList: [],
+      designTopList: [],
+      columns: [...columnsFixd, ...initVariableColimns], //table的表头
+      columnsFixd,
+      ipagination: {
+        current: 1,
+        pageSize: 10,
+        //   pageSizeOptions: ['10', '20', '30'],
+        showTotal: (total, range) => {
+          return range[0] + '-' + range[1] + ' 共' + total + '条'
+        },
+        showQuickJumper: true,
+        // showSizeChanger: true,
+        // pageSizeOptions: ['10', '30', '50'],
+        total: 0,
+        onChange: (current, pageSize) => {
+          // 切换分页时的回调,
+          // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+          this.ipagination.current = current
+          this.ipagination.pageSize = pageSize
+        },
+      },
+
+      dateRanges: {
+        今天: [moment(), moment()],
+        昨天: [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
+        近一周: [moment().subtract(7, 'days'), moment()],
+        近一月: [moment().subtract(1, 'months'), moment()],
+        近半年: [moment().subtract(6, 'months'), moment()],
+        近一年: [moment().subtract(12, 'months'), moment()],
+      },
+      dateValue: [moment().subtract(6, 'days'), moment()],
+      dataDimension: 'a',
+      mediaDimension: 'b',
+      dataDimensionValue: [],
+      dataDimensionList: [],
+      specificLoading: false,
+      order: null,
+      target: null,
+      materialData: null,
+      md5: '',
+      visible: false,
+      listNum: [],
+      scrollX: 1500,
+      tableWidth: '', //设置表格的列宽
+    }
+  },
+  watch: {
+    visibleVideo(n, o) {
+      if (!n) {
+        stopOtherVideo()
+        closeAllVideoFun()
+      }
+    },
+    'ipagination.current': function (n, o) {
+      if (n != o) {
+        this.getMoreVideoList({
+          ...this.materialData,
+        })
+      }
+    },
+  },
+  methods: {
+    rowClick(record, index) {
+      return {
+        on: {
+          click: (e) => {
+            var params = { md5: record.signature, mediaId: 1 }
+            localStorage.setItem('videoInfo', JSON.stringify(params))
+            this.$router.push({
+              path: '/materialReport/marterialDetail',
+            })
+          },
+        },
+      }
+    },
+
+    moment,
+    closeCustomColumn() {
+      this.visible = false
+    },
+    changeColumn(val) {
+      this.columns = [...val]
+
+      if (this.columns.length > this.columnsFixd.length && this.columns.length < 8) {
+        this.columns.forEach((element, index) => {
+          if (index < this.columns.length - 1) {
+            if (element.dataIndex == 'coverUrl') {
+              element.width = 100
+              element.fixed = false
+            } else {
+              element.width = 'auto'
+              element.fixed = false
+            }
+          }
+        })
+
+        // this.scrollX=2000+200*(this.columns.length-this.columnsFixd.length)
+      } else if (this.columns.length >= 8) {
+        this.columns.forEach((element, index) => {
+          if (index < this.columnsFixd.length) {
+            element.width = 100
+            element.fixed = 'left'
+          }
+        })
+
+        this.scrollX = 1000 + 200 * (this.columns.length - this.columnsFixd.length)
+      } else {
+        this.scrollX = 0
+
+        this.columns.forEach((element) => {
+          if (element.dataIndex == 'coverUrl') {
+            element.width = 100
+            element.fixed = false
+          } else {
+            element.width = 'auto'
+            element.fixed = false
+          }
+        })
+      }
+      let arr = JSON.stringify(this.columns)
+      this.postDataAction('/toutiao/videoReportDaily/saveOrUpdateColumnJson', {
+        json: arr,
+        columnType: 11,
+      }).then((res) => {
+        // console.log(res)
+      })
+    },
+    customColumns() {
+      this.visible = true
+      this.listNum = [...this.columns]
+    },
+    ...mapGetters(['userInfo']),
+    filterOption(input, option) {
+      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+    },
+    sort(pagination, filters, sorter, { currentDataSource }) {
+      // console.log(pagination, filters, sorter)
+      this.ipagination.current = pagination.current
+      this.ipagination.pageSize = pagination.pageSize
+      if (sorter.order) {
+        this.order = sorter.order ? sorter.order : 'descend'
+        this.target = sorter.columnKey
+        this.getMoreVideoList({
+          ...this.materialData,
+          target: sorter.columnKey,
+          order: sorter.order ? sorter.order : 'descend',
+        })
+      } else {
+        this.order = null
+        this.target = null
+      }
+    },
+    getData() {
+      var data = { ...this.materialData, md5: this.md5 }
+      this.getMoreVideoList(data)
+    },
+
+    getMoreVideoList(data) {
+      this.loading = true
+      var params = { ...data }
+      params.channelType = null
+
+      if (data.target) {
+        params.target = data.target
+        if (data.order == 'descend') {
+          params.order = 'desc'
+        } else {
+          params.order = 'asc'
+        }
+      } else {
+        params.target = this.target
+        params.order = this.order == 'descend' ? 'desc' : this.order == null ? null : 'asc'
+      }
+
+      params.pageSize = this.ipagination.pageSize
+      params.pageNo = this.ipagination.current
+      this.postDataAction('/overView/materialTopViewMore', params).then((res) => {
+        this.loading = false
+        this.resetLoading = false
+        this.videoLoading = false
+        if (res.success) {
+          this.tableData = res.result.list
+          this.ipagination.total = res.result.total
+        }
+      })
+    },
+    getDesignTopList(data) {
+      this.designTopLoading = true
+      return new Promise((resolve, reject) => {
+        var params = {
+          // startDate: this.dateValue.length == 2 ? moment(this.dateValue[0]).format('YYYY-MM-DD') : null,
+          // endDate: this.dateValue.length == 2 ? moment(this.dateValue[1]).format('YYYY-MM-DD') : null,
+          // userId: this.userInfo().id,
+          // pageSize: this.ipagination.pageSize,
+          // pageNo: this.ipagination.current,
+          // target: 'cost',
+          // order: 'desc',
+        }
+        params.startDate = this.dateValue.length == 2 ? moment(this.dateValue[0]).format('YYYY-MM-DD') : null
+        params.endDate = this.dateValue.length == 2 ? moment(this.dateValue[1]).format('YYYY-MM-DD') : null
+        params.userId = this.userInfo().id
+        params.pageSize = this.ipagination.pageSize
+        params.pageNo = this.ipagination.current
+
+        if (data) {
+          params.target = data.target
+          if (data.order == 'descend') {
+            params.order = 'desc'
+          } else {
+            params.order = 'asc'
+          }
+        } else {
+          params.target = this.target
+          params.order = this.order == 'descend' ? 'desc' : 'asc'
+        }
+        this.postDataAction('/overView/designTop', params).then((res) => {
+          this.designTopLoading = false
+          if (res.success) {
+            this.designTopList = res.result.list
+            this.ipagination.total = res.result.total
+            resolve(res.result)
+          } else {
+            reject(res.message)
+          }
+        })
+      })
+    },
+
+    handleSubmit() {
+      this.videoLoading = true
+      this.ipagination.current = 1
+      this.getData()
+    },
+    resetSubmit() {
+      this.resetLoading = true
+      this.ipagination.current = 1
+      this.md5 = ''
+      this.getData()
+    },
+    //导出报表
+    exportExcel() {
+      this.excelLoading = true
+      let column = this.columns.map((item, index) => {
+        return item.dataIndex
+      })
+      let columns = column.splice(4)
+      // "mediaId":"",
+      // "projects":[],
+      // "columns":"",
+      // "startDate":"",
+      // "endDate":"",
+      // "channelType":"",
+      // "md5":"",
+      // "target":"",
+      // "order":""
+      downFilePost('/overView/excel', {
+        ...this.materialData,
+        columns,
+        target: this.target,
+        order: this.order == 'descend' ? 'desc' : 'asc',
+        md5: this.md5,
+      }).then((res) => {
+        let blob = new Blob([res], {
+          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+        })
+        let downloadElement = document.createElement('a')
+        let href = window.URL.createObjectURL(blob) //创建下载的链接
+        downloadElement.href = href
+        downloadElement.download = this.materialData.startDate + '~' + this.materialData.endDate + '素材报表.xlsx' //下载后文件名
+        document.body.appendChild(downloadElement)
+        downloadElement.click() //点击下载
+        document.body.removeChild(downloadElement) //下载完成移除元素
+        window.URL.revokeObjectURL(href) //释放掉blob对象
+        this.excelLoading = false
+      })
+    },
+    tableChange(data) {
+      console.log(data)
+    },
+    //获取echart的值
+    initEchart(idName, optionName) {
+      const chart = this.$refs[idName]
+      //   console.log(chart)
+      if (chart) {
+        const myChart = echarts.init(document.getElementById(idName))
+        // myChart.showLoading({
+        //     text: "图表数据正在努力加载..."
+        // });
+
+        myChart.setOption(optionName)
+        window.addEventListener('resize', function () {
+          myChart.resize()
+        })
+      }
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.postDataAction('/toutiao/videoReportDaily/getColumnJson', {
+        columnType: 11,
+      }).then((res) => {
+        // console.log(res)
+        if (res.success) {
+          // console.log(JSON.parse(res.result))
+          if (res.result) {
+            let columns = JSON.parse(res.result)
+            if (columns.length) {
+              if (columns.length >= columnsFixd.length) {
+                columns.map((item, index) => {
+                  if (index > columnsFixd.length - 1) {
+                    item.sorter = function (a, b) {}
+                  }
+                })
+                columns = columns.slice(columnsFixd.length)
+                this.columns = [...columnsFixd, ...columns]
+
+                // this.tableHandle()
+              }
+
+              // console.log(this.columns)
+            }
+          }
+
+          this.changeColumn(this.columns)
+        }
+      })
+
+      this.materialData = JSON.parse(localStorage.getItem('TtmaterialParams'))
+      this.getMoreVideoList(this.materialData)
+    })
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.materialReport {
+  .option {
+    background: white;
+    padding: 20px;
+    display: flex;
+    justify-content: flex-start;
+    flex-wrap: wrap;
+    .item {
+      margin-right: 15px;
+      margin-bottom: 15px;
+      height: 32px;
+      line-height: 32px;
+      flex-shrink: 0;
+      span {
+        margin-right: 10px;
+      }
+    }
+  }
+  .echart {
+    margin-top: 20px;
+    padding: 0 20px 20px;
+    background: white;
+    .echart-header {
+      padding: 20px 0;
+      font-size: 15px;
+      font-weight: 600;
+    }
+  }
+  .tableBody {
+    margin-top: 20px;
+  }
+}
+</style>
+<style>
+.card-container {
+  overflow: hidden;
+  /* padding: 24px; */
+}
+.card-container > .ant-tabs-card > .ant-tabs-content {
+  /* height: 120px; */
+  margin-top: -16px;
+}
+
+.card-container > .ant-tabs-card > .ant-tabs-content > .ant-tabs-tabpane {
+  background: #fff;
+  /* padding: 16px; */
+}
+
+.card-container > .ant-tabs-card > .ant-tabs-bar {
+  border-color: #fff;
+}
+
+.card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
+  border-color: transparent;
+  background: transparent !important;
+}
+
+.card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
+  border-color: #fff;
+  background: #fff !important;
+}
+</style>

文件差异内容过多而无法显示
+ 923 - 458
src/views/modules/Statistics/materialReport/materialReport.vue


+ 2 - 9
src/views/modules/workBench/designLeader/platForm.vue

@@ -208,13 +208,12 @@ export default {
     },
     methods: {
         orderDetail(item){
-            console.log(item)
+            
             this.$parent.currentTabComponent='orderDetail';
             this.$parent.orderId=item.id
         },
         goOrderList(val){
-            console.log(val);
-            // console.log(this.$parent)
+            
             this.$parent.currentTabComponent='orderList';
             this.$parent.orderStatus=val
             
@@ -242,7 +241,6 @@ export default {
                 pageSize:8,
             }
             getAction('/platform/order/listByCreatorOrDesignLeader',params).then(res=>{
-                console.log(res);
                 this.loading=false;
                 this.orderProgressSpinning=false;
                 if(res.success){
@@ -256,14 +254,12 @@ export default {
         getOperationRecord(){
             this.spinning=true;
             getAction('/platform/operateRecord/createDesc').then(res=>{
-                console.log(res)
                  this.spinning=false;
                 if(res.success){
                     this.operateRecordList=res.result.list.map((item,index)=>{
                        
                             let time='';
                             let startTime=moment(item.createTime)
-                            console.log() 
                             if(moment().diff(startTime,'hours')>24){
                                 time=item.createTime.split(/[ ]+/)[0]
                                 return {
@@ -299,7 +295,6 @@ export default {
         },
         
         scrollRecord(){
-            console.log(this.$refs.scrollRecord);
             this.TimerObj=setInterval(()=>{
                 this.getOperationRecord()
 
@@ -309,7 +304,6 @@ export default {
         // 获取工作台内容
         getPlantformInfo(){
             getAction('/platform/query/jobContent').then(res=>{
-                console.log(res)
                 if(res.success){
                     if(this.$parent.role=='operator'){
                         this.countInfo=res.result.operatorJobContent
@@ -350,7 +344,6 @@ export default {
 
         getidentity(){
             getAction('/platform/query/identity',{}).then(res=>{
-                console.log(res);
                 if(res.success){
                     this.roleInfo=res.result
                 }

+ 85 - 22
src/views/modules/workBench/orderDetail.vue

@@ -507,15 +507,23 @@
                         
                     
                     <div class="section-box">
+
+                        <a-tabs v-model="activeType" @change="callback">
+                            <a-tab-pane key="1" tab="真人"></a-tab-pane>
+                            <a-tab-pane key="2" tab="剪辑" force-render></a-tab-pane>
+                        </a-tabs>
+                        <a-button type="primary" @click="getTemplate"  :disabled="selectedRowKeys.length==0"> 批量指派</a-button>
                          <a-table
                             size="middle"
                             :columns="columns"
                             :dataSource="data"
                             id="outTable"
+                            rowKey="id"
                             :pagination="ipagination"
                             :loading="loading"
                             @change="sort"
                             style="word-break: break-all;"
+                            :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange,getCheckboxProps:getCheckboxProps }"
                             >
                             <div slot="materialStatus" slot-scope="text" >
                                 <!-- <a-spin :spinning="record.spin" size="small" >
@@ -966,7 +974,7 @@
                                 </a-select>
                             </a-form-model-item>
                             <!-- {{currentMaterial.materialType==1?true:false}} -->
-                            <a-form-model-item  label="拍摄"  ref="shot"  prop="shot" :rules='[{ required: currentMaterial.materialType==1, message: "拍摄人员必须指派" ,trigger: "change" }]'>
+                            <a-form-model-item  label="拍摄"  ref="shot"  prop="shot" :rules="[{ required: currentMaterial.materialType==1||activeType=='1', message: '拍摄人员必须指派' ,trigger: 'change' }]">
                                 <a-select                                   
                                     v-model="formPerson.shot"
                                     showSearch
@@ -1142,6 +1150,7 @@ export default {
     },
     data() {
         return {
+            activeType:'1',
             descriptionlength:'',
             viewImgUrl:'',
             viewImgVisiable:false,
@@ -1191,7 +1200,8 @@ export default {
             userInfo:{},
             roleCode:'',
             tabKey:1,
-
+            selectedRowKeys:[],
+            selectionRows:[],
             columns:[...realColumns],
             data:[],
             loading:false,
@@ -1317,9 +1327,39 @@ export default {
 
             },
             imageinfo:[],
+            batch:false
         }
     },
     methods: {
+        getTemplate(){
+            this.batch = true
+            this.assignVisible=true;
+            this.formPerson={
+                plan:'',
+                shot:'',
+                clip:'',
+            }
+            this.currentMaterial={}
+            this.getProjectId(this.selectionRows[0].projectId)
+        },
+        onSelectChange(selectedRowKeys, selectionRows) {
+            this.selectedRowKeys = selectedRowKeys
+            this.selectionRows = selectionRows
+        },
+        getCheckboxProps(record) {
+        return {
+            props: {
+                disabled: record.materialStatus==2||record.materialStatus==3||record.materialStatus==4||record.materialStatus==5||record.materialStatus==6||record.materialStatus==7
+            },
+        }
+        },
+        //切换页签
+        callback(key) {
+            this.ipagination.current = 1
+            this.selectedRowKeys = []
+            this.selectionRows = []
+            this.materialHttp()
+        },
         //获取表单的某一个属性值
         getFormData(className) {
             return this.form.getFieldValue(className)
@@ -1451,25 +1491,47 @@ export default {
                     console.log(this.formPerson)
                     this.loadingElse=true;
                     if(this.currentMaterial.clip&&this.currentMaterial.plan&&this.currentMaterial.shot){
-                        postAction('/platform/designer/assignAgain',{
-                            id:this.currentMaterial.id,
-                            ...this.formPerson
-                        }).then(res=>{
-                            this.loadingElse=false;
-                            this.assignVisible = false;
-                            this.$message.success(res.message);
-                            this.materialHttp(this.activeKey)
-                        })
+                        
+                            postAction('/platform/designer/assignAgain',{
+                                id:this.currentMaterial.id,
+                                ...this.formPerson
+                            }).then(res=>{
+                                this.loadingElse=false;
+                                this.assignVisible = false;
+                                this.selectedRowKeys=[]
+                                this.selectionRows=[]
+                                this.$message.success(res.message);
+                                this.materialHttp(this.activeKey)
+                            })
+         
+                       
                     }else{
-                        postAction(this.url.assgin,{
-                            id:this.currentMaterial.id,
-                            ...this.formPerson
-                        }).then(res=>{
-                            this.loadingElse=false;
-                            this.assignVisible = false;
-                            this.$message.success(res.message);
-                            this.materialHttp(this.activeKey)
-                        })
+                        if(!this.batch){
+                            postAction(this.url.assgin,{
+                                id:this.currentMaterial.id,
+                                ...this.formPerson
+                            }).then(res=>{
+                                this.loadingElse=false;
+                                this.assignVisible = false;
+                                this.selectedRowKeys=[]
+                                this.selectionRows=[]
+                                this.$message.success(res.message);
+                                this.materialHttp(this.activeKey)
+                            })
+                        }else{
+                            postAction('/platform/designer/batchAssign',{
+                                id:this.selectedRowKeys,
+                                ...this.formPerson
+                            }).then(res=>{
+                                this.loadingElse=false;
+                                this.assignVisible = false;
+                                this.batch = false
+                                this.$message.success(res.message);
+                                this.materialHttp(this.activeKey)
+                                this.selectedRowKeys = []
+                                this.selectionRows = []
+                            })
+                        }
                     }
                    
                 } else {
@@ -1640,12 +1702,13 @@ export default {
             getAction(this.url.materialList,{
                 orderCode:this.currentOrderInfo.orderCode,
                 pageNo:this.ipagination.current,
-                pageSize:this.ipagination.pageSize
+                pageSize:this.ipagination.pageSize,
+                materialType:this.activeType
             }).then(res=>{
                 console.log(res);
                 this.data=[]
                 if(res.success){
-                    this.data=res.result.list;
+                    this.data=res.result.list
                     // this.data=res.result.list.filter(item=>item.materialType==this.tabKey);
                     this.ipagination.total=res.result.total
                     // this.ipagination.total=this.data.length

+ 3 - 3
src/views/modules/workBench/placeOrder.vue

@@ -294,7 +294,7 @@
                         </div>
                         <div class="input-item"> 
                             <a-form-model-item ref="materialAmount"  prop="materialAmount">
-                                <a-input-number :min="1" :max="500"  @change="materialAmountChange" v-model="form.materialAmount" />
+                                <a-input-number :min="1" :max="99"  @change="materialAmountChange" v-model="form.materialAmount" />
                             </a-form-model-item>
                         </div>
                     </div>
@@ -335,7 +335,7 @@
                         </div>
                         <div class="input-item"> 
                             <a-form-model-item ref="realAmount"  prop="realAmount">
-                                 <a-input-number :min="1" :max="500"  @change="realAmountChange" v-model="form.realAmount" />
+                                 <a-input-number :min="1" :max="99"  @change="realAmountChange" v-model="form.realAmount" />
                             </a-form-model-item>
                         </div>
                     </div>
@@ -347,7 +347,7 @@
                         </div>
                         <div class="input-item"> 
                             <a-form-model-item ref="cutAmount"  prop="cutAmount">
-                                 <a-input-number :min="1" :max="500"  @change="cutAmountChange" v-model="form.cutAmount" />
+                                 <a-input-number :min="1" :max="99"  @change="cutAmountChange" v-model="form.cutAmount" />
                             </a-form-model-item>
                         </div>
                     </div>

+ 17 - 6
src/views/system/modules/UserModal.vue

@@ -312,6 +312,13 @@ export default {
       this.userId = ''
     },
     add() {
+      this.disableSubmit = false
+      this.selectedRole = ''
+      this.userDepartModel = { userId: '', departIdList: [] }
+      this.checkedDepartNames = []
+      this.checkedDepartNameString = ''
+      this.checkedDepartKeys = []
+      this.selectedDepartKeys = []
       this.picUrl = ''
       this.refresh()
       this.edit({ activitiSync: '1' })
@@ -377,10 +384,11 @@ export default {
     moment,
     handleSubmit() {
       const that = this
+      that.confirmLoading = true
       // 触发表单验证
       this.form.validateFields((err, values) => {
         if (!err) {
-          that.confirmLoading = true
+          
           let avatar = that.model.avatar
           if (!values.birthday) {
             values.birthday = ''
@@ -408,17 +416,20 @@ export default {
               if (res.success) {
                 that.$message.success(res.message)
                 that.$emit('ok')
-                that.close()
+                // that.close()
+                that.visible = false
+                that.confirmLoading = false
               } else {
                 that.$message.warning(res.message)
               }
             })
             .finally(() => {
-              that.confirmLoading = false
-              that.checkedDepartNames = []
-              that.userDepartModel.departIdList = { userId: '', departIdList: [] }
-              that.close()
+              
+             
+              
             })
+        }else{
+          that.confirmLoading = false
         }
       })
     },

+ 3 - 3
vue.config.js

@@ -75,18 +75,18 @@ module.exports = {
         // target: 'http://192.168.2.115:8080', //请求本地 需要jeecg-boot后台项目  祚云
         // target: 'http://192.168.1.43:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.1.43:8088', //请求本地 需要jeecg-boot后台项目  毕洁泉
-        // target: 'http://192.168.1.43:8087', //请求本地 需要jeecg-boot后台项目  毕洁泉
+        target: 'http://192.168.1.43:8806', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.0.252:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.1.219:8080', //请求本地 需要jeecg-boot后台项目  赵西安
         // target: 'http://192.168.1.193:8080', //请求本地 需要jeecg-boot后台项目  李煜一
         // target: 'http://192.168.1.193:31012', //请求本地 需要jeecg-boot后台项目  李煜一
-         target: 'http://api.tjyourong.com.cn', //请求本地 需要jeecg-boot后台项目
+        //  target: 'http://api.tjyourong.com.cn', //请求本地 需要jeecg-boot后台项目
         // target: 'https://trac.tjyourong.com.cn', //请求本地 需要jeecg-boot后台项目
         // target: 'http://39.106.184.70:8088/', //请求本地 需要jeecg-boot后台项目
         //  target: 'http://adsp.tjyourong.com.cn/', //请求本地 需要jeecg-boot后台项目
         // target: 'http://192.168.1.251/', //请求本地 需要jeecg-boot后台项目
         // target:'http://118.24.244.213:8804',
-      //  target:'http://139.186.151.174:8804', //测试
+      //  target:'http://139.186.165.84:8806', //测试
 
         ws: false,