xushengqiang@efunbox.cn 3 роки тому
батько
коміт
f38990032b

+ 61 - 0
src/api/reader.js

@@ -0,0 +1,61 @@
+import axios from 'axios'
+import { Message, MessageBox } from 'element-ui'
+
+// 创建axios实例
+const service = axios.create({
+  baseURL: process.env.SKILL_API, // api 的 base_url
+  timeout: 5000 // 请求超时时间
+})
+
+// request拦截器
+service.interceptors.request.use(
+  config => {
+    if (localStorage.getItem('token')) {
+      config.headers['token'] = localStorage.getItem('token'); // 让每个请求携带自定义token 请根据实际情况自行修改
+    }
+    return config
+  },
+  error => {
+    // Do something with request error
+    console.log(error) // for debug
+    Promise.reject(error)
+  }
+)
+
+// response 拦截器
+service.interceptors.response.use(
+  response => {
+    /**
+     * code为非200是抛错 可结合自己业务进行修改
+     */
+    const res = response.data
+    if (res.code !== 200) {
+      Message({
+        message: res.message,
+        type: 'error',
+        duration: 5 * 1000
+      })
+    } else {
+      return response.data
+    }
+  },
+  error => {
+    console.log('err' + error) // for debug
+    Message({
+      message: error.message,
+      type: 'error',
+      duration: 5 * 1000
+    })
+    return Promise.reject(error)
+  }
+)
+
+
+export function getReaderData(params) {
+  return service({
+    url: 'https://reader-xiaoai-api.ai160.com/statistics/userView',
+    method: 'get',
+    params
+  })
+}
+

+ 3 - 0
src/pages/layout/leftnav/LeftNav.vue

@@ -43,6 +43,9 @@
       <el-menu-item index="/baidu/index" route="/baidu/index">
         <span slot="title">小度-技能</span>
       </el-menu-item>
+      <el-menu-item index="/reader/index" route="/reader/index">
+        <span slot="title">朗读配音</span>
+      </el-menu-item>
     </el-menu>
   </div>
 </template>

+ 382 - 0
src/pages/reader/index.vue

@@ -0,0 +1,382 @@
+<template>
+  <div>
+    <el-card>
+      <el-form :model="skillParams" ref="skillParams" class="clearfix topForm" style="float: left">
+        <div class="leftForm-skill">
+          <el-form-item
+            class="pruductForm-skill"
+            prop="channel"
+            label="渠道选择"
+            :rules="[{ required: true, message: '请选择渠道', trigger: 'blur' }]"
+          >
+            <el-select v-model="skillParams.channel" placeholder="请选择渠道" @change="skillChange" style="width:160px">
+              <el-option key="2016" label="天猫精灵" value="2016" ></el-option>
+              <el-option key="3001" label="微信小程序" value="3001" ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item class="dateForm-skill" name="data" label="查询日期" style="display:flex">
+            <el-date-picker
+              style="width:140px"
+              v-model="skillParams.startDay"
+              type="date"
+              placeholder="起"
+            ></el-date-picker>
+            <el-date-picker
+              style="width:140px"
+              v-model="skillParams.endDay"
+              type="date"
+              placeholder="止"
+            ></el-date-picker>
+          </el-form-item>
+        </div>
+        <el-form-item>
+          <el-button type="primary" @click="submitForm('skillParams')">搜索</el-button>
+        </el-form-item>
+      </el-form>
+      <el-button type="primary" @click="onExportExcel" style="float: right">导出</el-button>
+      <el-table id="table" ref="table1" :data="readerData" border style="width: 100%" :height="tableHeight" >
+        <el-table-column
+          label="日期"
+          fixed
+          align="left"
+          header-align="center"
+          min-width="140px"
+        >
+            <template slot-scope="scope">
+                <span>{{changeDate(scope.row.day)}}</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="流量与观看" header-align="center">
+          <el-table-column
+            label="UV"
+            prop="uv"
+            align="right"
+            header-align="center"
+            min-width="100px"
+          ></el-table-column>
+
+          <el-table-column
+            label="VIP用户 | -UV1"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="vipUv"
+            min-width="120px"
+          ></el-table-column>
+          <el-table-column
+            label="非VIP用户 | UV2=UV-UV1"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="waitVipUv"
+            min-width="140px"
+          ></el-table-column>
+
+          <el-table-column
+            label="VIP用户占比 | =UV1/UV"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="vipProportion"
+            min-width="140px"
+          ></el-table-column>
+          <el-table-column
+            label="VIP权限用户 | =V0"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="vipCount"
+            min-width="140px"
+          ></el-table-column>
+          <el-table-column
+            label="VIP用户活跃率 | =UV1/V0"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            min-width="140px"
+            prop="aliveVipProportion"
+          >
+          </el-table-column>
+          <!-- <el-table-column
+            label="VV"
+            prop="vv"
+            align="right"
+            header-align="center"
+            min-width="100px"
+          ></el-table-column>-->
+          <el-table-column
+            label="VV"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="vv"
+            min-width="140px"
+          ></el-table-column>
+          <el-table-column
+            label="新增用户"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="registerAmount"
+            min-width="140px"
+          ></el-table-column>
+          <el-table-column
+            label="累计用户"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="totalRegisterAmount"
+            min-width="140px"
+          ></el-table-column>
+          <el-table-column
+            label="人均播放 | =VV/UV"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="perCapitaPlay"
+            min-width="140px"
+          ></el-table-column>
+        </el-table-column>
+
+        <el-table-column label="拉新,付费与转换率" header-align="center">
+          <el-table-column
+            label="连续包月 | -Qm1"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="consecutiveMonthly"
+            min-width="100px"
+          ></el-table-column>
+          <el-table-column
+            label="新增连续包月 | -Qm1-1"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            min-width="140px"
+          >
+              <template slot-scope="scope">
+                  <span>{{scope.row.appendConsecutiveMonthly || 0}}</span>
+              </template>
+          </el-table-column>
+          <el-table-column
+            label="续包月续费 | -Qm1-2"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            min-width="140px"
+          >
+              <template slot-scope="scope">
+                  <span>{{scope.row.continueConsecutiveMonthly || 0}}</span>
+              </template>
+          </el-table-column>
+          <el-table-column
+            label="月包 | -Qm2"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="monthlyPayment"
+            min-width="90px"
+          ></el-table-column>
+          <el-table-column
+            label="年包 | -Qy"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="yearlyPayment"
+          ></el-table-column>
+          <el-table-column
+            label="付费订单数量| Q=Qm1+Qm2+Qy"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="totalPayment"
+            min-width="160px"
+          ></el-table-column>
+          <el-table-column
+            label="r1 | =Qm1/Q"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="consecutiveConversion"
+            min-width="130px"
+          ></el-table-column>// 月包占比
+          <el-table-column
+            label="r2 | =Qm2/Q"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="monthlyConversion"
+            min-width="130px"
+          ></el-table-column>// 年包占比
+          <el-table-column
+            label="r3 | =Qy/Q"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="yearlyConversion"
+            min-width="130px"
+          ></el-table-column>
+          <el-table-column
+            label="R | =(Qm1+Qm2+Qy)/UV2"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="totalConversion"
+            min-width="190px"
+          ></el-table-column>
+          <!--<el-table-column
+            label="R1 | =(Qm1-1+Qm2+Qy)/UV2"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            min-width="190px"
+          >
+              <template slot-scope="scope">
+                  <span>{{scope.row.appendTotalConversion || 0}}</span>
+              </template>
+          </el-table-column>-->
+        </el-table-column>
+      </el-table>
+    </el-card>
+  </div>
+</template>
+<script>
+import { mapGetters } from "vuex";
+import formatDate from "../../utils/formatTime";
+import {  getBaiduCourseList } from '../../api/skill'
+import downTable from '@/utils/downTable'
+export default {
+  data() {
+    return {
+      tableHeight: 500,
+      dateValue: "",
+      skillParams: {
+        startDay: "",
+        endDay: "",
+        channel: "",
+      },
+    };
+  },
+  computed: {
+    ...mapGetters({
+      readerData: "readerData"
+    })
+  },
+  created() {
+    this.$store.dispatch("clearList");
+
+    // this.$store.dispatch("getOrderList", this.skillParams);
+    this.skillParams.startDay = this.getYesterDay();
+    this.skillParams.endDay = this.getYesterDay();
+
+    this.tableHeight = document.documentElement.clientHeight * 0.75;
+  },
+  methods: {
+    // 搜索
+    submitForm(formName) {
+      this.skillParams.startDay = this.skillParams.startDay
+        ? formatDate(this.skillParams.startDay, 2)
+        : "";
+      this.skillParams.endDay = this.skillParams.endDay
+        ? formatDate(this.skillParams.endDay, 2)
+        : "";
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.$store.dispatch("getReaderData", this.skillParams);
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+      this.$refs.table1.doLayout();
+    },
+    // 渠道下课程分页
+    changePage(e) {
+      this.skillParams.pageNo = e;
+      // this.$store.dispatch("getSkillData", this.skillParams);
+    },
+
+    // 表头折行
+    renderheader(h, { column, $index }) {
+      return h("span", {}, [
+        h("span", {}, column.label.split("|")[0]),
+        h("br"),
+        h("span", {}, column.label.split("|")[1])
+      ]);
+    },
+    getYesterDay() {
+      let yesterday = new Date().getTime() - 86400000;
+      return formatDate(yesterday, 2);
+    },
+    channelChange(val) {
+      // 清空数据
+      this.$store.dispatch("clearList");
+    },
+    skillChange(val) {
+      console.log(val)
+    },
+    columnZero() {
+      return "0";
+    },
+    columnZeroPercent(row, column, index) {
+      if (row.totalPayment && column.property === "yearlyConversion") {
+        return "100.00%";
+      } else {
+        return "0.00%";
+      }
+      // if(row.)
+    },
+    changeDate(date) {
+      return formatDate(date, 4)
+    },
+    // 导出表格
+    onExportExcel() {
+        const name = '朗读配音'
+        const date = this.skillParams.startDay + '至' + this.skillParams.endDay
+        downTable('table', [
+          {wch: 15}, // "characters"
+          {wch: 6},
+          {wch: 15},
+          {wch: 20},
+          {wch: 20},
+          {wch: 6},
+          {wch: 15},
+          {wch: 15},
+          {wch: 18},
+          {wch: 18},
+          {wch: 10},
+          {wch: 15},
+          {wch: 25},
+          {wch: 10},
+          {wch: 10},
+          {wch: 10},
+          {wch: 20},
+          {wch: 25}
+        ], name + date)
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+.pruductForm-skill {
+  margin-left: 10px;
+  display: flex;
+}
+.topForm {
+  display: flex;
+  align-items: center;
+  flex-direction: row;
+  flex-shrink: 0;
+  justify-content: space-between;
+}
+.leftForm-skill {
+  display: flex;
+  align-items: center;
+  flex-direction: row;
+  justify-content: space-between;
+}
+.dateForm-skill {
+  margin-left: 18px;
+}
+</style>
+

+ 10 - 0
src/router/router.js

@@ -137,6 +137,16 @@ const router = new Router({
         component: () => import('@/pages/baidu/Skill'),
       }]
     },
+    {
+      path: '/reader',
+      component: Layout,
+      children: [{
+        path: 'index',
+        name:'reader',
+        meta: { title: '语文朗读配音', url: '/reader/index' },
+        component: () => import('@/pages/reader/index'),
+      }]
+    },
     // {
     //   path: '/course',
     //   component: Layout,

+ 3 - 0
src/store/getter.js

@@ -1,3 +1,5 @@
+import reader from "./modules/reader";
+
 const getters = {
   flag: state => state.login.flag,
   channeList: state => state.channel.channeList,
@@ -12,6 +14,7 @@ const getters = {
   efunChannelList: state => state.efun.efunChannelList,
   oppoData:state=>state.oppo.oppoData,
   xyyfData: state => state.xyyf.xyyfData,
+  readerData: state => state.reader.readerData,
 
 }
 export default getters

+ 2 - 0
src/store/index.js

@@ -11,6 +11,7 @@ import skill from './modules/skill'
 import efun from './modules/efun'
 import oppo from './modules/oppo'
 import xyyf from './modules/xyyf'
+import reader from './modules/reader'
 Vue.use(Vuex)
 
 const store = new Vuex.Store({
@@ -25,6 +26,7 @@ const store = new Vuex.Store({
     efun,
     oppo,
     xyyf,
+    reader,
   },
   getters
 })

+ 42 - 0
src/store/modules/reader.js

@@ -0,0 +1,42 @@
+import {
+  getReaderData,
+} from '../../api/reader'
+
+const reader = {
+  state: {
+    readerData: [],
+  },
+  mutations: {
+    GET_READER_DATA: (state, data) => {
+      state.readerData = data
+    },
+  },
+  actions: {
+    // 清空数据
+    clearList({
+      dispatch,
+      commit
+    }) {
+      commit('GET_READER_DATA', [])
+    },
+    getReaderData({
+      dispatch,
+      commit
+    },data) {
+      return new Promise((resolve, reject) => {
+        console.log(data)
+        getReaderData(data).then(res => {
+          console.log(res.data)
+          if (res.code == 200) {
+            resolve(res.data);
+            commit('GET_READER_DATA', res.data)
+          }
+        }).catch(error => {
+          reject(error);
+        })
+      })
+    },
+  }
+}
+
+export default reader