Explorar o código

目录结构修改

xushengqiang %!s(int64=3) %!d(string=hai) anos
pai
achega
22b99bc737

+ 67 - 0
src/api/oppo.js

@@ -0,0 +1,67 @@
+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 getOppoData (params) {
+
+    console.log(123123123,params)
+    return service({
+      url: `${process.env.OPPO_API}/statistics`,
+      method: 'get',
+      params: {
+        channelCode: params.channel,
+        startDate: params.startDate,
+        endDate: params.endDate,
+      }
+    })
+
+
+}

+ 67 - 0
src/api/xyyf.js

@@ -0,0 +1,67 @@
+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 getXyyfMobileList() {
+  return service({
+    url: 'http://m-xyyf-api.ai160.com/statistics/channel',
+    method: 'get'
+  })
+}
+export function getXyyfData(params) {
+  return service({
+    url: 'http://m-xyyf-api.ai160.com/statistics',
+    method: 'get',
+    params
+  })
+}
+

+ 431 - 0
src/pages/baidu/Skill.vue

@@ -0,0 +1,431 @@
+<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="skillId"
+            label="技能选择"
+            :rules="[{ required: true, message: '请选择技能', trigger: 'blur' }]"
+          >
+            <el-select v-model="skillParams.skillId" placeholder="请选择技能" @change="skillChange" style="width:160px">
+              <el-option
+                v-for="item in skillList"
+                :key="item.skillId || item.skillId === 0 ? item.skillId : item.id"
+                :label="item.skillName ? item.skillName : item.title"
+                :value="item.skillId || item.skillId === 0 ? item.skillId : item.id"
+              ></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.startDate"
+              type="date"
+              placeholder="起"
+            ></el-date-picker>
+            <el-date-picker
+              style="width:140px"
+              v-model="skillParams.endDate"
+              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="skillData" 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"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></el-table-column>
+          <el-table-column
+            label="VIP用户活跃率 | =UV1/V0"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            min-width="140px"
+            prop="aliveVipProportion"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          >
+          </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="fealtyCount"
+            min-width="140px"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></el-table-column>
+          <el-table-column
+            label="忠实用户占比"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="fealtyProportion"
+            min-width="140px"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></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-pagination
+      v-if="orderList.totalElements"
+      background
+      layout="prev, pager, next"
+      :total="orderList.totalElements"
+      @current-change="changePage">
+      </el-pagination>-->
+    </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: {
+        skillId: "",
+        startDate: "",
+        endDate: "",
+        channel: "",
+        classId: ""
+      },
+      channelList: "",
+      baiduCourseList: [],
+      skillList:[
+        { skillName : "小学语文",skillId : 0},
+        { skillName : "小学数学",skillId : 3},
+        { skillName : "小学一年级",skillId : 7},
+        { skillName : "小学二年级",skillId : 8},
+        { skillName : "小学三年级",skillId : 9},
+        { skillName : "小学四年级",skillId : 10},
+        { skillName : "易学拼音",skillId : 18},
+        { skillName : "动画识字",skillId : 16},
+        { skillName : "思维数学",skillId : 17},
+
+      ]
+    };
+  },
+  computed: {
+    ...mapGetters({
+      skillList: "skillList",
+      orderList: "orderList",
+      productList: "productList",
+      skillData: "skillData"
+    })
+  },
+  created() {
+    this.$store.dispatch("clearList");
+
+    // this.$store.dispatch("getOrderList", this.skillParams);
+    this.skillParams.startDate = this.getYesterDay();
+    this.skillParams.endDate = this.getYesterDay();
+
+    this.tableHeight = document.documentElement.clientHeight * 0.75;
+  },
+  methods: {
+    // 搜索
+    submitForm(formName) {
+      this.skillParams.startDate = this.skillParams.startDate
+        ? formatDate(this.skillParams.startDate, 2)
+        : "";
+      this.skillParams.endDate = this.skillParams.endDate
+        ? formatDate(this.skillParams.endDate, 2)
+        : "";
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.skillParams.channel = "BAIDU";
+          this.$store.dispatch("getSkillData", 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);
+    },
+    skillChange(val) {
+      this.skillParams.classId = ''
+      console.log(val)
+      // if (val === 0) {
+      //   getBaiduCourseList('CHINESE').then(res => {
+      //     this.baiduCourseList = [{
+      //       fullName: '全部',
+      //       id: 100
+      //     }, ...res.data]
+      //   })
+      // } else if (val === 3) {
+      //   getBaiduCourseList('MATH').then(res => {
+      //      this.baiduCourseList = [{
+      //       fullName: '全部',
+      //       id: 101
+      //     }, ...res.data]
+      //   })
+      // }
+    },
+    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 list = this.skillList.filter((item) => item.skillId === this.skillParams.skillId)[0] || ''
+        const productName = list && list.skillName ? '-' + list.skillName : ''
+        const date = this.skillParams.startDate + '至' + this.skillParams.endDate
+        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 + productName + 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>
+

+ 14 - 14
src/pages/layout/leftnav/LeftNav.vue

@@ -7,15 +7,6 @@
       active-text-color="#20a0ff"
       :router=true
       :default-active="$route.path">
-      <!-- <el-menu-item index="/channel/index" route="/channel/index">
-        <span slot="title">渠道管理</span>
-      </el-menu-item>
-      <el-menu-item index="/course/index" route="/course/index">
-        <span slot="title">课程管理</span>
-      </el-menu-item>
-      <el-menu-item index="/relation/index" route="/relation/index">
-          <span slot="title">渠道课程管理</span>
-      </el-menu-item> -->
       <el-menu-item index="/soundBox/index" route="/soundBox/index">
         <span slot="title">学有义方-音箱</span>
       </el-menu-item>
@@ -28,9 +19,9 @@
       <el-menu-item index="/order/index" route="/order/index">
           <span slot="title">TV-联运</span>
       </el-menu-item>
-      <el-menu-item index="/skill/index" route="/skill/index">
+    <!--  <el-menu-item index="/skill/index" route="/skill/index">
         <span slot="title">智能语音</span>
-      </el-menu-item>
+      </el-menu-item>-->
       <el-menu-item index="/tv/index" route="/tv/index">
         <span slot="title">TV-快乐学堂8.0</span>
       </el-menu-item>
@@ -40,9 +31,18 @@
       <el-menu-item index="/skill/yey" route="/skill/yey">
         <span slot="title">爱上幼儿园</span>
       </el-menu-item>
-      <!-- <el-menu-item index="/operation/index" route="/operation/index">
-          <span slot="title">操作日志</span>
-      </el-menu-item> -->
+      <el-menu-item index="/skill/xqb" route="/skill/xqb">
+        <span slot="title">学前领先班</span>
+      </el-menu-item>
+      <el-menu-item index="/skill/xxms" route="/skill/xxms">
+        <span slot="title">小学名师优课</span>
+      </el-menu-item>
+      <el-menu-item index="/oppo/index" route="/oppo/index">
+        <span slot="title">OPPO-同步辅导</span>
+      </el-menu-item>
+      <el-menu-item index="/baidu/index" route="/baidu/index">
+        <span slot="title">小度在家</span>
+      </el-menu-item>
     </el-menu>
   </div>
 </template>

+ 1 - 0
src/pages/mobile/Mobile.vue

@@ -217,6 +217,7 @@ export default {
     })
   },
   created() {
+    this.$store.dispatch("clearList");
     this.$store.dispatch("getEfunChannelList",'PHONE');
     this.efunParams.startDate = this.getYesterDay();
     this.efunParams.endDate = this.getYesterDay();

+ 396 - 0
src/pages/oppo/xxtbfd.vue

@@ -0,0 +1,396 @@
+<template>
+  <div>
+    <el-card>
+      <el-form :model="skillParams" ref="skillParams" class="clearfix topForm" style="float: left">
+        <div class="leftForm-skill">
+          <el-form-item class="dateForm-skill" name="data" label="查询日期" style="display:flex">
+            <el-date-picker
+              style="width:140px"
+              v-model="skillParams.startDate"
+              type="date"
+              placeholder="起"
+            ></el-date-picker>
+            <el-date-picker
+              style="width:140px"
+              v-model="skillParams.endDate"
+              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="skillData" 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"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></el-table-column>
+          <el-table-column
+            label="VIP用户活跃率 | =UV1/V0"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            min-width="140px"
+            prop="aliveVipProportion"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          >
+          </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="fealtyCount"
+            min-width="140px"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></el-table-column>
+          <el-table-column
+            label="忠实用户占比"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="fealtyProportion"
+            min-width="140px"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></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-pagination
+      v-if="orderList.totalElements"
+      background
+      layout="prev, pager, next"
+      :total="orderList.totalElements"
+      @current-change="changePage">
+      </el-pagination>-->
+    </el-card>
+  </div>
+</template>
+<script>
+import { mapGetters } from "vuex";
+import formatDate from "../../utils/formatTime";
+import downTable from '@/utils/downTable'
+export default {
+  data() {
+    return {
+      tableHeight: 500,
+      dateValue: "",
+      skillParams: {
+        skillId: "",
+        startDate: "",
+        endDate: "",
+        channel: "",
+        classId: ""
+      },
+      channelList: "",
+    };
+  },
+  computed: {
+    ...mapGetters({
+      skillData: "oppoData"
+    })
+  },
+  created() {
+    // this.$store.dispatch("getOrderList", this.skillParams);
+    this.skillParams.startDate = this.getYesterDay();
+    this.skillParams.endDate = this.getYesterDay();
+
+    this.tableHeight = document.documentElement.clientHeight * 0.75;
+  },
+  methods: {
+    // 搜索
+    submitForm(formName) {
+      this.skillParams.startDate = this.skillParams.startDate
+        ? formatDate(this.skillParams.startDate, 2)
+        : "";
+      this.skillParams.endDate = this.skillParams.endDate
+        ? formatDate(this.skillParams.endDate, 2)
+        : "";
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.skillParams.channel = "6001";
+          this.$store.dispatch("getOppoData", this.skillParams);
+          // if(this.skillParams.channel === '6001'){
+          //
+          // } else if(this.skillParams.skillId === 0 || this.skillParams.skillId === 3){
+          // // this.$store.dispatch("getBaiduData", this.skillParams);
+          // this.$store.dispatch("getSkillData", this.skillParams);
+          //
+          // } else if(this.skillParams.channel === 'ALI') {
+          // this.$store.dispatch("getAliData", this.skillParams);
+          // } else if(this.skillParams.channel === 'XYYFMOBILE') {
+          //   // console.log('学有义方')
+          //   this.$store.dispatch("getXyyfData", this.skillParams);
+          // } else{
+          //   this.$store.dispatch("getSkillData", 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);
+    },
+    columnZero() {
+      return "0";
+    },
+    columnZeroPercent(row, column, index) {
+      if (row.totalPayment && column.property === "yearlyConversion") {
+        return "100.00%";
+      } else {
+        return "0.00%";
+      }
+      // if(row.)
+    },
+    hide (channel) {
+      if (channel === '6001' || channel === 'XYYF' || channel === 'XYYFMOBILE') {
+        return false
+      }
+      return true
+    },
+    changeDate(date) {
+      return formatDate(date, 4)
+    },
+    // 导出表格
+    onExportExcel() {
+        const name = "OPPO-同步辅导"
+        const date = this.skillParams.startDate + '至' + this.skillParams.endDate
+        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>
+

+ 4 - 7
src/pages/order/Order.vue

@@ -266,12 +266,12 @@ export default {
   },
   computed: {
     ...mapGetters({
-      channeList: "channeList",
       orderList: "orderList",
-      productList: "productList"
     })
   },
   created() {
+    this.$store.dispatch("clearList");
+
     // this.$store.dispatch("getChannelList", { pageNo: "", pageSize: "" });
     // this.$store.dispatch("getOrderList", this.orderParams);
     this.orderParams.startDate = this.getYesterDay();
@@ -323,10 +323,7 @@ export default {
     },
     // 导出表格
     onExportExcel() {
-        const nameList = this.channeList.list.filter((item) => item.code === this.orderParams.channelCode)[0]
-        const name = (nameList && nameList.title) || ''
-        const list = this.productList.filter((item) => item.id === this.orderParams.packageId)[0]
-        const productName = list && list.title ? '-' + list.title : ''
+        const name = '极米-教育全栏目'
         const date = this.orderParams.startDate + '至' + this.orderParams.endDate
         downTable('table', [
           {wch: 15}, // "characters"
@@ -347,7 +344,7 @@ export default {
           {wch: 10},
           {wch: 20},
           {wch: 25}
-        ], name + productName + date)
+        ], name + date)
     },
   }
 };

+ 432 - 0
src/pages/skill/xqb.vue

@@ -0,0 +1,432 @@
+<template>
+  <div>
+    <el-card>
+      <el-form :model="skillParams" ref="skillParams" class="clearfix topForm" style="float: left">
+        <div class="leftForm-skill">
+          <el-form-item
+            style="display:flex;"
+            prop="channel"
+            name="channel"
+            :rules="[{ required: true, message: '请选择渠道', trigger: 'blur' }]"
+            label="渠道选择"
+          >
+            <el-select
+              v-model="skillParams.channel"
+              @change="channelChange"
+              style="width:160px"
+              placeholder="请选择渠道"
+            >
+              <el-option
+                v-for="item in skillChanneList"
+                :key="item.code"
+                :label="item.title"
+                :value="item.code"
+              ></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.startDate"
+              type="date"
+              placeholder="起"
+            ></el-date-picker>
+            <el-date-picker
+              style="width:140px"
+              v-model="skillParams.endDate"
+              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="skillData" 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"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></el-table-column>
+          <el-table-column
+            label="VIP用户活跃率 | =UV1/V0"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            min-width="140px"
+            prop="aliveVipProportion"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          >
+          </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="fealtyCount"
+            min-width="140px"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></el-table-column>
+          <el-table-column
+            label="忠实用户占比"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="fealtyProportion"
+            min-width="140px"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></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-pagination
+      v-if="orderList.totalElements"
+      background
+      layout="prev, pager, next"
+      :total="orderList.totalElements"
+      @current-change="changePage">
+      </el-pagination>-->
+    </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: {
+        skillId: "",
+        startDate: "",
+        endDate: "",
+        channel: "",
+        classId: "",
+        channelCode: "",
+        packageId: ""
+      },
+      channelList: "",
+      skillChanneList: [
+        { title: "百度-小度在家", code: "BAIDU" },
+        { title: "阿里-天猫精灵", code: "ALI" },
+        { title: "蜜蜂视频", code: "MIFENG" },
+      ],
+    };
+  },
+  computed: {
+    ...mapGetters({
+      skillData: "skillData"
+    })
+  },
+  created() {
+    this.$store.dispatch("clearList");
+    // this.$store.dispatch("getOrderList", this.skillParams);
+    this.skillParams.startDate = this.getYesterDay();
+    this.skillParams.endDate = this.getYesterDay();
+
+    this.tableHeight = document.documentElement.clientHeight * 0.75;
+  },
+  methods: {
+    // 搜索
+    submitForm(formName) {
+      this.skillParams.startDate = this.skillParams.startDate
+        ? formatDate(this.skillParams.startDate, 2)
+        : "";
+      this.skillParams.endDate = this.skillParams.endDate
+        ? formatDate(this.skillParams.endDate, 2)
+        : "";
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          console.log(this.skillParams.channel)
+          if(this.skillParams.channel === 'BAIDU'){
+            this.$store.dispatch("getSkillData", this.skillParams);
+          } else if(this.skillParams.channel === 'ALI') {
+            this.$store.dispatch("getAliData", this.skillParams);
+          }  else {
+            console.log(this.skillParams)
+            this.skillParams.channelCode = "100501";
+            this.skillParams.packageId = "10050102";
+            this.$store.dispatch("getMiFengData", 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) {
+      if (val === 'BAIDU' ) {
+        this.skillParams.skillId = "5";
+      } else if( val ==='ALI') {
+        this.skillParams.skillId = "14";
+      }
+      // 清空数据
+      this.$store.dispatch("clearList");
+    },
+    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 = "学前领先班-"
+        let productName = "蜜蜂视频"
+        let channel = this.skillParams.channel;
+        if (channel === 'BAIDU' ) {
+          productName = "小度在家";
+        } else if( channel ==='ALI') {
+          productName = "天猫精灵";
+        }
+
+      const date = this.skillParams.startDate + '至' + this.skillParams.endDate
+        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 + productName + 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>
+

+ 432 - 0
src/pages/skill/xxms.vue

@@ -0,0 +1,432 @@
+<template>
+  <div>
+    <el-card>
+      <el-form :model="skillParams" ref="skillParams" class="clearfix topForm" style="float: left">
+        <div class="leftForm-skill">
+          <el-form-item
+            style="display:flex;"
+            prop="channel"
+            name="channel"
+            :rules="[{ required: true, message: '请选择渠道', trigger: 'blur' }]"
+            label="渠道选择"
+          >
+            <el-select
+              v-model="skillParams.channel"
+              @change="channelChange"
+              style="width:160px"
+              placeholder="请选择渠道"
+            >
+              <el-option
+                v-for="item in skillChanneList"
+                :key="item.code"
+                :label="item.title"
+                :value="item.code"
+              ></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.startDate"
+              type="date"
+              placeholder="起"
+            ></el-date-picker>
+            <el-date-picker
+              style="width:140px"
+              v-model="skillParams.endDate"
+              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="skillData" 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"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></el-table-column>
+          <el-table-column
+            label="VIP用户活跃率 | =UV1/V0"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            min-width="140px"
+            prop="aliveVipProportion"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          >
+          </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="fealtyCount"
+            min-width="140px"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></el-table-column>
+          <el-table-column
+            label="忠实用户占比"
+            align="right"
+            header-align="center"
+            :render-header="renderheader"
+            prop="fealtyProportion"
+            min-width="140px"
+            v-if="skillParams.channel === 'XYYF' || skillParams.channel === 'XYYFMOBILE'"
+          ></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-pagination
+      v-if="orderList.totalElements"
+      background
+      layout="prev, pager, next"
+      :total="orderList.totalElements"
+      @current-change="changePage">
+      </el-pagination>-->
+    </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: {
+        skillId: "",
+        startDate: "",
+        endDate: "",
+        channel: "",
+        classId: "",
+        channelCode: "",
+        packageId: ""
+      },
+      channelList: "",
+      skillChanneList: [
+        { title: "百度-小度在家", code: "BAIDU" },
+        { title: "阿里-天猫精灵", code: "ALI" },
+        { title: "蜜蜂视频", code: "MIFENG" },
+      ],
+    };
+  },
+  computed: {
+    ...mapGetters({
+      skillData: "skillData"
+    })
+  },
+  created() {
+    this.$store.dispatch("clearList");
+    // this.$store.dispatch("getOrderList", this.skillParams);
+    this.skillParams.startDate = this.getYesterDay();
+    this.skillParams.endDate = this.getYesterDay();
+
+    this.tableHeight = document.documentElement.clientHeight * 0.75;
+  },
+  methods: {
+    // 搜索
+    submitForm(formName) {
+      this.skillParams.startDate = this.skillParams.startDate
+        ? formatDate(this.skillParams.startDate, 2)
+        : "";
+      this.skillParams.endDate = this.skillParams.endDate
+        ? formatDate(this.skillParams.endDate, 2)
+        : "";
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          console.log(this.skillParams.channel)
+          if(this.skillParams.channel === 'BAIDU'){
+            this.$store.dispatch("getSkillData", this.skillParams);
+          } else if(this.skillParams.channel === 'ALI') {
+            this.$store.dispatch("getAliData", this.skillParams);
+          }  else {
+            console.log(this.skillParams)
+            this.skillParams.channelCode = "100501";
+            this.skillParams.packageId = "10050103";
+            this.$store.dispatch("getMiFengData", 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) {
+      if (val === 'BAIDU' ) {
+        this.skillParams.skillId = "11";
+      } else if( val ==='ALI') {
+        this.skillParams.skillId = "15";
+      }
+      // 清空数据
+      this.$store.dispatch("clearList");
+    },
+    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 = "小学名师优课-"
+        let productName = "蜜蜂视频"
+        let channel = this.skillParams.channel;
+        if (channel === 'BAIDU' ) {
+          productName = "小度在家";
+        } else if( channel ==='ALI') {
+          productName = "天猫精灵";
+        }
+
+        const date = this.skillParams.startDate + '至' + this.skillParams.endDate
+        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 + productName + 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 - 9
src/pages/skill/yey.vue

@@ -284,21 +284,17 @@ export default {
       skillChanneList: [
         { title: "百度-小度在家", code: "BAIDU" },
         { title: "阿里-天猫精灵", code: "ALI" },
-        // { title: "百度-义方小学堂", code: "XYYF" }, //注释掉百度义方小学堂
         { title: "蜜蜂视频", code: "MIFENG" },
       ],
-      baiduCourseList: []
     };
   },
   computed: {
     ...mapGetters({
-      skillList: "skillList",
-      orderList: "orderList",
-      productList: "productList",
       skillData: "skillData"
     })
   },
   created() {
+    this.$store.dispatch("clearList");
     // this.$store.dispatch("getOrderList", this.skillParams);
     this.skillParams.startDate = this.getYesterDay();
     this.skillParams.endDate = this.getYesterDay();
@@ -377,10 +373,15 @@ export default {
     },
     // 导出表格
     onExportExcel() {
-        const nameList = this.skillChanneList.filter((item) => item.code === this.skillParams.channel)[0]
-        const name = (nameList && nameList.title) || ''
-        const list = this.skillList.filter((item) => item.skillId === this.skillParams.skillId)[0] || ''
-        const productName = list && list.skillName ? '-' + list.skillName : ''
+        const name = "爱上幼儿园-"
+        let productName = "蜜蜂视频"
+        let channel = this.skillParams.channel;
+        if (channel === 'BAIDU' ) {
+          productName = "小度在家";
+        } else if( channel ==='ALI') {
+          productName = "天猫精灵";
+        }
+
         const date = this.skillParams.startDate + '至' + this.skillParams.endDate
         downTable('table', [
           {wch: 15}, // "characters"

+ 1 - 0
src/pages/tv/TV.vue

@@ -216,6 +216,7 @@ export default {
     })
   },
   created() {
+    this.$store.dispatch("clearList");
     this.$store.dispatch("getEfunChannelList",'TV');
     this.efunParams.startDate = this.getYesterDay();
     this.efunParams.endDate = this.getYesterDay();

+ 10 - 14
src/pages/xyyf/Adaline.vue

@@ -5,11 +5,11 @@
         <div class="leftForm-skill">
           <el-form-item
             class="pruductForm-skill"
-            prop="skillId"
+            prop="channel"
             label="渠道选择"
             :rules="[{ required: true, message: '请选择渠道', trigger: 'blur' }]"
           >
-            <el-select v-model="skillParams.skillId" placeholder="请选择渠道" @change="skillChange" style="width:160px">
+            <el-select v-model="skillParams.channel" placeholder="请选择渠道" @change="channelChange" style="width:160px">
               <el-option key="1008" label="步步高" value="2010" ></el-option>
               <el-option key="1013" label="联想(PC)" value="2014" ></el-option>
               <el-option key="1007" label="萌状元" value="2009" ></el-option>
@@ -34,8 +34,8 @@
           <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="skillData" border style="width: 100%" :height="tableHeight" >
+      <el-button type="primary" @click="onExportExcel" style="float: right">导出</el-button>
+      <el-table id="table" ref="table1" :data="xyyfData" border style="width: 100%" :height="tableHeight" >
         <el-table-column
           label="日期"
           fixed
@@ -260,18 +260,17 @@ export default {
     };
   },
   computed: {
+
     ...mapGetters({
-      skillList: "skillList",
-      orderList: "orderList",
-      productList: "productList",
-      skillData: "skillData"
+
+      xyyfData: "xyyfData"
     })
   },
   created() {
     // this.$store.dispatch("getOrderList", this.skillParams);
     this.skillParams.startDate = this.getYesterDay();
     this.skillParams.endDate = this.getYesterDay();
-
+    this.$store.dispatch("clearList");
     this.tableHeight = document.documentElement.clientHeight * 0.75;
   },
   methods: {
@@ -350,10 +349,7 @@ export default {
     },
     // 导出表格
     onExportExcel() {
-        const nameList = this.skillChanneList.filter((item) => item.code === this.skillParams.channel)[0]
-        const name = (nameList && nameList.title) || ''
-        const list = this.skillList.filter((item) => item.skillId === this.skillParams.skillId)[0] || ''
-        const productName = list && list.skillName ? '-' + list.skillName : ''
+        const name = '学有义方-学习机'
         const date = this.skillParams.startDate + '至' + this.skillParams.endDate
         downTable('table', [
           {wch: 15}, // "characters"
@@ -374,7 +370,7 @@ export default {
           {wch: 10},
           {wch: 20},
           {wch: 25}
-        ], name + productName + date)
+        ], name + date)
     }
   }
 };

+ 8 - 13
src/pages/xyyf/AppStore.vue

@@ -5,11 +5,11 @@
         <div class="leftForm-skill">
           <el-form-item
             class="pruductForm-skill"
-            prop="skillId"
+            prop="channel"
             label="渠道选择"
             :rules="[{ required: true, message: '请选择渠道', trigger: 'blur' }]"
           >
-            <el-select v-model="skillParams.skillId" placeholder="请选择渠道" @change="skillChange" style="width:160px">
+            <el-select v-model="skillParams.channel" placeholder="请选择渠道" @change="skillChange" style="width:160px">
               <el-option key="10011" label="应用宝" value="2001" ></el-option>
               <el-option key="1002" label="OPPO" value="2004" ></el-option>
               <el-option key="1004" label="义方" value="2006" ></el-option>
@@ -36,8 +36,8 @@
           <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="skillData" border style="width: 100%" :height="tableHeight" >
+      <el-button type="primary" @click="onExportExcel" style="float: right">导出</el-button>
+      <el-table id="table" ref="table1" :data="xyyfData" border style="width: 100%" :height="tableHeight" >
         <el-table-column
           label="日期"
           fixed
@@ -263,13 +263,11 @@ export default {
   },
   computed: {
     ...mapGetters({
-      skillList: "skillList",
-      orderList: "orderList",
-      productList: "productList",
-      skillData: "skillData"
+      xyyfData: "xyyfData"
     })
   },
   created() {
+    this.$store.dispatch("clearList");
     // this.$store.dispatch("getOrderList", this.skillParams);
     this.skillParams.startDate = this.getYesterDay();
     this.skillParams.endDate = this.getYesterDay();
@@ -352,10 +350,7 @@ export default {
     },
     // 导出表格
     onExportExcel() {
-        const nameList = this.skillChanneList.filter((item) => item.code === this.skillParams.channel)[0]
-        const name = (nameList && nameList.title) || ''
-        const list = this.skillList.filter((item) => item.skillId === this.skillParams.skillId)[0] || ''
-        const productName = list && list.skillName ? '-' + list.skillName : ''
+        const name = '学有义方-APPStore'
         const date = this.skillParams.startDate + '至' + this.skillParams.endDate
         downTable('table', [
           {wch: 15}, // "characters"
@@ -376,7 +371,7 @@ export default {
           {wch: 10},
           {wch: 20},
           {wch: 25}
-        ], name + productName + date)
+        ], name + date)
     }
   }
 };

+ 9 - 13
src/pages/xyyf/SoundBox.vue

@@ -5,11 +5,11 @@
         <div class="leftForm-skill">
           <el-form-item
             class="pruductForm-skill"
-            prop="skillId"
+            prop="channel"
             label="渠道选择"
             :rules="[{ required: true, message: '请选择渠道', trigger: 'blur' }]"
           >
-            <el-select v-model="skillParams.skillId" placeholder="请选择渠道" @change="skillChange" style="width:160px">
+            <el-select v-model="skillParams.channel" placeholder="请选择渠道" @change="skillChange" style="width:160px">
               <el-option key="1001" label="小度音箱" value="3003" ></el-option>
               <el-option key="1011" label="天猫精灵" value="2012" ></el-option>
               <el-option key="1011" label="小爱同学" value="2013" ></el-option>
@@ -34,8 +34,8 @@
           <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="skillData" border style="width: 100%" :height="tableHeight" >
+      <el-button type="primary" @click="onExportExcel" style="float: right">导出</el-button>
+      <el-table id="table" ref="table1" :data="xyyfData" border style="width: 100%" :height="tableHeight" >
         <el-table-column
           label="日期"
           fixed
@@ -261,13 +261,12 @@ export default {
   },
   computed: {
     ...mapGetters({
-      skillList: "skillList",
-      orderList: "orderList",
-      productList: "productList",
-      skillData: "skillData"
+      xyyfData: "xyyfData"
     })
   },
   created() {
+    this.$store.dispatch("clearList");
+
     // this.$store.dispatch("getOrderList", this.skillParams);
     this.skillParams.startDate = this.getYesterDay();
     this.skillParams.endDate = this.getYesterDay();
@@ -350,10 +349,7 @@ export default {
     },
     // 导出表格
     onExportExcel() {
-        const nameList = this.skillChanneList.filter((item) => item.code === this.skillParams.channel)[0]
-        const name = (nameList && nameList.title) || ''
-        const list = this.skillList.filter((item) => item.skillId === this.skillParams.skillId)[0] || ''
-        const productName = list && list.skillName ? '-' + list.skillName : ''
+        const name = '学有义方-音箱'
         const date = this.skillParams.startDate + '至' + this.skillParams.endDate
         downTable('table', [
           {wch: 15}, // "characters"
@@ -374,7 +370,7 @@ export default {
           {wch: 10},
           {wch: 20},
           {wch: 25}
-        ], name + productName + date)
+        ], name + date)
     }
   }
 };

+ 34 - 3
src/router/router.js

@@ -79,11 +79,22 @@ const router = new Router({
       },
       {
         path: 'yey',
-        name:'Skill-ali',
-        meta: { title: '技能相关', url: '/skill/yey' },
+        name:'Skill-yey',
+        meta: { title: '爱上幼儿园', url: '/skill/yey' },
         component: () => import('@/pages/skill/yey'),
       },
-
+      {
+        path: 'xqb',
+        name:'Skill-xqb',
+        meta: { title: '学前领先班', url: '/skill/xqb' },
+        component: () => import('@/pages/skill/xqb'),
+      },
+      {
+        path: 'xxms',
+        name:'Skill-xxms',
+        meta: { title: '小学名师优课', url: '/skill/xxms' },
+        component: () => import('@/pages/skill/xxms'),
+      },
       ]
     },
     {
@@ -106,6 +117,26 @@ const router = new Router({
         component: () => import('@/pages/mobile/Mobile'),
       }]
     },
+    {
+      path: '/oppo',
+      component: Layout,
+      children: [{
+        path: 'index',
+        name:'oppo',
+        meta: { title: 'tv8.0', url: '/oppo/index' },
+        component: () => import('@/pages/oppo/xxtbfd'),
+      }]
+    },
+    {
+      path: '/baidu',
+      component: Layout,
+      children: [{
+        path: 'index',
+        name:'baidu',
+        meta: { title: 'tv8.0', url: '/baidu/index' },
+        component: () => import('@/pages/baidu/Skill'),
+      }]
+    },
     // {
     //   path: '/course',
     //   component: Layout,

+ 2 - 0
src/store/getter.js

@@ -10,6 +10,8 @@ const getters = {
   skillData: state => state.skill.skillData,
   channelData: state => state.efun.channelData,
   efunChannelList: state => state.efun.efunChannelList,
+  oppoData:state=>state.oppo.oppoData,
+  xyyfData: state => state.xyyf.xyyfData,
 
 }
 export default getters

+ 5 - 1
src/store/index.js

@@ -9,6 +9,8 @@ import order from './modules/order'
 import operation from './modules/operation'
 import skill from './modules/skill'
 import efun from './modules/efun'
+import oppo from './modules/oppo'
+import xyyf from './modules/xyyf'
 Vue.use(Vuex)
 
 const store = new Vuex.Store({
@@ -20,7 +22,9 @@ const store = new Vuex.Store({
     order,
     operation,
     skill,
-    efun
+    efun,
+    oppo,
+    xyyf,
   },
   getters
 })

+ 7 - 0
src/store/modules/efun.js

@@ -41,6 +41,13 @@ const efun = {
           })
         })
       },
+    // 清空数据
+    clearList({
+                dispatch,
+                commit
+              }) {
+      commit('GET_CHANNEL_DATA', [])
+    },
   }
 }
 

+ 41 - 0
src/store/modules/oppo.js

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

+ 3 - 3
src/store/modules/skill.js

@@ -12,7 +12,7 @@ import {
 const skill = {
   state: {
     skillList: [],
-    skillData: []
+    skillData: [],
   },
   mutations: {
     GET_SKILL_LIST: (state, data) => {
@@ -20,7 +20,7 @@ const skill = {
     },
     GET_SKILL_DATA: (state, data) => {
       state.skillData = data
-    }
+    },
   },
   actions: {
     // 获取技能信息
@@ -116,7 +116,7 @@ const skill = {
           console.log(res.data)
           if (res.code == 200) {
             resolve(res.data);
-            commit('GET_SKILL_DATA', res.data)
+            commit('GET_OPPO_DATA', res.data)
           }
         }).catch(error => {
           reject(error);

+ 64 - 0
src/store/modules/xyyf.js

@@ -0,0 +1,64 @@
+import {
+  getXyyfMobileList,
+  getXyyfData,
+} from '../../api/xyyf'
+
+const xyyf = {
+  state: {
+    xyyfChannelList: [],
+    xyyfData: [],
+  },
+  mutations: {
+    GET_XYYF_LIST: (state, data) => {
+      state.xyyfList = data
+    },
+    GET_XYYF_DATA: (state, data) => {
+      state.xyyfData = data
+    },
+  },
+  actions: {
+    // 获取学有义方渠道号
+    getXyyfMobileList({
+      dispatch,
+      commit
+    }) {
+      return new Promise((resolve, reject) => {
+        getXyyfMobileList().then(res => {
+          console.log(3333333, res.data)
+          if (res.code == 200) {
+            resolve(res.data);
+            commit('GET_XYYF_LIST', res.data)
+          }
+        }).catch(error => {
+          reject(error);
+        })
+      })
+    },
+    // 清空数据
+    clearList({
+      dispatch,
+      commit
+    }) {
+      commit('GET_XYYF_DATA', [])
+    },
+    getXyyfData({
+      dispatch,
+      commit
+    },data) {
+      return new Promise((resolve, reject) => {
+        console.log(data)
+        getXyyfData(data).then(res => {
+          console.log(res.data)
+          if (res.code == 200) {
+            resolve(res.data);
+            commit('GET_XYYF_DATA', res.data)
+          }
+        }).catch(error => {
+          reject(error);
+        })
+      })
+    },
+  }
+}
+
+export default xyyf