ソースを参照

添加统计页面

lex-xin 3 ヶ月 前
コミット
cf1a636e57

+ 16 - 0
src/router/routes-teacher.ts

@@ -395,6 +395,22 @@ export default [
         meta: {
           title: '协议'
         }
+      },
+      {
+        path: '/home-statistics',
+        name: 'home-statistics',
+        component: () => import('@/teacher/statistics/home-statistics/index'),
+        meta: {
+          title: '浏览/购买'
+        }
+      },
+      {
+        path: '/home-statistics-detail',
+        name: 'home-statistics-detail',
+        component: () => import('@/teacher/statistics/home-statistics-detail/index'),
+        meta: {
+          title: '数据详情'
+        }
       }
     ]
   },

+ 155 - 0
src/teacher/statistics/home-statistics-detail/index.module.less

@@ -0,0 +1,155 @@
+.homeStatistics {
+  background: #FFFFFF;
+  box-shadow: 0px 2px 10px 0px rgba(229, 229, 229, 0.1);
+  border-radius: 10px;
+  padding: 12px;
+  margin: 0 14px;
+}
+
+.homeHead {
+  display: flex;
+  justify-content: space-between;
+  padding-bottom: 12px;
+
+  .title {
+    display: flex;
+    align-items: center;
+    font-weight: 600;
+    font-size: 15px;
+    color: #333333;
+    line-height: 20px;
+
+    img {
+      width: 18px;
+      height: 18px;
+      margin-right: 6px;
+    }
+  }
+
+  .more {
+    display: flex;
+    align-items: center;
+    font-weight: 400;
+    font-size: 12px;
+    color: rgba(45, 199, 170, 1);
+    line-height: 17px;
+    cursor: pointer;
+    background: rgba(45, 199, 170, 0.1);
+    border-radius: 9px;
+    padding: 0 6px;
+
+    img {
+      width: 5px;
+      height: 8px;
+      margin-left: 5px;
+    }
+  }
+}
+
+.eChartSection {
+  .eChartTitle {
+    display: flex;
+    justify-content: space-between;
+    background: #F8F8F8;
+    border-radius: 4px;
+    padding: 6px 12px;
+
+    .left {
+      display: flex;
+      align-items: center;
+    }
+
+    .item {
+      display: flex;
+      align-items: center;
+      margin-right: 12px;
+      --color: #2DC7AA;
+
+      &:last-child {
+        margin-right: 0;
+      }
+
+      .line {
+        display: inline-block;
+        width: 10px;
+        height: 3px;
+        background: var(--color);
+        border-radius: 3px;
+
+      }
+
+      .text {
+        font-size: 12px;
+        color: #333333;
+        line-height: 16px;
+        padding: 0 4px 0 6px;
+      }
+
+      .num {
+        font-weight: 600;
+        font-size: 12px;
+        color: var(--color);
+        line-height: 16px;
+      }
+    }
+
+    .right {
+      display: flex;
+      align-items: center;
+    }
+
+    .showItem {
+      display: flex;
+      align-items: center;
+      font-size: 13px;
+      color: #131415;
+      line-height: 18px;
+
+      img {
+        margin-left: 4px;
+        width: 9px;
+        height: 5px;
+      }
+
+      &.showItemActive {
+        color: #2DC7AA;
+      }
+    }
+  }
+
+  .eChart {
+    height: 240px;
+    padding: 0;
+  }
+}
+
+:global {
+  .select-time {
+    width: 81px;
+    background: #FFFFFF;
+    box-shadow: 0px 0px 18px 0px rgba(0, 0, 0, 0.15);
+    border-radius: 8px;
+    padding: 6px;
+
+    span {
+      display: block;
+      font-size: 13px;
+      color: #323233;
+      line-height: 20px;
+      text-align: center;
+      line-height: 28px;
+      margin-bottom: 6px;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+
+    .active {
+      background: rgba(45, 199, 170, 0.1);
+      border-radius: 4px;
+      color: #2DC7AA;
+      font-weight: 500;
+    }
+  }
+}

+ 287 - 0
src/teacher/statistics/home-statistics-detail/index.tsx

@@ -0,0 +1,287 @@
+import { defineComponent, nextTick, onMounted, ref } from "vue";
+import styles from './index.module.less';
+import icon1 from '../images/icon1.png';
+import iconArrow from '../images/icon-arrow.png';
+import iconArrow1 from '../images/icon-arrow1.png';
+import iconArrow11 from '../images/icon-arrow1-1.png';
+import { Popover } from "vant";
+
+import * as echarts from 'echarts/core'
+import {
+  LineChart,
+  // LineSeriesOption
+} from 'echarts/charts'
+// import { PieChart } from 'echarts/charts'
+import {
+  TitleComponent,
+  // 组件类型的定义后缀都为 ComponentOption
+  // TitleComponentOption,
+  TooltipComponent,
+  // TooltipComponentOption,
+  GridComponent,
+  // 数据集组件
+  DatasetComponent,
+  // DatasetComponentOption,
+  // 内置数据转换器组件 (filter, sort)
+  // TransformComponent,
+  LegendComponent,
+  ToolboxComponent,
+  DataZoomComponent
+} from 'echarts/components'
+import { LabelLayout } from 'echarts/features'
+import { CanvasRenderer } from 'echarts/renderers'
+import { format } from "path";
+
+// 注册必须的组件
+echarts.use([
+  TitleComponent,
+  TooltipComponent,
+  GridComponent,
+  DatasetComponent,
+  // TransformComponent,
+  LabelLayout,
+  // UniversalTransition,
+  CanvasRenderer,
+  // PieChart,
+  ToolboxComponent,
+  LegendComponent,
+  DataZoomComponent,
+  LineChart
+])
+
+const lineChartOption = (xAxisData: any, seriesData: any) => {
+  return {
+    title: {
+      text: "单位:次",
+      textStyle: {
+        color: "#777777",
+        fontSize: 13,
+        fontWeight: 400
+      }
+    },
+    legend: { show: false },
+    emphasis: { lineStyle: { width: 2 } },
+    xAxis: {
+      boundaryGap: false,
+      data: xAxisData,
+      type: 'category',
+      axisLine: { lineStyle: { color: '#8C8C8C' } },
+      lineStyle: { color: '#F2F2F2' }
+    },
+    color: [
+      '#2DC7AA',
+      '#FF6079',
+      // '#2DC7AA',
+      // '#FF602C',
+      // '#91DD1C',
+      // '#FFA92C',
+      // '#BE7E2E',
+      // '#1C96DD',
+      // '#D22CFF',
+      // '#FF3C3C',
+      // '#1AEE3E',
+      // '#00c9ff'
+    ],
+    series: [
+      {
+        lineStyle: { width: 1 },
+        data: seriesData[0],
+        symbol: 'circle',
+        name: '浏览次数',
+        type: 'line',
+        emphasis: { lineStyle: { width: 1 } }
+      },
+      {
+        lineStyle: { width: 1 },
+        data: seriesData[1],
+        symbol: 'circle',
+        name: '购买次数',
+        type: 'line',
+        areaStyle: {
+          color: {
+            type: 'linear',
+            x: 0,
+            y: 0,
+            x2: 0,
+            y2: 1,
+            colorStops: [
+              {
+                offset: 0,
+                color: 'rgba(255, 96, 121, 0.23)'
+                // 0% 处的颜色
+              },
+              {
+                offset: 1,
+                // 100% 处的颜色
+                color: 'rgba(255, 96, 121, 0)'
+              }
+            ]
+          }
+        },
+        emphasis: { lineStyle: { width: 1 } }
+      }
+    ],
+    grid: {
+      bottom: '3%',
+      containLabel: true,
+      left: '3%',
+      right: '5%',
+      top: '40'
+    },
+    tooltip: {
+      trigger: 'axis',
+      confine: true,
+      formatter: function (params: any) {
+        return params[0].name;
+      },
+      backgroundColor: '#FF6079',
+      borderWidth: 0,
+      borderRadius: 24,
+      padding: [1, 4],
+      textStyle: {
+        color: '#FFFFFF',
+        fontSize: 12
+      }
+    },
+    yAxis: {
+      type: 'value',
+      splitLine: {
+        axisLine: { lineStyle: { color: '#8C8C8C' } },
+        lineStyle: { color: ['#f2f2f2'], type: 'dashed' }
+      }
+    },
+    dataZoom: [{ type: 'inside', throttle: 100 }],
+    toolbox: { feature: { saveAsImage: { show: false } } }
+  }
+}
+
+export default defineComponent({
+  name: 'HomeStatistics',
+  setup() {
+    const popoverStatus = ref(false);
+    const statisticCounts = ref({
+      browseCount: 0,
+      buyCount: 0
+    })
+    let myChart: echarts.ECharts
+
+    nextTick(() => {
+      myChart = echarts.init(document.getElementById('eChart') as HTMLDivElement)
+    })
+
+    onMounted(() => {
+      nextTick(() => {
+        myChart.clear()
+        lineChartOption && myChart.setOption(lineChartOption([
+        '01月',
+        '02月',
+        '03月',
+        '04月',
+        '05月',
+        '06月',
+        '07月',
+        '08月',
+        '09月',
+        '10月',
+        '11月',
+        '12月'
+      ], [[
+        '0',
+        '0',
+        '0',
+        '0',
+        '0',
+        '0',
+        '0',
+        '2',
+        '0',
+        '8',
+        '10',
+        '0'
+      ], [
+        '0',
+        '0',
+        '0',
+        '0',
+        '1',
+        '3',
+        '0',
+        '2',
+        '0',
+        '8',
+        '10',
+        '0'
+      ]]))
+        myChart.on('highlight', function (params: any) {
+          const batch = params.batch || []
+          const options: any = myChart.getOption()
+          batch.forEach((item: any) => {
+            const batchIndex = item.dataIndex;
+
+            const browseCount = options.series[0].data[batchIndex]
+            const buyCount = options.series[1].data[batchIndex]
+            statisticCounts.value = {
+              browseCount,
+              buyCount
+            }
+          })
+        })
+      })
+    })
+
+
+    return () => (
+      <div class={styles.homeStatistics}>
+        <div class={styles.homeHead}>
+          <div class={styles.title}>
+            <img src={icon1} />
+            <span>浏览/购买</span>
+          </div>
+
+          <div class={styles.more}>
+            <span>详情</span>
+            <img src={iconArrow} />
+          </div>
+        </div>
+
+        <div class={styles.eChartSection}>
+          <div class={styles.eChartTitle}>
+            <div class={styles.left}>
+              <div class={styles.item} style="--color: #2DC7AA">
+                <span class={styles.line}></span>
+                <span class={styles.text}>浏览次数</span>
+                <span class={styles.num}>{statisticCounts.value.browseCount}次</span>
+              </div>
+              <div class={styles.item} style="--color: #FF6079">
+                <span class={styles.line}></span>
+                <span class={styles.text}>购买次数</span>
+                <span class={styles.num}>{statisticCounts.value.buyCount}次</span>
+              </div>
+            </div>
+            <div class={styles.right}>
+              <Popover v-model:show={popoverStatus.value} showArrow={false}>
+                {{
+                  default: () => (
+                    <div class={'select-time'}>
+                      <span>本月</span>
+                      <span class={'active'}>近三个月</span>
+                      <span>近半年</span>
+                      <span>近一年</span>
+                    </div>),
+                  reference: () => (<div class={[styles.showItem, popoverStatus.value && styles.showItemActive]}>
+                    <span>本月</span>
+                    <img src={popoverStatus.value?iconArrow11 : iconArrow1} />
+                  </div>)
+                }}
+              </Popover>
+            </div>
+          </div>
+
+          <div class={styles.eChart}>
+            <div id="eChart" style="width: 100%; height: 100%;"></div>
+          </div>
+        </div>
+      </div>
+    )
+  }
+})

+ 155 - 0
src/teacher/statistics/home-statistics/index.module.less

@@ -0,0 +1,155 @@
+.homeStatistics {
+  background: #FFFFFF;
+  box-shadow: 0px 2px 10px 0px rgba(229, 229, 229, 0.1);
+  border-radius: 10px;
+  padding: 12px;
+  margin: 0 14px;
+}
+
+.homeHead {
+  display: flex;
+  justify-content: space-between;
+  padding-bottom: 12px;
+
+  .title {
+    display: flex;
+    align-items: center;
+    font-weight: 600;
+    font-size: 15px;
+    color: #333333;
+    line-height: 20px;
+
+    img {
+      width: 18px;
+      height: 18px;
+      margin-right: 6px;
+    }
+  }
+
+  .more {
+    display: flex;
+    align-items: center;
+    font-weight: 400;
+    font-size: 12px;
+    color: rgba(45, 199, 170, 1);
+    line-height: 17px;
+    cursor: pointer;
+    background: rgba(45, 199, 170, 0.1);
+    border-radius: 9px;
+    padding: 0 6px;
+
+    img {
+      width: 5px;
+      height: 8px;
+      margin-left: 5px;
+    }
+  }
+}
+
+.eChartSection {
+  .eChartTitle {
+    display: flex;
+    justify-content: space-between;
+    background: #F8F8F8;
+    border-radius: 4px;
+    padding: 6px 12px;
+
+    .left {
+      display: flex;
+      align-items: center;
+    }
+
+    .item {
+      display: flex;
+      align-items: center;
+      margin-right: 12px;
+      --color: #2DC7AA;
+
+      &:last-child {
+        margin-right: 0;
+      }
+
+      .line {
+        display: inline-block;
+        width: 10px;
+        height: 3px;
+        background: var(--color);
+        border-radius: 3px;
+
+      }
+
+      .text {
+        font-size: 12px;
+        color: #333333;
+        line-height: 16px;
+        padding: 0 4px 0 6px;
+      }
+
+      .num {
+        font-weight: 600;
+        font-size: 12px;
+        color: var(--color);
+        line-height: 16px;
+      }
+    }
+
+    .right {
+      display: flex;
+      align-items: center;
+    }
+
+    .showItem {
+      display: flex;
+      align-items: center;
+      font-size: 13px;
+      color: #131415;
+      line-height: 18px;
+
+      img {
+        margin-left: 4px;
+        width: 9px;
+        height: 5px;
+      }
+
+      &.showItemActive {
+        color: #2DC7AA;
+      }
+    }
+  }
+
+  .eChart {
+    height: 240px;
+    padding: 0;
+  }
+}
+
+:global {
+  .select-time {
+    width: 81px;
+    background: #FFFFFF;
+    box-shadow: 0px 0px 18px 0px rgba(0, 0, 0, 0.15);
+    border-radius: 8px;
+    padding: 6px;
+
+    span {
+      display: block;
+      font-size: 13px;
+      color: #323233;
+      line-height: 20px;
+      text-align: center;
+      line-height: 28px;
+      margin-bottom: 6px;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+
+    .active {
+      background: rgba(45, 199, 170, 0.1);
+      border-radius: 4px;
+      color: #2DC7AA;
+      font-weight: 500;
+    }
+  }
+}

+ 275 - 0
src/teacher/statistics/home-statistics/index.tsx

@@ -0,0 +1,275 @@
+import { defineComponent, nextTick, onMounted, ref } from "vue";
+import styles from './index.module.less';
+import icon1 from '../images/icon1.png';
+import iconArrow from '../images/icon-arrow.png';
+import iconArrow1 from '../images/icon-arrow1.png';
+import iconArrow11 from '../images/icon-arrow1-1.png';
+import { Popover } from "vant";
+
+import * as echarts from 'echarts/core'
+import {
+  LineChart,
+  // LineSeriesOption
+} from 'echarts/charts'
+// import { PieChart } from 'echarts/charts'
+import {
+  TitleComponent,
+  // 组件类型的定义后缀都为 ComponentOption
+  // TitleComponentOption,
+  TooltipComponent,
+  // TooltipComponentOption,
+  GridComponent,
+  // 数据集组件
+  DatasetComponent,
+  // DatasetComponentOption,
+  // 内置数据转换器组件 (filter, sort)
+  // TransformComponent,
+  LegendComponent,
+  ToolboxComponent,
+  DataZoomComponent
+} from 'echarts/components'
+import { LabelLayout } from 'echarts/features'
+import { CanvasRenderer } from 'echarts/renderers'
+import { format } from "path";
+
+// 注册必须的组件
+echarts.use([
+  TitleComponent,
+  TooltipComponent,
+  GridComponent,
+  DatasetComponent,
+  // TransformComponent,
+  LabelLayout,
+  // UniversalTransition,
+  CanvasRenderer,
+  // PieChart,
+  ToolboxComponent,
+  LegendComponent,
+  DataZoomComponent,
+  LineChart
+])
+
+const lineChartOption = (xAxisData: any, seriesData: any) => {
+  return {
+    title: {
+      text: "单位:次",
+      textStyle: {
+        color: "#777777",
+        fontSize: 13,
+        fontWeight: 400
+      }
+    },
+    legend: { show: false },
+    emphasis: { lineStyle: { width: 2 } },
+    xAxis: {
+      boundaryGap: false,
+      data: xAxisData,
+      type: 'category',
+      axisLine: { lineStyle: { color: '#8C8C8C' } },
+      lineStyle: { color: '#F2F2F2' }
+    },
+    color: [
+      '#2DC7AA',
+      '#FF6079',
+      // '#2DC7AA',
+      // '#FF602C',
+      // '#91DD1C',
+      // '#FFA92C',
+      // '#BE7E2E',
+      // '#1C96DD',
+      // '#D22CFF',
+      // '#FF3C3C',
+      // '#1AEE3E',
+      // '#00c9ff'
+    ],
+    series: [
+      {
+        lineStyle: { width: 1 },
+        data: seriesData[0],
+        symbol: 'circle',
+        name: '浏览次数',
+        type: 'line',
+        emphasis: { lineStyle: { width: 1 } }
+      },
+      {
+        lineStyle: { width: 1 },
+        data: seriesData[1],
+        symbol: 'circle',
+        name: '购买次数',
+        type: 'line',
+        areaStyle: {
+          color: {
+            type: 'linear',
+            x: 0,
+            y: 0,
+            x2: 0,
+            y2: 1,
+            colorStops: [
+              {
+                offset: 0,
+                color: 'rgba(255, 96, 121, 0.23)'
+                // 0% 处的颜色
+              },
+              {
+                offset: 1,
+                // 100% 处的颜色
+                color: 'rgba(255, 96, 121, 0)'
+              }
+            ]
+          }
+        },
+        emphasis: { lineStyle: { width: 1 } }
+      }
+    ],
+    grid: {
+      bottom: '3%',
+      containLabel: true,
+      left: '3%',
+      right: '5%',
+      top: '40'
+    },
+    tooltip: {
+      trigger: 'axis',
+      confine: true,
+      formatter: function (params: any) {
+        return params[0].name;
+      },
+      backgroundColor: '#FF6079',
+      borderWidth: 0,
+      borderRadius: 24,
+      padding: [1, 4],
+      textStyle: {
+        color: '#FFFFFF',
+        fontSize: 12
+      }
+    },
+    yAxis: {
+      type: 'value',
+      splitLine: {
+        axisLine: { lineStyle: { color: '#8C8C8C' } },
+        lineStyle: { color: ['#f2f2f2'], type: 'dashed' }
+      }
+    },
+    dataZoom: [{ type: 'inside', throttle: 100 }],
+    toolbox: { feature: { saveAsImage: { show: false } } }
+  }
+}
+
+export default defineComponent({
+  name: 'HomeStatistics',
+  setup() {
+    const popoverStatus = ref(false);
+    const statisticCounts = ref({
+      browseCount: 0,
+      buyCount: 0
+    })
+    let myChart: echarts.ECharts
+
+    nextTick(() => {
+      myChart = echarts.init(document.getElementById('eChart') as HTMLDivElement)
+    })
+
+    onMounted(() => {
+      nextTick(() => {
+        myChart.clear()
+        lineChartOption && myChart.setOption(lineChartOption([
+        '01月',
+        '02月',
+        '03月',
+        '04月',
+        '05月',
+        '06月',
+        '07月',
+        '08月',
+        '09月',
+        '10月',
+        '11月',
+        '12月'
+      ], [[
+        '0',
+        '0',
+        '0',
+        '0',
+        '0',
+        '0',
+        '0',
+        '2',
+        '0',
+        '8',
+        '10',
+        '0'
+      ], [
+        '0',
+        '0',
+        '0',
+        '0',
+        '1',
+        '3',
+        '0',
+        '2',
+        '0',
+        '8',
+        '10',
+        '0'
+      ]]))
+        myChart.on('highlight', function (params: any) {
+          const batch = params.batch || []
+          const options: any = myChart.getOption()
+          batch.forEach((item: any) => {
+            const batchIndex = item.dataIndex;
+
+            const browseCount = options.series[0].data[batchIndex]
+            const buyCount = options.series[1].data[batchIndex]
+            statisticCounts.value = {
+              browseCount,
+              buyCount
+            }
+          })
+        })
+      })
+    })
+
+
+    return () => (
+      <div class={styles.homeStatistics}>
+        <div class={styles.eChartSection}>
+          <div class={styles.eChartTitle}>
+            <div class={styles.left}>
+              <div class={styles.item} style="--color: #2DC7AA">
+                <span class={styles.line}></span>
+                <span class={styles.text}>浏览次数</span>
+                <span class={styles.num}>{statisticCounts.value.browseCount}次</span>
+              </div>
+              <div class={styles.item} style="--color: #FF6079">
+                <span class={styles.line}></span>
+                <span class={styles.text}>购买次数</span>
+                <span class={styles.num}>{statisticCounts.value.buyCount}次</span>
+              </div>
+            </div>
+            <div class={styles.right}>
+              <Popover v-model:show={popoverStatus.value} showArrow={false}>
+                {{
+                  default: () => (
+                    <div class={'select-time'}>
+                      <span>本月</span>
+                      <span class={'active'}>近三个月</span>
+                      <span>近半年</span>
+                      <span>近一年</span>
+                    </div>),
+                  reference: () => (<div class={[styles.showItem, popoverStatus.value && styles.showItemActive]}>
+                    <span>本月</span>
+                    <img src={popoverStatus.value?iconArrow11 : iconArrow1} />
+                  </div>)
+                }}
+              </Popover>
+            </div>
+          </div>
+
+          <div class={styles.eChart}>
+            <div id="eChart" style="width: 100%; height: 100%;"></div>
+          </div>
+        </div>
+      </div>
+    )
+  }
+})

BIN
src/teacher/statistics/images/icon-arrow.png


BIN
src/teacher/statistics/images/icon-arrow1-1.png


BIN
src/teacher/statistics/images/icon-arrow1.png


BIN
src/teacher/statistics/images/icon1.png