yangyuxuan 2 هفته پیش
والد
کامیت
acff3c4bb6

BIN
src/assets/images/homePage/card.png


BIN
src/assets/images/homePage/icon1.png


BIN
src/assets/images/homePage/icon2.png


BIN
src/assets/images/homePage/icon3.png


BIN
src/assets/images/homePage/icon4.png


BIN
src/assets/images/homePage/icon5.png


+ 643 - 1
src/views/index.vue

@@ -1,9 +1,429 @@
 <template>
   <div class="app-container home">
-    <h2>安心E查工作台</h2>
+    <!--    <h2>安心E查工作台</h2>-->
+    <el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-click="handleClick">
+      <el-tab-pane label="今日" name="today"></el-tab-pane>
+      <el-tab-pane label="本周" name="week"></el-tab-pane>
+      <el-tab-pane label="本月" name="month"></el-tab-pane>
+      <el-tab-pane label="自定义" name="customize">
+        <el-date-picker
+          v-model="dataRange"
+          type="datetimerange"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          date-format="YYYY/MM/DD"
+          time-format="hh:mm:ss"
+        />
+      </el-tab-pane>
+    </el-tabs>
+    <div class="card-box">
+      <div v-for="(item, index) in statisticalData" :key="index" class="card-item">
+        <i :class="item.icon" />
+        <div class="text-box1">
+          <div class="text1">{{ item.name }}</div>
+          <div class="line">
+            <div class="text2">{{ item.data1 }}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div>
+      <el-tabs v-model="activeName1" type="card" class="demo-tabs" @tab-click="handleClick1">
+        <el-tab-pane label="家政服务" name="house"></el-tab-pane>
+        <el-tab-pane label="婚恋服务" name="marriage"></el-tab-pane>
+      </el-tabs>
+      <div class="flex">
+        <div class="card2">
+          <div class="card-header">
+            <i class="icon-line" />
+            <div class="card-title">对比分析漏斗图</div>
+          </div>
+          <div class="card-content">
+            <!--          漏斗图-->
+            <Chart :option="option1" rotation style="flex: 1" />
+          </div>
+        </div>
+        <div class="card2">
+          <div class="card-header">
+            <i class="icon-line" />
+            <div class="card-title">用户分析</div>
+          </div>
+          <div class="card-content">
+            <!-- 表格组件 -->
+            <el-table v-loading="loading" :data="userDataList" height="300px" style="width: 100%">
+              <el-table-column label="用户类型" align="center" prop="customer_type" />
+              <el-table-column label="用户数" align="center" prop="customer_num" />
+            </el-table>
+          </div>
+        </div>
+      </div>
+      <div class="flex" style="margin-top: 10px">
+        <div class="card2">
+          <div class="card-header">
+            <i class="icon-line" />
+            <div class="card-title">时间段分布</div>
+          </div>
+          <div class="card-content">
+            <Chart :option="option2" rotation style="flex: 1" />
+          </div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
+<script setup name="views">
+import * as echarts from 'echarts';
+import { addDateRange2 } from '@/utils/ruoyi.js';
+let activeName = ref('today');
+let activeName1 = ref('house');
+let xData = ref([]);
+let yData1 = ref([]); //家政服务数据
+let yData2 = ref([]); //婚恋服务数据
+let funnelData = ref([]);
+const dataRange = ref('');
+const option1 = ref({
+  color: ['#37A2DA', '#9FE6B8', '#FFDB5C'],
+  tooltip: {
+    trigger: 'item',
+    formatter: '{b} : {c}%'
+  },
+  legend: {
+    data: ['浏览量', '订单数', '支付数'],
+    top: 'bottom'
+  },
+  calculable: true,
+  series: [
+    {
+      name: '漏斗图',
+      type: 'funnel',
+      left: '10%',
+      top: 60,
+      bottom: 60,
+      width: '80%',
+      min: 0,
+      max: 100,
+      minSize: '0%',
+      maxSize: '100%',
+      sort: 'descending',
+      gap: 2,
+      label: {
+        show: true,
+        position: 'inside',
+        formatter: '{c}%',
+        color: '#fff',
+        fontSize: 14
+      },
+      labelLine: {
+        normal: {
+          length: 10,
+          lineStyle: {
+            width: 1,
+            type: 'solid'
+          }
+        }
+      },
+      itemStyle: {
+        normal: {
+          borderColor: '#fff',
+          borderWidth: 1
+        }
+      },
+      data: funnelData
+    }
+  ]
+});
+const option2 = ref({
+  title: {
+    text: '',
+    left: '12%',
+    top: '13%',
+    textStyle: {
+      color: '#999',
+      fontSize: 14
+    }
+  },
+  legend: {
+    show: true,
+    icon: 'circle',
+    top: '13%',
+    itemWidth: 6,
+    itemHeight: 6,
+    itemGap: 25,
+    data: ['家政服务', '婚恋服务']
+  },
+  tooltip: {
+    trigger: 'axis',
+    formatter: '{b}<br/>{a0}: {c0}<br/>{a1}: {c1}'
+  },
+  xAxis: [
+    {
+      type: 'category',
+      data: xData,
+      axisLine: {
+        lineStyle: {
+          color: '#ddd'
+        }
+      },
+      axisTick: {
+        show: false
+      },
+      axisLabel: {
+        interval: 0,
+        textStyle: {
+          color: 'rgba(34,32,32,0.93)'
+        },
+        margin: 15
+      },
+      boundaryGap: false,
+      nameLocation: 'middle',
+      nameGap: 30
+    }
+  ],
+  yAxis: [
+    {
+      type: 'value',
+      axisTick: {
+        show: false
+      },
+      axisLine: {
+        lineStyle: {
+          color: 'rgba(0,0,0,0.93)'
+        }
+      },
+      axisLabel: {
+        textStyle: {
+          color: '#201f1f'
+        },
+        formatter: '{value}'
+      },
+      splitLine: {
+        show: false
+      },
+      name: '单位:个',
+      nameLocation: 'end',
+      nameGap: 30
+    }
+  ],
+  series: [
+    {
+      name: '家政服务',
+      type: 'line',
+      data: yData1,
+      symbolSize: 6,
+      symbol: 'circle',
+      smooth: true,
+      lineStyle: {
+        color: '#fe9a8b'
+      },
+      itemStyle: {
+        normal: {
+          color: '#fe9a8b',
+          borderColor: '#fe9a8b'
+        }
+      },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: '#fe9a8bb3'
+          },
+          {
+            offset: 1,
+            color: '#fe9a8b03'
+          }
+        ])
+      },
+      emphasis: {
+        itemStyle: {
+          color: {
+            type: 'radial',
+            x: 0.5,
+            y: 0.5,
+            r: 0.5,
+            colorStops: [
+              {
+                offset: 0,
+                color: '#fe9a8b'
+              },
+              {
+                offset: 0.4,
+                color: '#fe9a8b'
+              },
+              {
+                offset: 0.5,
+                color: '#fff'
+              },
+              {
+                offset: 0.7,
+                color: '#fff'
+              },
+              {
+                offset: 0.8,
+                color: '#fff'
+              },
+              {
+                offset: 1,
+                color: '#fff'
+              }
+            ]
+          },
+          borderColor: '#fe9a8b',
+          borderWidth: 2
+        }
+      }
+    },
+    {
+      name: '婚恋服务',
+      type: 'line',
+      data: yData2,
+      symbolSize: 6,
+      symbol: 'circle',
+      smooth: true,
+      lineStyle: {
+        color: '#9E87FF'
+      },
+      itemStyle: {
+        normal: {
+          color: '#9E87FF',
+          borderColor: '#9E87FF'
+        }
+      },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: '#9E87FFb3'
+          },
+          {
+            offset: 1,
+            color: '#9E87FF03'
+          }
+        ])
+      },
+      emphasis: {
+        itemStyle: {
+          color: {
+            type: 'radial',
+            x: 0.5,
+            y: 0.5,
+            r: 0.5,
+            colorStops: [
+              {
+                offset: 0,
+                color: '#9E87FF'
+              },
+              {
+                offset: 0.4,
+                color: '#9E87FF'
+              },
+              {
+                offset: 0.5,
+                color: '#fff'
+              },
+              {
+                offset: 0.7,
+                color: '#fff'
+              },
+              {
+                offset: 0.8,
+                color: '#fff'
+              },
+              {
+                offset: 1,
+                color: '#fff'
+              }
+            ]
+          },
+          borderColor: '#9E87FF',
+          borderWidth: 2
+        }
+      }
+    }
+  ]
+});
+let loading = ref(false);
+const statisticalData = ref([]);
+const userDataList = ref([]);
+
+const formatDate = (date) => {
+  const targetDate = date ? new Date(date) : new Date();
+  const year = targetDate.getFullYear();
+  const month = String(targetDate.getMonth() + 1).padStart(2, '0');
+  const day = String(targetDate.getDate()).padStart(2, '0');
+  return `${year}-${month}-${day}`;
+};
+const getThisWeekRange = () => {
+  const today = new Date();
+  const sunday = new Date(today);
+  sunday.setDate(today.getDate() - today.getDay());
+  const saturday = new Date(sunday);
+  saturday.setDate(sunday.getDate() + 6);
+  return {
+    start: formatDate(sunday),
+    end: formatDate(saturday)
+  };
+};
+const getMonthRange = () => {
+  const now = new Date();
+  const start = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0);
+  const end = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
+  return { start: formatDate(start), end: formatDate(end) };
+};
+
+const getData = () => {
+  let query = ref('');
+  if (activeName.value === 'today') {
+    query.value = formatDate();
+  } else if (activeName.value === 'week') {
+    query.value = getThisWeekRange();
+  } else if (activeName.value === 'month') {
+    query.value = getMonthRange();
+  }
+  // else {
+  //   query.value = addDateRange2(queryParams, dataRange.value, 'startTime', 'endTime');
+  // }
+  xData.value = ['0:00', '2:00', '4:00', '6:00', '8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', '24:00'];
+  yData1.value = [5, 8, 3, 10, 35, 42, 50, 48, 60, 55, 40, 20, 8];
+  yData2.value = [20, 25, 15, 8, 5, 10, 15, 20, 30, 45, 60, 55, 30];
+  funnelData.value = [
+    { value: 100, name: '浏览量' },
+    { value: 70, name: '订单数' },
+    { value: 50, name: '支付数' }
+  ];
+  userDataList.value = [
+    {
+      customer_type: '普通用户',
+      customer_num: 1250
+    },
+    {
+      customer_type: 'VIP用户',
+      customer_num: 342
+    },
+    {
+      customer_type: '企业用户',
+      customer_num: 89
+    }
+  ];
+  statisticalData.value = [
+    { name: '订单数', icon: 'icon1', data1: '1800' },
+    { name: '销售额', icon: 'icon2', data1: '10000' },
+    { name: '支付数', icon: 'icon3', data1: '1700' },
+    { name: '退款额', icon: 'icon4', data1: '100' },
+    { name: '浏览量', icon: 'icon5', data1: '13909' }
+  ];
+};
+watch(
+  [activeName, activeName1],
+  () => {
+    getData();
+  },
+  { immediate: true }
+);
+</script>
+
 <style scoped lang="scss">
 .home {
   blockquote {
@@ -66,4 +486,226 @@
     }
   }
 }
+.card-box {
+  display: flex;
+  width: 100%;
+  .card-item {
+    flex: 1;
+    height: 135px;
+    background: url('@/assets/images/homePage/card.png') no-repeat;
+    background-size: 100% 100%;
+    margin-left: 20px;
+    padding: 24px 16px;
+    display: flex;
+    box-shadow: 0 0 10px #e7effa;
+    &:first-child {
+      margin-left: 0;
+    }
+    .icon1 {
+      background: url('@/assets/images/homePage/icon1.png') no-repeat;
+    }
+    .icon2 {
+      background: url('@/assets/images/homePage/icon2.png') no-repeat;
+    }
+    .icon3 {
+      background: url('@/assets/images/homePage/icon3.png') no-repeat;
+    }
+    .icon4 {
+      background: url('@/assets/images/homePage/icon4.png') no-repeat;
+    }
+    .icon5 {
+      background: url('@/assets/images/homePage/icon5.png') no-repeat;
+    }
+    .icon1,
+    .icon2,
+    .icon3,
+    .icon4,
+    .icon5 {
+      display: inline-block;
+      width: 44px;
+      height: 45px;
+      background-size: 100% 100%;
+      margin-right: 24px;
+    }
+    .text-box1 {
+      .text1 {
+        font-size: 17px;
+        color: #000000;
+        font-weight: bold;
+        margin-bottom: 19px;
+      }
+    }
+    .line {
+      display: flex;
+      .text2 {
+        font-size: 22px;
+        color: rgba(0, 0, 0, 0.65);
+        font-weight: bold;
+      }
+      .text-box2 {
+        margin-left: 21px;
+        .text3 {
+          display: flex;
+          align-items: center;
+          font-size: 12px;
+          color: rgba(0, 0, 0, 0.65);
+        }
+        .up-icon {
+          background: url('@/assets/images/knowledgeAnalysis/up.png') no-repeat;
+          background-size: 100% 100%;
+        }
+        .down-icon {
+          background: url('@/assets/images/knowledgeAnalysis/down.png') no-repeat;
+        }
+        .up-icon,
+        .down-icon {
+          width: 9px;
+          height: 5px;
+          background-size: 100% 100%;
+          margin-left: 9px;
+        }
+        .up-text {
+          font-size: 18px;
+          font-weight: bold;
+          color: #ff2f3c;
+          margin-top: 8px;
+        }
+        .down-text {
+          font-size: 18px;
+          font-weight: bold;
+          color: #41c861;
+          margin-top: 8px;
+        }
+      }
+    }
+  }
+}
+.flex {
+  display: flex;
+  justify-content: space-between;
+  padding: 0 17px;
+}
+.card2 {
+  flex: 1;
+  height: 367px;
+  border: 1px solid #e6f2ff;
+  background-image: linear-gradient(to bottom, #ffffff 0%, #ebf4ff 100%);
+  overflow-y: auto;
+  display: flex;
+  flex-direction: column;
+  padding-bottom: 10px;
+  &:nth-child(2) {
+    margin-left: 20px;
+  }
+  .card-header {
+    flex-shrink: 0;
+    display: flex;
+    align-items: center;
+    height: 40px;
+    padding: 10px 5px 16px;
+    .icon-line {
+      display: inline-block;
+      width: 6px;
+      height: 17px;
+      background-image: linear-gradient(180deg, #00fce7 0%, #2c81ff 100%);
+      border-radius: 0 3px 0 0;
+      margin-right: 7px;
+    }
+    .card-title {
+      font-size: 16px;
+      color: rgba(0, 0, 0, 0.85);
+    }
+  }
+  .card-content {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    padding: 0 22px;
+    overflow: hidden;
+    .box1 {
+      flex-shrink: 0;
+      display: flex;
+      align-items: center;
+      flex-wrap: wrap;
+      .date-box {
+        width: 289px;
+        height: 40px;
+        background-color: #edf1f8;
+        border-radius: 4px;
+        display: flex;
+        align-items: center;
+        padding: 0 4px;
+        .date-tag {
+          height: 32px;
+          width: 60px;
+          font-size: 14px;
+          color: #7a8293;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          cursor: pointer;
+          margin-left: 13px;
+          &:first-child {
+            margin-left: 0;
+          }
+          &:hover {
+            color: #2c81ff;
+            background: #ffffff;
+            box-shadow: 0 2px 1px 0 rgba(36, 41, 51, 0.04);
+            border-radius: 3px;
+          }
+        }
+        .tag-active {
+          color: #2c81ff;
+          background: #ffffff;
+          box-shadow: 0 2px 1px 0 rgba(36, 41, 51, 0.04);
+          border-radius: 3px;
+        }
+      }
+      :deep(.date-picker) {
+        margin-left: 29px;
+        width: 242px;
+        height: 40px;
+        border-radius: 3px;
+      }
+    }
+    .box2 {
+      height: 100%;
+      display: flex;
+      overflow: hidden;
+      .box3 {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        .box-item {
+          display: flex;
+          align-items: center;
+          padding: 11px 0;
+          .icon {
+            width: 8px;
+            height: 8px;
+            border-radius: 50%;
+            margin-right: 10px;
+          }
+          .text1 {
+            font-size: 14px;
+            color: rgba(0, 0, 0, 0.65);
+            width: 56px;
+            margin-right: 23px;
+          }
+          .text2 {
+            font-size: 14px;
+            color: rgba(0, 0, 0, 0.65);
+            width: 35px;
+            margin-right: 35px;
+          }
+          .text3 {
+            font-size: 14px;
+            color: rgba(0, 0, 0, 0.65);
+          }
+        }
+      }
+    }
+  }
+}
 </style>