hurx 1 сар өмнө
parent
commit
0f71f3005c
1 өөрчлөгдсөн 341 нэмэгдсэн , 113 устгасан
  1. 341 113
      src/views/index.vue

+ 341 - 113
src/views/index.vue

@@ -1,147 +1,375 @@
 <template>
   <div class="app-container home">
-    <!-- <el-divider /> -->
-    <div class="index-style">
-      <div class="typewriter-container">
-        <span v-for="(char, index) in 'welcome!'" :key="index" :style="{ animationDelay: `${index * 0.5}s` }" class="typewriter-char">{{
-          char
-        }}</span>
-      </div>
-    </div>
+    <!-- 统计卡片 -->
+    <el-row :gutter="20" class="panel-group">
+      <el-col :span="6" class="card-panel-col">
+        <el-card shadow="hover" class="box-card">
+          <div class="card-header">
+            <span>伙伴商总数</span>
+            <el-tag type="primary" effect="light" size="small">实时</el-tag>
+          </div>
+          <div class="card-body">
+            <h2 class="num">1,250</h2>
+            <div class="bottom">
+              <span class="text-up">较上月 + 5% ↑</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6" class="card-panel-col">
+        <el-card shadow="hover" class="box-card">
+          <div class="card-header">
+            <span>本月新增入驻</span>
+            <el-tag type="success" effect="light" size="small">月度</el-tag>
+          </div>
+          <div class="card-body">
+            <h2 class="num">120</h2>
+            <div class="bottom">
+              <span class="text-up">较上月 + 12% ↑</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6" class="card-panel-col">
+        <el-card shadow="hover" class="box-card">
+          <div class="card-header">
+            <span>待处理审批</span>
+            <el-tag type="warning" effect="light" size="small">待办</el-tag>
+          </div>
+          <div class="card-body">
+            <h2 class="num" style="color: #e6a23c;">15</h2>
+            <div class="bottom">
+              <span style="color: #909399">需及时处理审批事项</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6" class="card-panel-col">
+        <el-card shadow="hover" class="box-card">
+          <div class="card-header">
+            <span>合作中项目数</span>
+            <el-tag type="info" effect="light" size="small">业务</el-tag>
+          </div>
+          <div class="card-body">
+            <h2 class="num">340</h2>
+            <div class="bottom">
+              <span class="text-down">较上月 - 2% ↓</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 图表 -->
+    <el-row :gutter="20" class="chart-group">
+      <el-col :span="12">
+        <el-card shadow="hover">
+          <template #header>
+            <div class="clearfix">
+              <span>近半年新增伙伴商趋势</span>
+            </div>
+          </template>
+          <div ref="lineChartRef" style="height: 350px"></div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card shadow="hover">
+          <template #header>
+            <div class="clearfix">
+              <span>伙伴商评级分布</span>
+            </div>
+          </template>
+          <div ref="pieChartRef" style="height: 350px"></div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 列表 -->
+    <el-row :gutter="20" class="list-group">
+      <el-col :span="24">
+        <el-card shadow="hover">
+          <template #header>
+            <div class="clearfix">
+              <span>最新入驻伙伴商审批列表</span>
+              <el-button style="float: right; padding: 3px 0" type="primary" link>查看更多</el-button>
+            </div>
+          </template>
+          <el-table :data="partnerList" style="width: 100%" :header-cell-style="{background:'#f8f8f9',color:'#606266'}">
+            <el-table-column type="index" label="序号" width="60" align="center" />
+            <el-table-column prop="companyName" label="伙伴商名称" min-width="200" show-overflow-tooltip />
+            <el-table-column prop="contact" label="联系人" width="120" />
+            <el-table-column prop="phone" label="联系电话" width="150" />
+            <el-table-column prop="level" label="申请评级" width="120" align="center">
+              <template #default="scope">
+                <el-tag :type="getLevelType(scope.row.level)">
+                  {{ scope.row.level }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="status" label="审批状态" width="120" align="center">
+              <template #default="scope">
+                <el-tag :type="scope.row.status === '已通过' ? 'success' : scope.row.status === '待审批' ? 'warning' : 'danger'">
+                  {{ scope.row.status }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="joinTime" label="申请时间" width="160" />
+            <el-table-column label="操作" width="120" align="center">
+              <template #default="scope">
+                <el-button type="primary" link size="small" v-if="scope.row.status === '待审批'">审批</el-button>
+                <el-button type="info" link size="small" v-else>查看</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </el-col>
+    </el-row>
   </div>
 </template>
 
 <script setup name="Index" lang="ts">
-const goTarget = (url: string) => {
-  window.open(url, '__blank');
-};
-</script>
+import { ref, onMounted, onBeforeUnmount, nextTick, markRaw } from 'vue';
+import * as echarts from 'echarts';
 
-<style lang="scss" scoped>
-.home {
-  blockquote {
-    padding: 10px 20px;
-    margin: 0 0 20px;
-    font-size: 17.5px;
-    border-left: 5px solid #eee;
+const lineChartRef = ref<HTMLElement | null>(null);
+const pieChartRef = ref<HTMLElement | null>(null);
+
+let lineChart: echarts.ECharts | null = null;
+let pieChart: echarts.ECharts | null = null;
+
+// 表格数据
+const partnerList = ref([
+  { companyName: '上海星瑞科技有限公司', contact: '张伟', phone: '138****8000', level: '战略伙伴', status: '待审批', joinTime: '2023-11-05 10:23:00' },
+  { companyName: '北京云创集团有限公司', contact: '李娜', phone: '139****5678', level: '核心伙伴', status: '已通过', joinTime: '2023-11-04 15:45:12' },
+  { companyName: '深圳速达物流中心', contact: '王强', phone: '137****9999', level: '普通伙伴', status: '已通过', joinTime: '2023-11-02 09:12:30' },
+  { companyName: '广州联智网络股份有限公司', contact: '陈静', phone: '136****6666', level: '核心伙伴', status: '已驳回', joinTime: '2023-10-30 14:20:00' },
+  { companyName: '杭州数智信息技术有限公司', contact: '刘洋', phone: '135****8888', level: '战略伙伴', status: '已通过', joinTime: '2023-10-28 11:10:45' },
+]);
+
+const getLevelType = (level: string) => {
+  switch (level) {
+    case '战略伙伴': return 'danger';
+    case '核心伙伴': return 'warning';
+    case '普通伙伴': return 'info';
+    default: return 'primary';
   }
-  hr {
-    margin-top: 20px;
-    margin-bottom: 20px;
-    border: 0;
-    border-top: 1px solid #eee;
+};
+
+const initLineChart = () => {
+  if (lineChartRef.value) {
+    lineChart = markRaw(echarts.init(lineChartRef.value));
+    const option = {
+      tooltip: {
+        trigger: 'axis'
+      },
+      grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true
+      },
+      xAxis: {
+        type: 'category',
+        boundaryGap: false,
+        data: ['5月', '6月', '7月', '8月', '9月', '10月']
+      },
+      yAxis: {
+        type: 'value',
+        splitLine: {
+          lineStyle: {
+            type: 'dashed'
+          }
+        }
+      },
+      series: [
+        {
+          name: '新增伙伴商',
+          type: 'line',
+          smooth: true,
+          areaStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: 'rgba(64,158,255,0.6)' },
+              { offset: 1, color: 'rgba(64,158,255,0.1)' }
+            ])
+          },
+          itemStyle: {
+            color: '#409EFF'
+          },
+          data: [20, 32, 25, 45, 60, 55]
+        }
+      ]
+    };
+    lineChart.setOption(option);
   }
-  .col-item {
-    margin-bottom: 20px;
+};
+
+const initPieChart = () => {
+  if (pieChartRef.value) {
+    pieChart = markRaw(echarts.init(pieChartRef.value));
+    const option = {
+      tooltip: {
+        trigger: 'item',
+        formatter: '{a} <br/>{b} : {c}家 ({d}%)'
+      },
+      legend: {
+        bottom: '0%',
+        left: 'center',
+        itemWidth: 10,
+        itemHeight: 10,
+      },
+      series: [
+        {
+          name: '伙伴商评级',
+          type: 'pie',
+          radius: ['45%', '70%'],
+          center: ['50%', '45%'],
+          avoidLabelOverlap: false,
+          itemStyle: {
+            borderRadius: 8,
+            borderColor: '#fff',
+            borderWidth: 2
+          },
+          label: {
+            show: false,
+            position: 'center'
+          },
+          emphasis: {
+            label: {
+              show: true,
+              fontSize: '18',
+              fontWeight: 'bold'
+            }
+          },
+          labelLine: {
+            show: false
+          },
+          data: [
+            { value: 1048, name: '普通伙伴', itemStyle: { color: '#909399' } },
+            { value: 735, name: '核心伙伴', itemStyle: { color: '#E6A23C' } },
+            { value: 580, name: '战略伙伴', itemStyle: { color: '#F56C6C' } },
+            { value: 484, name: '认证伙伴', itemStyle: { color: '#409EFF' } },
+            { value: 300, name: '观察期伙伴', itemStyle: { color: '#C0C4CC' } }
+          ]
+        }
+      ]
+    };
+    pieChart.setOption(option);
   }
+};
 
-  ul {
-    padding: 0;
-    margin: 0;
+const handleResize = () => {
+  if (lineChart) {
+    lineChart.resize();
+  }
+  if (pieChart) {
+    pieChart.resize();
   }
+};
 
-  font-family: 'open sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
-  font-size: 13px;
-  color: #676a6c;
-  overflow-x: hidden;
+onMounted(() => {
+  nextTick(() => {
+    initLineChart();
+    initPieChart();
+    window.addEventListener('resize', handleResize);
+  });
+});
 
-  ul {
-    list-style-type: none;
+onBeforeUnmount(() => {
+  window.removeEventListener('resize', handleResize);
+  if (lineChart) {
+    lineChart.dispose();
   }
-
-  h4 {
-    margin-top: 0px;
+  if (pieChart) {
+    pieChart.dispose();
   }
+});
+</script>
 
-  h2 {
-    margin-top: 10px;
-    font-size: 26px;
-    font-weight: 100;
-  }
+<style lang="scss" scoped>
+.app-container {
+  padding: 20px;
+  background-color: #f0f2f5;
+  min-height: calc(100vh - 84px);
+}
 
-  p {
-    margin-top: 10px;
+.panel-group {
+  margin-bottom: 20px;
+}
 
-    b {
-      font-weight: 700;
-    }
+.box-card {
+  border: none;
+  border-radius: 8px;
+  
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    color: #606266;
+    font-size: 14px;
+    font-weight: 500;
   }
 
-  .update-log {
-    ol {
-      display: block;
-      list-style-type: decimal;
-      margin-block-start: 1em;
-      margin-block-end: 1em;
-      margin-inline-start: 0;
-      margin-inline-end: 0;
-      padding-inline-start: 40px;
+  .card-body {
+    margin-top: 15px;
+
+    .num {
+      font-size: 30px;
+      font-weight: bold;
+      margin: 0;
+      color: #303133;
     }
-  }
-  .index-style {
-    font-size: 48px;
-    font-weight: bold;
-    letter-spacing: 15px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    height: 300px;
-    background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
-    border-radius: 10px;
-    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
 
-    .typewriter-container {
+    .bottom {
+      margin-top: 15px;
+      font-size: 13px;
       display: flex;
-    }
+      align-items: center;
+
+      .text-up {
+        color: #f56c6c;
+        display: flex;
+        align-items: center;
+        font-weight: 500;
+      }
 
-    .typewriter-char {
-      opacity: 0;
-      transform: translateY(20px) rotate(-5deg);
-      animation:
-        typewriter-animation 0.8s ease forwards,
-        pulse 2s ease-in-out infinite 1s;
-      color: #2d8cf0;
-      text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
-      transition: color 0.3s ease;
-
-      &:hover {
-        color: #f06292;
-        transform: scale(1.1);
-        animation-play-state: paused;
+      .text-down {
+        color: #67c23a;
+        display: flex;
+        align-items: center;
+        font-weight: 500;
       }
     }
   }
+}
 
-  @keyframes typewriter-animation {
-    0% {
-      opacity: 0;
-      transform: translateY(20px) rotate(-5deg);
-    }
-    50% {
-      opacity: 0.5;
-      transform: translateY(10px) rotate(-2deg);
-    }
-    100% {
-      opacity: 1;
-      transform: translateY(0) rotate(0deg);
-    }
+.chart-group {
+  margin-bottom: 20px;
+  
+  .el-card {
+    border: none;
+    border-radius: 8px;
+  }
+  
+  .clearfix {
+    font-size: 16px;
+    font-weight: 600;
+    color: #303133;
   }
+}
 
-  @keyframes pulse {
-    0% {
-      text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
-      transform: scale(1);
-    }
-    50% {
-      text-shadow:
-        0 0 15px rgba(45, 140, 240, 0.8),
-        0 0 30px rgba(45, 140, 240, 0.4);
-      transform: scale(1.05);
-    }
-    100% {
-      text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
-      transform: scale(1);
-    }
+.list-group {
+  .el-card {
+    border: none;
+    border-radius: 8px;
+  }
+  
+  .clearfix {
+    font-size: 16px;
+    font-weight: 600;
+    color: #303133;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
   }
 }
 </style>