Explorar o código

拉取代码,素材大盘上测试

朱鑫波 %!s(int64=4) %!d(string=hai) anos
pai
achega
7fff6aece5

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

@@ -0,0 +1,498 @@
+<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 span {
+  display: inline-block;
+  width: 85px;
+}
+</style>
+<template>
+  <a-row :gutter="10">
+    <a-spin :spinning="spinning">
+      <a-col :sm="6" style="margin-bottom: 20px; z-index: 10">
+        <a-card class="search-box" style="min-height: 500px" v-if="materialInfo">
+          <video class="video" :src="materialInfo.url" controls="controls" style="width: 100%">
+            您的浏览器不支持 video 标签。
+          </video>
+        </a-card>
+      </a-col>
+      <a-col :sm="18" style="margin-bottom: 20px; z-index: 10">
+        <a-card class="search-box info-detail" style="min-height: 300px" v-if="materialInfo">
+          <a-descriptions title="视频信息">
+            <a-descriptions-item label="素材标题" :span="3"> {{ materialInfo.materialName }} </a-descriptions-item>
+            <a-descriptions-item label="素材ID"> {{ materialInfo.materialId }} </a-descriptions-item>
+            <a-descriptions-item label="上线时间"> {{ materialInfo.createTime.split(' ')[0] }} </a-descriptions-item>
+            <a-descriptions-item label="素材类型">
+              {{ materialInfo.materialType == '' ? '无' : materialInfo.materialType }}
+            </a-descriptions-item>
+            <a-descriptions-item label="视频时长"> {{ materialInfo.second }}s </a-descriptions-item>
+            <a-descriptions-item label="视频大小">
+              {{ materialInfo.size }}
+            </a-descriptions-item>
+            <a-descriptions-item label="视频尺寸">
+              {{ 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 }}
+            </a-descriptions-item>
+            <a-descriptions-item label="拍摄">
+              {{ materialInfo.shotName == '' ? '无' : materialInfo.shotName }}
+            </a-descriptions-item>
+            <a-descriptions-item label="剪辑">
+              {{ materialInfo.clipName == '' ? '无' : materialInfo.clipName }}
+            </a-descriptions-item>
+          </a-descriptions>
+        </a-card>
+        <a-card
+          class="search-box"
+          style="min-height: 300px; margin: 20px 0"
+          title="数据概览"
+          v-if="dataView && $route.query.mediaId == 2"
+        >
+          <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
+          class="search-box"
+          style="min-height: 300px; margin: 20px 0"
+          title="数据概览"
+          v-if="dataView && $route.query.mediaId == 1"
+        >
+          <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 class="search-box" style="min-height: 300px" title="数据消耗趋势">
+          <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 {
+      materialInfo: null,
+      dataView: null,
+      clientWidth: 1920,
+      spinning: false,
+    }
+  },
+  components: {
+    UploadToAli,
+    uploadFile,
+  },
+  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: [
+          {
+            name: '消耗',
+            type: 'line',
+            stack: '总量',
+            data: data.map((item) => {
+              return item.cost.toFixed(3)
+            }),
+            symbol: 'circle',
+            symbolSize: 1,
+            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()
+        })
+      }
+    },
+    getMaterialInfo() {
+      this.spinning = true
+      var params = {
+        mediaId: this.$route.query.mediaId,
+        md5: this.$route.query.md5,
+      }
+      var data = []
+      this.postDataAction('/overView/materialDetailInfo', params).then((res) => {
+        if (res.success) {
+          this.materialInfo = res.result
+          
+        }
+      })
+      this.postDataAction('/overView/materialDetailAnalyse', params).then((res) => {
+        if (res.success) {
+          this.dataView = res.result
+           this.spinning = false
+        }
+      })
+      this.postDataAction('/overView/materialDetailChat', params).then((res) => {
+        if (res.success) {
+          this.initEchart('echartCircular', this.handlerEchartOption(res.result))
+          
+        }
+      })
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.clientWidth = document.documentElement.clientWidth - 224
+      //   this.$route.query.mediaId
+      //   this.$route.query.md5
+      this.getMaterialInfo()
+    })
+  },
+  created() {
+    
+  },
+}
+</script>

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

@@ -0,0 +1,680 @@
+<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>素材ID</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="loading">搜索</a-button>
+          <a-button @click="resetSubmit" style="margin-left: 15px" :loading="loading">重置</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">导出报表</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" />
+            </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: 200,
+    fixed: 'left',
+  },
+  {
+    title: '素材名称',
+    dataIndex: 'materialName',
+    align: 'center',
+    width: 200,
+    fixed: 'left',
+    customRender: function (text) {
+      if (text) {
+        return text
+      } else {
+        return '-'
+      }
+    },
+  },
+  {
+    title: '所属项目',
+    dataIndex: 'projectName',
+    align: 'center',
+    width: 200,
+    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 {
+      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: 1000,
+      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) => {
+            this.$router.push({
+              path: '/materialReport/marterialDetail?md5=' + record.signature + '&mediaId=2',
+            })
+          },
+        },
+      }
+    },
+    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) {
+            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 = 200
+            element.fixed = 'left'
+          }
+        })
+
+        this.scrollX = 1000 + 200 * (this.columns.length - this.columnsFixd.length)
+      } else {
+        this.scrollX = 0
+        this.columns.forEach((element) => {
+          element.width = 'auto'
+          element.fixed = false
+        })
+      }
+    },
+    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
+        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.spinning = true
+      this.ipagination.current = 1
+      this.getData()
+    },
+    resetSubmit() {
+      this.dateValue = [moment().subtract(7, 'days'), moment()]
+      this.dataDimension = 'a'
+      this.mediaDimension = 'b'
+      this.dataDimensionValue = []
+      this.ipagination.current = 1
+      this.md5 = ''
+      this.getData()
+    },
+    //导出报表
+    exportExcel() {
+      
+      let column = this.columns.map((item, index) => {
+        return item.dataIndex
+      })
+      let columns = column.splice(3)
+      
+      downFilePost('/ctop/kuaishou/dailyPage/report/excel', {
+        mediaId: this.mediaId,
+        discount: this.discount,
+        accountIds: this.accountId,
+        startDate: this.dateValue[0].format('YYYY-MM-DD'),
+        endDate: this.dateValue[1].format('YYYY-MM-DD'),
+        hour: this.timeSelectValue,
+        target: this.target,
+        order: this.order,
+        columns,
+      }).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 = moment().format('YYYY-MM-DD') + '账户报表.xlsx' //下载后文件名
+        document.body.appendChild(downloadElement)
+        downloadElement.click() //点击下载
+        document.body.removeChild(downloadElement) //下载完成移除元素
+        window.URL.revokeObjectURL(href) //释放掉blob对象
+      })
+    },
+    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.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>

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

@@ -0,0 +1,633 @@
+<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>素材ID</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="spinning">搜索</a-button>
+          <a-button @click="resetSubmit" style="margin-left: 15px" :loading="spinning">重置</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">导出报表</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" />
+            </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: 200,
+    fixed: 'left',
+  },
+  {
+    title: '素材名称',
+    dataIndex: 'materialName',
+    align: 'center',
+    width: 200,
+    fixed: 'left',
+    customRender: function (text) {
+      if (text) {
+        return text
+      } else {
+        return '-'
+      }
+    },
+  },
+  {
+    title: '所属项目',
+    dataIndex: 'projectName',
+    align: 'center',
+    width: 200,
+    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,
+      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: 1000,
+      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) => {
+            this.$router.push({
+              path: '/materialReport/marterialDetail?md5=' + record.signature + '&mediaId=1',
+            })
+          },
+        },
+      }
+    },
+
+    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) {
+            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 = 200
+            element.fixed = 'left'
+          }
+        })
+
+        this.scrollX = 1000 + 200 * (this.columns.length - this.columnsFixd.length)
+      } else {
+        this.scrollX = 0
+        this.columns.forEach((element) => {
+          element.width = 'auto'
+          element.fixed = false
+        })
+      }
+    },
+    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
+        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.ipagination.current = 1
+      this.getData()
+    },
+    resetSubmit() {
+      this.dateValue = [moment().subtract(7, 'days'), moment()]
+      this.dataDimension = 'a'
+      this.mediaDimension = 'b'
+      this.dataDimensionValue = []
+      this.ipagination.current = 1
+      this.md5 = ''
+      this.getData()
+    },
+    //导出报表
+    exportExcel() {
+      let column = this.columns.map((item, index) => {
+        return item.dataIndex
+      })
+      let columns = column.splice(3)
+      // console.log(columns)
+      downFilePost('/ctop/kuaishou/dailyPage/report/excel', {
+        mediaId: this.mediaId,
+        discount: this.discount,
+        accountIds: this.accountId,
+        startDate: this.dateValue[0].format('YYYY-MM-DD'),
+        endDate: this.dateValue[1].format('YYYY-MM-DD'),
+        hour: this.timeSelectValue,
+        target: this.target,
+        order: this.order,
+        columns,
+      }).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 = moment().format('YYYY-MM-DD') + '账户报表.xlsx' //下载后文件名
+        document.body.appendChild(downloadElement)
+        downloadElement.click() //点击下载
+        document.body.removeChild(downloadElement) //下载完成移除元素
+        window.URL.revokeObjectURL(href) //释放掉blob对象
+      })
+    },
+    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.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>

+ 227 - 107
src/views/modules/Statistics/materialReport/materialReport.vue

@@ -86,6 +86,9 @@
               showSearch
               :filterOption="filterOption"
             >
+              <a-select-option value="no" disabled v-if="dataDimensionList.length==0&&specificLoading">
+                数据请求中,请稍后。。。
+              </a-select-option>
               <a-select-option v-for="(item, index) in dataDimensionList" :key="index" :value="item.projectId">
                 {{ item.projectName }}
               </a-select-option>
@@ -94,8 +97,10 @@
         </div>
 
         <div class="item" style="float: right">
-          <a-button @click="handleSubmit" type="primary" :loading="spinning">搜索</a-button>
-          <a-button @click="handleSubmit" style="margin-left: 15px" :loading="spinning">重置</a-button>
+          <a-button @click="handleSubmit" type="primary" :loading="spinning" :disabled="dateValue.length == 0"
+            >搜索</a-button
+          >
+          <a-button @click="resetSubmit" style="margin-left: 15px" :loading="spinning">重置</a-button>
         </div>
       </div>
     </div>
@@ -113,7 +118,7 @@
             </trend> -->
               <trend :flag="costLink > 0 ? 'up' : 'down'">
                 <span slot="term">环比</span>
-                {{ costLink * 100 }}%
+                {{ (costLink * 100).toFixed(2) }}%
               </trend>
             </div>
             <!-- <template slot="footer">
@@ -176,14 +181,21 @@
         </a-col>
       </a-row>
 
-      <a-row :gutter="24" style="margin-top: 20px">
+      <a-row :gutter="24" style="margin-top: 20px" id="getWidth">
         <a-col :xl="18">
           <a-card title="数据趋势" style="width: 100%" :bordered="false">
             <div class="echart">
               <div class="echartBody">
-                <div id="echart" ref="echart" style="width: 100%; height: 350px">
-                  <!-- <a-empty style="position: relative; top: 50%; margin-top: -65px" /> -->
-                </div>
+                <div
+                  id="echart"
+                  ref="echart"
+                  style="height: 350px"
+                  :style="{ width: (clientWidth / 24) * 18 - 48 - 24 + 'px' }"
+                ></div>
+                <a-empty
+                  style="width: 100%; height: 350px; position: absolute; top: 30%; z-index: 100; left: 0"
+                  v-if="chartList.length == 0"
+                />
               </div>
             </div>
           </a-card>
@@ -192,7 +204,12 @@
           <a-card title="标签占比" style="width: 100%" :bordered="false">
             <div class="echart">
               <div class="echartBody">
-                <div id="echartCircular" ref="echartCircular" style="width: 100%; height: 350px">
+                <div
+                  id="echartCircular"
+                  ref="echartCircular"
+                  style="height: 350px"
+                  :style="{ width: (clientWidth / 24) * 6 - 48 - 24 + 'px' }"
+                >
                   <!-- <a-empty style="position: relative; top: 50%; margin-top: -65px" /> -->
                 </div>
               </div>
@@ -203,9 +220,9 @@
 
       <a-row :gutter="24" style="margin-top: 20px">
         <a-col :xl="12">
-          <a-card title="top素材排行榜" style="width: 100%; min-height: 600px" :bordered="false">
-            <a slot="extra" href="#">查看更多</a>
-            <ul class="top-ul-style">
+          <a-card title="top素材排行榜" style="width: 100%; min-height: 700px" :bordered="false">
+            <a slot="extra" @click="getMoreVideoList">查看更多</a>
+            <ul class="top-ul-style" v-if="videoList.length > 0">
               <li v-for="(item, index) in videoList" :key="index">
                 <div style="display: flex; position: relative; width: 80%">
                   <span style="position: absolute; top: 50%; width: 40px; height: 40px; margin-top: -20px"
@@ -219,32 +236,48 @@
                       videoUrlShow = item.url
                     "
                   >
-                    <img :src="item.coverUrl||noImg" style="width: auto; height: 100%" alt="" srcset="" />
+                    <img
+                      :src="item.coverUrl || noImg"
+                      style="width: auto; height: 100%; max-width: 100%"
+                      alt=""
+                      srcset=""
+                    />
                   </div>
-                  <div style="display: flex; flex-flow: column; justify-content: space-between">
-                    <p style="margin-left: 10px">{{ item.materialName?item.materialName:'无素材名称' }}</p>
-                    <p style="margin-left: 10px;margin-bottom:0" v-if="item.tag">
-                      <a-tag v-for="(items,index) in item.tag.split(',')" :key="index" style="margin-right:5px">{{items}}</a-tag>
+                  <div
+                    style="display: flex; flex-flow: column; justify-content: space-between; width: 60%"
+                    @click.stop="toDetail(item.signature)"
+                  >
+                    <p style="margin-left: 10px">{{ item.materialName ? item.materialName : '无素材名称' }}</p>
+                    <p style="margin-left: 10px; margin-bottom: 0" v-if="item.tag">
+                      <a-tag v-for="(items, index) in item.tag.split(',')" :key="index" style="margin-right: 5px">{{
+                        items
+                      }}</a-tag>
                     </p>
                   </div>
                 </div>
                 <div class="li-cost">
                   <span>消耗</span>
-                  <span>{{ (item.charge?item.charge:item.cost) | decimalsHandle }}</span>
+                  <span>{{ (item.charge ? item.charge : item.cost) | decimalsHandle }}</span>
                 </div>
               </li>
             </ul>
+            <a-empty v-else style="margin-top: 20%" />
           </a-card>
         </a-col>
         <a-col :xl="12">
-          <a-card title="top设计排行榜" style="width: 100%; min-height: 600px" :bordered="false">
-            <ul class="top-ul-style">
-              <li>card content</li>
-              <li>card content</li>
-              <li>card content</li>
-              <li>card content</li>
-              <li>card content</li>
-            </ul>
+          <a-card title="top设计排行榜" style="width: 100%; min-height: 700px" :bordered="false">
+            <a-table
+              :columns="columns"
+              :data-source="designTopList"
+              bordered
+              size="middle"
+              :scroll="{ y: 600 }"
+              :pagination="ipagination"
+              :loading="designTopLoading"
+              @change="sort"
+            >
+              <span slot="cost" slot-scope="text, records">{{ text | decimalsHandle }}</span>
+            </a-table>
           </a-card>
         </a-col>
       </a-row>
@@ -270,36 +303,28 @@ var echarts = require('echarts')
 const columnsFixd = [
   {
     title: '排名',
-    dataIndex: 'date',
-    scopedSlots: { customRender: 'date' },
+    dataIndex: 'rowNumber',
+    scopedSlots: { customRender: 'rowNumber' },
     align: 'center',
     key: 'date',
   },
   {
     title: '设计人员',
-    dataIndex: 'accountId',
+    dataIndex: 'userName',
     align: 'center',
-    scopedSlots: { customRender: 'accountId' },
+    scopedSlots: { customRender: 'userName' },
   },
   {
     title: '角色',
-    dataIndex: 'authName',
+    dataIndex: 'roleName',
     align: 'center',
   },
   {
-    title: '消耗',
+    title: '消耗(元)',
     dataIndex: 'cost',
     align: 'center',
-  },
-  {
-    title: '有效视频',
-    dataIndex: 'valid',
-    align: 'center',
-  },
-  {
-    title: '爆款视频',
-    dataIndex: 'authName',
-    align: 'hot',
+    scopedSlots: { customRender: 'cost' },
+    sorter: () => {},
   },
 ]
 export default {
@@ -310,7 +335,8 @@ export default {
   },
   data() {
     return {
-      noImg:require('@/assets/noImg.png'),
+      designTopLoading: false,
+      noImg: require('@/assets/noImg.png'),
       visibleVideo: false,
       videoUrlShow: '',
       cost: '0',
@@ -321,8 +347,10 @@ export default {
       xiaoTotal: '0',
       spinning: false,
       loading: false,
+      chartList: [],
       videoList: [],
-      column: [...columnsFixd], //table的表头
+      designTopList: [],
+      columns: [...columnsFixd], //table的表头
       columnsFixd,
       ipagination: {
         current: 1,
@@ -332,8 +360,8 @@ export default {
           return range[0] + '-' + range[1] + ' 共' + total + '条'
         },
         showQuickJumper: true,
-        showSizeChanger: true,
-        pageSizeOptions: ['10', '30', '50'],
+        // showSizeChanger: true,
+        // pageSizeOptions: ['10', '30', '50'],
         total: 0,
         onChange: (current, pageSize) => {
           // 切换分页时的回调,
@@ -357,6 +385,9 @@ export default {
       dataDimensionValue: [],
       dataDimensionList: [],
       specificLoading: false,
+      order: 'descend',
+      target: 'cost',
+      clientWidth: 0,
     }
   },
   watch: {
@@ -366,20 +397,35 @@ export default {
         closeAllVideoFun()
       }
     },
+    'ipagination.current': function (n, o) {
+      if (n != o) {
+        this.getDesignTopList()
+      }
+    },
   },
   methods: {
     ...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.getDesignTopList({ target: sorter.columnKey, order: sorter.order ? sorter.order : 'descend' })
+      }
+    },
     getData() {
       this.spinning = true
+      this.initEchart('echartCircular', this.handlerAgeOption([]))
       Promise.all([
-        this.getProjectList(),
         this.getSumData(),
         this.getChartDataList(),
         this.getVideoTopList(),
-        // this.getDesignTopList(),
+        this.getDesignTopList({ target: 'cost', order: 'descend' }),
         // this.getTagProportionAnalyseList(),
       ])
         .then((res) => {
@@ -422,12 +468,12 @@ export default {
           })
           .then((res) => {
             if (res.success) {
-              this.cost = res.result.cost ? res.result.cost : 0
-              this.videoTotal = res.result.video ? res.result.video : 0
-              this.hotTotal = res.result.hot ? res.result.hot : 0
-              this.xiaoTotal = res.result.valid ? res.result.valid : 0
-              this.costLink = res.result.costLink ? res.result.costLink : 0
-              this.newVideo = res.result.newVideo ? res.result.newVideo : 0
+              this.cost = res.result.cost ? res.result.cost : '0'
+              this.videoTotal = res.result.video ? res.result.video : '0'
+              this.hotTotal = res.result.hot ? res.result.hot : '0'
+              this.xiaoTotal = res.result.valid ? res.result.valid : '0'
+              this.costLink = res.result.costLink ? res.result.costLink : '0'
+              this.newVideo = res.result.newVideo ? res.result.newVideo : '0'
               resolve(res.result)
             } else {
               reject(res.message)
@@ -444,7 +490,14 @@ export default {
           projects: this.dataDimensionValue,
         }).then((res) => {
           if (res.success) {
-            this.initEchart('echart', this.handlerEchartOption(res.result))
+            this.chartList = res.result
+            if (res.result.length == 0) {
+              const myChart = echarts.init(document.getElementById('echart'))
+              myChart.dispose()
+            } else {
+              this.initEchart('echart', this.handlerEchartOption(res.result))
+            }
+
             resolve(res.result)
           } else {
             reject(res.message)
@@ -470,17 +523,75 @@ export default {
         })
       })
     },
-    getDesignTopList() {
+    getMoreVideoList() {
+      // this.postDataAction('/overView/materialTopViewMore', {
+      //   mediaId: this.mediaDimension == 'a' ? 1 : 2,
+      //   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,
+      //   projects: this.dataDimensionValue,
+      //   channelType: null,
+      //   md5: null,
+      //   target: null,
+      //   order: null,
+      //   pageSize: '5',
+      //   pageNo: '1',
+      // }).then((res) => {
+      //   console.log(res)
+      // })
+      var params = {
+        mediaId: this.mediaDimension == 'a' ? 1 : 2,
+        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,
+        projects: this.dataDimensionValue,
+      }
+      params = JSON.stringify(params)
+      localStorage.setItem('materialParams', params)
+      if (this.mediaDimension == 'a') {
+        this.$router.push({ path: '/materialReport/marterialTtList' })
+      } else {
+        this.$router.push({ path: '/materialReport/marterialList' })
+      }
+    },
+    toDetail(md5) {
+      // /materialReport/marterialDetail
+      this.$router.push({
+        path: '/materialReport/marterialDetail?md5=' + md5 + '&mediaId=' + (this.mediaDimension == 'a' ? 1 : 2),
+      })
+    },
+    getDesignTopList(data) {
+      this.designTopLoading = true
       return new Promise((resolve, reject) => {
-        this.postDataAction('/overView/designTop', {
-          mediaId: this.mediaDimension == 'a' ? 1 : 2,
-          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,
-          projects: this.dataDimensionValue,
-          pageSize: '5',
-          pageNo: '1',
-        }).then((res) => {
+        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)
@@ -508,45 +619,23 @@ export default {
     },
 
     handleSubmit() {
+      this.ipagination.current = 1
       this.getData()
     },
-    //导出报表
-    exportExcel() {
-      console.log('触发导出事件')
-      let column = this.columns.map((item, index) => {
-        return item.dataIndex
-      })
-      let columns = column.splice(3)
-      // console.log(columns)
-      downFilePost('/ctop/kuaishou/dailyPage/report/excel', {
-        mediaId: this.mediaId,
-        discount: this.discount,
-        accountIds: this.accountId,
-        startDate: this.dateValue[0].format('YYYY-MM-DD'),
-        endDate: this.dateValue[1].format('YYYY-MM-DD'),
-        hour: this.timeSelectValue,
-        target: this.target,
-        order: this.order,
-        columns,
-      }).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 = moment().format('YYYY-MM-DD') + '账户报表.xlsx' //下载后文件名
-        document.body.appendChild(downloadElement)
-        downloadElement.click() //点击下载
-        document.body.removeChild(downloadElement) //下载完成移除元素
-        window.URL.revokeObjectURL(href) //释放掉blob对象
-      })
+    resetSubmit() {
+      this.dateValue = [moment().subtract(7, 'days'), moment()]
+      this.dataDimension = 'a'
+      this.mediaDimension = 'b'
+      this.dataDimensionValue = []
+      this.ipagination.current = 1
+      this.getData()
     },
     tableChange(data) {
       console.log(data)
     },
     //获取echart的值
     initEchart(idName, optionName) {
+      var that = this
       const chart = this.$refs[idName]
       //   console.log(chart)
       if (chart) {
@@ -557,12 +646,22 @@ export default {
 
         myChart.setOption(optionName)
         window.addEventListener('resize', function () {
+          that.clientWidth = document.documentElement.clientWidth - 224
           myChart.resize()
         })
       }
     },
     handlerEchartOption(data) {
       var option = {
+        noDataLoadingOption: {
+          text: '暂无数据',
+          effect: 'bubble',
+          effectOption: {
+            effect: {
+              n: 0,
+            },
+          },
+        },
         // title: {
         //     text: '折线图堆叠'
         // },
@@ -662,7 +761,7 @@ export default {
       const colorList = ['#58D5FF', '#73ACFF', '#FDD56A', '#FDB36A', '#FD866A', '#9E87FF']
       var that = this
       var option = {
-        color: ['#37a2da', '#32c5e9', '#9fe6b8', '#ffdb5c'],
+        color: colorList,
         backgroundColor: '#fff',
 
         tooltip: {
@@ -672,6 +771,7 @@ export default {
         legend: {
           orient: 'horizontal',
           top: 'top',
+          icon: 'circle',
           width: '100%',
           data: ['形式标签', '场景标签', '基调标签', '其他'],
         },
@@ -679,7 +779,7 @@ export default {
           {
             name: '',
             type: 'pie',
-            radius: '80%',
+            radius: ['40%', '70%'],
             center: ['50%', '50%'],
             data: [
               { value: 0, name: '形式标签' },
@@ -687,16 +787,28 @@ export default {
               { value: 0, name: '场景标签' },
               { value: 0, name: '其他' },
             ],
+            labelLine: {
+              length: 5,
+              length2: 5,
+            },
+            label: {
+              show: false,
+              position: 'center',
+            },
             emphasis: {
-              itemStyle: {
-                shadowBlur: 10,
-                shadowOffsetX: 0,
-                shadowColor: 'rgba(0, 0, 0, 0.5)',
+              label: {
+                show: true,
+                fontSize: '18',
+                fontWeight: 'bold',
               },
             },
-            label: {
-              normal: {
-                show: false,
+            labelLine: {
+              show: true,
+            },
+            itemStyle: {
+              borderRadius: 5,
+              color: (params) => {
+                return colorList[params.dataIndex]
               },
             },
           },
@@ -709,18 +821,26 @@ export default {
       return current && current > moment().endOf('day')
     },
     dataDimensionChange(e) {
-      console.log(`checked = ${e.target.value}`)
+      // console.log(`checked = ${e.target.value}`)
     },
     mediaDimensionChange(e) {
-      console.log(`checked = ${e.target.value}`)
+      this.dataDimensionList = []
+      this.dataDimensionValue = []
       this.getProjectList()
     },
   },
   mounted() {
+    this.clientWidth = document.documentElement.clientWidth - 224
     this.$nextTick(() => {
+      this.getProjectList()
       this.getData()
-
-      this.initEchart('echartCircular', this.handlerAgeOption([]))
+      // this.getMoreVideoList()
+      // this.initEchart('echartCircular', this.handlerAgeOption([]))
+    })
+  },
+  activated() {
+    this.$nextTick(() => {
+      this.clientWidth = document.documentElement.clientWidth - 224
     })
   },
 }

+ 41 - 24
src/views/modules/kuaishouapp/newBatch/index.vue

@@ -1070,9 +1070,9 @@ li.chouzhen.first:before {
                     v-model="unitInfo.bidMin"
                     style="width: 60%"
                     @change="changeBidMin"
-                    :min="0"
+                    :min="1"
                     :precision="2"
-                    :max="unitInfo.dayBudget ? unitInfo.dayBudget : 999999"
+                    :max="unitInfo.dayBudget ? (unitInfo.dayBudget > 3000 ? 3000 : unitInfo.dayBudget) : 3000"
                   />
                 </a-form-model-item>
               </a-col>
@@ -1083,9 +1083,9 @@ li.chouzhen.first:before {
                     v-model="unitInfo.bidMax"
                     style="width: 53.3%"
                     @change="changeBidMax"
-                    :min="0"
+                    :min="1"
                     :precision="2"
-                    :max="unitInfo.dayBudget ? unitInfo.dayBudget : 999999"
+                    :max="unitInfo.dayBudget ? (unitInfo.dayBudget > 3000 ? 3000 : unitInfo.dayBudget) : 3000"
                   />
                 </a-form-model-item>
               </a-col>
@@ -1131,9 +1131,9 @@ li.chouzhen.first:before {
                   <a-input-number
                     v-model="unitInfo.bid"
                     style="width: 90%"
-                    :min="0"
+                    :min="0.2"
                     :precision="2"
-                    :max="unitInfo.dayBudget ? unitInfo.dayBudget : 999999"
+                    :max="unitInfo.dayBudget ? (unitInfo.dayBudget > 100 ? 100 : unitInfo.dayBudget) : 100"
                   />元
                 </a-form-model-item>
               </a-col>
@@ -1152,9 +1152,9 @@ li.chouzhen.first:before {
                     v-model="unitInfo.bidMin"
                     style="width: 60%"
                     @change="changeBidMin"
-                    :min="0"
+                    :min="0.2"
                     :precision="2"
-                    :max="unitInfo.dayBudget ? unitInfo.dayBudget : 999999"
+                    :max="unitInfo.dayBudget ? (unitInfo.dayBudget > 100 ? 100 : unitInfo.dayBudget) : 100"
                   />
                 </a-form-model-item>
               </a-col>
@@ -1165,9 +1165,9 @@ li.chouzhen.first:before {
                     v-model="unitInfo.bidMax"
                     style="width: 53.3%"
                     @change="changeBidMax"
-                    :min="0"
+                    :min="0.2"
                     :precision="2"
-                    :max="unitInfo.dayBudget ? unitInfo.dayBudget : 999999"
+                    :max="unitInfo.dayBudget ? (unitInfo.dayBudget > 100 ? 100 : unitInfo.dayBudget) : 100"
                   />
                 </a-form-model-item>
               </a-col>
@@ -3468,12 +3468,14 @@ export default {
           if (this.materialInfo.isMakeCover == 2) {
             this.getImageCover(this.materialInfo.materialList[i].photoArr[j].photoId).then((res) => {
               setTimeout(() => {
-                if (res.length > 0) {
-                  this.materialInfo.materialList[i].photoArr[j].image =
-                    res[i % 2 == 0 ? j % this.materialInfo.coverNumber : 7 - (j % this.materialInfo.coverNumber)]
-                  this.materialList[i].photoArr[j].image =
-                    res[i % 2 == 0 ? j % this.materialInfo.coverNumber : 7 - (j % this.materialInfo.coverNumber)]
-                }
+               if(res.length>=this.materialInfo.coverNumber){
+                this.materialInfo.materialList[i].photoArr[j].image =
+                  res[i % 2 == 0 ? j % this.materialInfo.coverNumber : (res.length-1) - (j % this.materialInfo.coverNumber)]
+                this.materialList[i].photoArr[j].image =
+                  res[i % 2 == 0 ? j % this.materialInfo.coverNumber : (res.length-1) - (j % this.materialInfo.coverNumber)]
+               }
+               
+              
 
                 this.checkMatemalVisible = false
               }, 100)
@@ -3510,7 +3512,12 @@ export default {
       return new Promise((resolve, reject) => {
         this.getAction('/cutFrame/material/queryByPhotoId', params).then((res) => {
           if (res.success) {
-            resolve(res.result)
+            var data = res.result.sort(function (a, b) {
+              return a.imageIndex - b.imageIndex
+            })
+            setTimeout(() => {
+              resolve(res.result)
+            })
           }
         })
       })
@@ -3826,19 +3833,29 @@ export default {
       callback()
     },
     cpaBidValue(rule, value, callback) {
-      if (value == '' || value == null) {
-        callback('请输入转化目标出价')
-      } else if (value < 5 || value > 3000) {
-        callback('转化目标出价不能低于5元,不能高于3000元,请正确输入')
+      if (this.unitInfo.ocpxActionType == 53) {
+        if (value == '' || value == null) {
+          callback('请输入转化目标出价')
+        } else if (value < 5 || value > 3000) {
+          callback('转化目标为表单数,出价不能低于5元,不能高于3000元,请正确输入')
+        } else {
+          callback()
+        }
       } else {
-        callback()
+        if (value == '' || value == null) {
+          callback('请输入转化目标出价')
+        } else if (value < 1 || value > 3000) {
+          callback('转化目标出价不能低于1元,不能高于3000元,请正确输入')
+        } else {
+          callback()
+        }
       }
     },
     bidValue(rule, value, callback) {
       if (value == '' || value == null) {
         callback('请输入出价')
-      } else if (value < 1 || value > 3000) {
-        callback('出价不能低于1元,不能高于3000元,请正确输入')
+      } else if (value < 0.2 || value > 100) {
+        callback('不得低于0.2元,不得高于100元,不得高于组预算')
       } else {
         callback()
       }

+ 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
         }
       })
     },

+ 2 - 2
vue.config.js

@@ -74,7 +74,7 @@ module.exports = {
         // target: 'http://192.168.1.188:8088', //请求本地 需要jeecg-boot后台项目  英豪
         // 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:8088', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.1.43:8087', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.0.252:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.1.219:8080', //请求本地 需要jeecg-boot后台项目  赵西安
@@ -86,7 +86,7 @@ module.exports = {
         //  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.151.174:8804', //测试
 
         ws: false,