hurx 1 mēnesi atpakaļ
vecāks
revīzija
6ab988a036
2 mainītis faili ar 383 papildinājumiem un 116 dzēšanām
  1. 379 112
      src/views/index.vue
  2. 4 4
      src/views/order/saleOrder/index.vue

+ 379 - 112
src/views/index.vue

@@ -1,147 +1,414 @@
 <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 :xs="12" :sm="12" :lg="6" class="card-panel-col">
+        <el-card shadow="hover" class="box-card">
+          <div class="card-header">
+            <span class="card-title">今日订单(笔)</span>
+            <el-tag type="primary">日</el-tag>
+          </div>
+          <div class="card-value">1,245</div>
+          <div class="card-footer">
+            <span class="trend"
+              >较昨日
+              <span class="up"
+                ><el-icon><CaretTop /></el-icon>12.5%</span
+              ></span
+            >
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+        <el-card shadow="hover" class="box-card">
+          <div class="card-header">
+            <span class="card-title">待发货订单(笔)</span>
+            <el-tag type="warning">待办</el-tag>
+          </div>
+          <div class="card-value">342</div>
+          <div class="card-footer">
+            <span class="trend"
+              >较昨日
+              <span class="down"
+                ><el-icon><CaretBottom /></el-icon>5.2%</span
+              ></span
+            >
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+        <el-card shadow="hover" class="box-card">
+          <div class="card-header">
+            <span class="card-title">本月成交额(元)</span>
+            <el-tag type="success">月</el-tag>
+          </div>
+          <div class="card-value">¥89,450.00</div>
+          <div class="card-footer">
+            <span class="trend"
+              >同比上月
+              <span class="up"
+                ><el-icon><CaretTop /></el-icon>8.1%</span
+              ></span
+            >
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+        <el-card shadow="hover" class="box-card">
+          <div class="card-header">
+            <span class="card-title">售后退款订单(笔)</span>
+            <el-tag type="danger">售后</el-tag>
+          </div>
+          <div class="card-value">28</div>
+          <div class="card-footer">
+            <span class="trend"
+              >较昨日
+              <span class="up"
+                ><el-icon><CaretTop /></el-icon>2.0%</span
+              ></span
+            >
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 中部图表区域 -->
+    <el-row :gutter="20" style="margin-top: 20px">
+      <el-col :span="16">
+        <el-card shadow="hover" class="chart-card">
+          <template #header>
+            <div class="card-header-flex">
+              <span class="title">近七日订单趋势</span>
+            </div>
+          </template>
+          <!-- 柱状图 -->
+          <div ref="chartRef" style="height: 350px"></div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card shadow="hover" class="chart-card">
+          <template #header>
+            <div class="card-header-flex">
+              <span class="title">平台订单占比</span>
+            </div>
+          </template>
+          <!-- 饼图 -->
+          <div ref="pieRef" style="height: 350px"></div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 底部最新订单列表 -->
+    <el-row :gutter="20" style="margin-top: 20px">
+      <el-col :span="24">
+        <el-card shadow="hover" class="table-card">
+          <template #header>
+            <div class="card-header-flex">
+              <span class="title">最新订单动态</span>
+              <el-button link type="primary">查看全部</el-button>
+            </div>
+          </template>
+          <el-table :data="recentOrders" style="width: 100%" max-height="400">
+            <el-table-column prop="orderNo" label="订单编号" width="180" />
+            <el-table-column prop="customerName" label="客户名称" width="150" />
+            <el-table-column prop="platform" label="来源平台" width="120">
+              <template #default="scope">
+                <el-tag size="small" :type="scope.row.platform === '供应商' ? 'danger' : 'success'">
+                  {{ scope.row.platform }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="amount" label="订单金额(元)" width="150" />
+            <el-table-column prop="status" label="订单状态" width="120">
+              <template #default="scope">
+                <el-tag :type="getStatusType(scope.row.status)" effect="light">{{ scope.row.status }}</el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="createTime" label="创建时间" min-width="160" />
+            <el-table-column label="操作" width="120" fixed="right">
+              <template>
+                <el-button link type="primary" size="small">详情</el-button>
+                <!-- <el-button link type="primary" size="small">跟踪</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, onUnmounted, nextTick } from 'vue';
+import * as echarts from 'echarts';
+import { CaretTop, CaretBottom } from '@element-plus/icons-vue';
 
-<style lang="scss" scoped>
-.home {
-  blockquote {
-    padding: 10px 20px;
-    margin: 0 0 20px;
-    font-size: 17.5px;
-    border-left: 5px solid #eee;
-  }
-  hr {
-    margin-top: 20px;
-    margin-bottom: 20px;
-    border: 0;
-    border-top: 1px solid #eee;
-  }
-  .col-item {
-    margin-bottom: 20px;
+// 图表 refs
+const chartRef = ref<HTMLElement | null>(null);
+const pieRef = ref<HTMLElement | null>(null);
+let chartInstance: echarts.ECharts | null = null;
+let pieInstance: echarts.ECharts | null = null;
+
+// 模拟订单数据
+const recentOrders = ref([
+  { orderNo: 'ORD202310100001', customerName: '张先生', platform: '供应商', amount: '1,299.00', status: '待发货', createTime: '2023-10-10 10:23:05' },
+  {
+    orderNo: 'ORD202310100002',
+    customerName: '李四科技',
+    platform: '伙伴商',
+    amount: '8,950.00',
+    status: '已发货',
+    createTime: '2023-10-10 09:15:30'
+  },
+  { orderNo: 'ORD202310090015', customerName: '王五', platform: '大客户', amount: '399.00', status: '已完成', createTime: '2023-10-09 16:45:11' },
+  {
+    orderNo: 'ORD202310090008',
+    customerName: '赵六实业',
+    platform: '供应商',
+    amount: '12,500.00',
+    status: '已关闭',
+    createTime: '2023-10-09 11:20:00'
+  },
+  { orderNo: 'ORD202310080034', customerName: '孙七', platform: '普通客户', amount: '59.90', status: '部分发货', createTime: '2023-10-08 20:11:45' },
+  {
+    orderNo: 'ORD202310080002',
+    customerName: '华润商贸',
+    platform: '伙伴商',
+    amount: '45,000.00',
+    status: '已完成',
+    createTime: '2023-10-08 14:30:12'
   }
+]);
 
-  ul {
-    padding: 0;
-    margin: 0;
+// 订单状态颜色映射
+const getStatusType = (status: string) => {
+  switch (status) {
+    case '待发货':
+      return 'warning';
+    case '已发货':
+      return 'primary';
+    case '部分发货':
+      return 'primary';
+    case '已完成':
+      return 'success';
+    case '已关闭':
+      return 'info';
+    default:
+      return 'info';
   }
+};
 
-  font-family: 'open sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
-  font-size: 13px;
-  color: #676a6c;
-  overflow-x: hidden;
+// 初始化柱状图
+const initBarChart = () => {
+  if (!chartRef.value) return;
+  chartInstance = echarts.init(chartRef.value);
+  chartInstance.setOption({
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: { type: 'shadow' }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: [
+      {
+        type: 'category',
+        data: ['10-04', '10-05', '10-06', '10-07', '10-08', '10-09', '10-10'],
+        axisTick: { alignWithLabel: true },
+        axisLine: { lineStyle: { color: '#909399' } }
+      }
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        splitLine: { lineStyle: { type: 'dashed' } }
+      }
+    ],
+    series: [
+      {
+        name: '新增订单数',
+        type: 'bar',
+        barWidth: '40%',
+        data: [120, 200, 150, 80, 70, 110, 130],
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#83bff6' },
+            { offset: 0.5, color: '#188df0' },
+            { offset: 1, color: '#188df0' }
+          ]),
+          borderRadius: [4, 4, 0, 0]
+        }
+      }
+    ]
+  });
+};
 
-  ul {
-    list-style-type: none;
-  }
+// 初始化饼图
+const initPieChart = () => {
+  if (!pieRef.value) return;
+  pieInstance = echarts.init(pieRef.value);
+  pieInstance.setOption({
+    tooltip: {
+      trigger: 'item',
+      formatter: '{a} <br/>{b}: {c}笔 ({d}%)'
+    },
+    legend: {
+      orient: 'horizontal',
+      bottom: 'bottom'
+    },
+    series: [
+      {
+        name: '订单来源平台',
+        type: 'pie',
+        radius: ['45%', '70%'],
+        avoidLabelOverlap: false,
+        itemStyle: {
+          borderRadius: 8,
+          borderColor: '#fff',
+          borderWidth: 2
+        },
+        label: {
+          show: false,
+          position: 'center'
+        },
+        emphasis: {
+          label: {
+            show: true,
+            fontSize: 20,
+            fontWeight: 'bold',
+            formatter: '{b}\n{d}%'
+          }
+        },
+        labelLine: {
+          show: false
+        },
+        data: [
+          { value: 1048, name: '供应商', itemStyle: { color: '#f56c6c' } },
+          { value: 735, name: '伙伴商', itemStyle: { color: '#e6a23c' } },
+          { value: 580, name: '大客户', itemStyle: { color: '#409eff' } },
+          { value: 484, name: '普通客户', itemStyle: { color: '#67c23a' } },
+          { value: 300, name: '其他渠道', itemStyle: { color: '#909399' } }
+        ]
+      }
+    ]
+  });
+};
 
-  h4 {
-    margin-top: 0px;
-  }
+// 自适应图表大小
+const resizeCharts = () => {
+  chartInstance?.resize();
+  pieInstance?.resize();
+};
 
-  h2 {
-    margin-top: 10px;
-    font-size: 26px;
-    font-weight: 100;
-  }
+onMounted(() => {
+  nextTick(() => {
+    initBarChart();
+    initPieChart();
+    window.addEventListener('resize', resizeCharts);
+  });
+});
 
-  p {
-    margin-top: 10px;
+onUnmounted(() => {
+  window.removeEventListener('resize', resizeCharts);
+  chartInstance?.dispose();
+  pieInstance?.dispose();
+});
+</script>
 
-    b {
-      font-weight: 700;
-    }
-  }
+<style lang="scss" scoped>
+.app-container {
+  padding: 20px;
+  background-color: #f5f7f9;
+  min-height: calc(100vh - 84px);
+}
+
+.card-panel-col {
+  margin-bottom: 20px;
+}
 
-  .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;
+.box-card {
+  border-radius: 8px;
+  border: none;
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    color: #909399;
+    font-size: 14px;
+    margin-bottom: 12px;
+    .card-title {
+      font-weight: 500;
     }
   }
-  .index-style {
-    font-size: 48px;
-    font-weight: bold;
-    letter-spacing: 15px;
+  .card-value {
+    font-size: 28px;
+    font-weight: 600;
+    color: #303133;
+    margin-bottom: 15px;
+  }
+  .card-footer {
+    border-top: 1px solid #ebeef5;
+    padding-top: 12px;
+    font-size: 13px;
+    color: #606266;
     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 {
+    .trend {
       display: flex;
-    }
+      align-items: center;
+      gap: 5px;
 
-    .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;
+      .up {
+        color: #f56c6c;
+        display: inline-flex;
+        align-items: center;
+      }
+      .down {
+        color: #67c23a;
+        display: inline-flex;
+        align-items: center;
       }
     }
   }
+}
 
-  @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-card {
+  border-radius: 8px;
+  border: none;
+  .card-header-flex {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .title {
+      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);
+.table-card {
+  border-radius: 8px;
+  border: none;
+  .card-header-flex {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .title {
+      font-size: 16px;
+      font-weight: 600;
+      color: #303133;
     }
   }
 }
+
+// 覆盖 Element Plus 默认的卡片头部 padding
+:deep(.el-card__header) {
+  padding: 15px 20px;
+  border-bottom: 1px solid #ebeef5;
+}
 </style>

+ 4 - 4
src/views/order/saleOrder/index.vue

@@ -592,13 +592,13 @@ const getButtonsByStatus = (orderStatus: string, checkStatus: string): ActionBut
   }
 
   // 待审核:显示审核按钮
-  if (checkStatus === CheckStatus.PENDING) {
-    buttons.push({ label: '审核', handler: handleCheck });
-  }
+  // if (checkStatus === CheckStatus.PENDING) {
+  //   buttons.push({ label: '审核', handler: handleCheck });
+  // }
 
   // 待发货或部分发货:显示发货按钮
   if (orderStatus === OrderStatus.PENDING_SHIPMENT || orderStatus === OrderStatus.PARTIAL_SHIPMENT) {
-    buttons.push({ label: '发货', handler: handleDeliver });
+    // buttons.push({ label: '发货', handler: handleDeliver });
   }
 
   // 待发货、部分发货、发货完成、已完成:显示查看订单信息按钮