hurx пре 1 месец
родитељ
комит
f6612e1283

+ 1 - 1
src/views/bill/statementInvoice/index.vue

@@ -312,7 +312,7 @@ const buttonConfigMap: Record<number, ActionButton[]> = {
   [InvoiceStatus.DRAFT]: [
     { action: 'detail', label: '查看', handler: handleDetail, permission: 'bill:statementInvoice:edit' },
     { action: 'edit', label: '编辑', handler: handleUpdate, permission: 'bill:statementInvoice:edit' },
-    { action: 'send', label: '发送对账单', handler: handleSend, permission: 'bill:statementInvoice:edit' },
+    { action: 'send', label: '发送开票信息', handler: handleSend, permission: 'bill:statementInvoice:edit' },
     { action: 'withdraw', label: '撤回', handler: handleWithdraw, permission: 'bill:statementInvoice:edit' },
     { action: 'obsolete', label: '作废', handler: handleObsolete, permission: 'bill:statementInvoice:remove' }
   ],

+ 325 - 110
src/views/index.vue

@@ -1,146 +1,361 @@
 <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 class="dashboard-header">
+      <h2>客户营销数据看板</h2>
+      <p>为您提供实时的客户、订单和商品数据概览</p>
     </div>
+
+    <!-- 数据统计卡片 -->
+    <el-row :gutter="20" class="panel-group">
+      <el-col :xs="24" :sm="12" :lg="6" class="card-panel-col">
+        <el-card shadow="hover" class="data-card customer-card">
+          <div class="card-header">
+            <div class="card-title">总客户数</div>
+            <el-tag type="primary" effect="light">实时</el-tag>
+          </div>
+          <div class="card-value">1,250</div>
+          <div class="card-desc">
+            <span>较上月 <span class="trend-up">+5.2% ↗</span></span>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :xs="24" :sm="12" :lg="6" class="card-panel-col">
+        <el-card shadow="hover" class="data-card order-card">
+          <div class="card-header">
+            <div class="card-title">总订单数</div>
+            <el-tag type="success" effect="light">实时</el-tag>
+          </div>
+          <div class="card-value">3,520</div>
+          <div class="card-desc">
+            <span>较上月 <span class="trend-up">+12.4% ↗</span></span>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :xs="24" :sm="12" :lg="6" class="card-panel-col">
+        <el-card shadow="hover" class="data-card product-card">
+          <div class="card-header">
+            <div class="card-title">商品总量</div>
+            <el-tag type="warning" effect="light">总计</el-tag>
+          </div>
+          <div class="card-value">485</div>
+          <div class="card-desc">
+            <span>本周上新 <span class="trend-up">+15 ↗</span></span>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :xs="24" :sm="12" :lg="6" class="card-panel-col">
+        <el-card shadow="hover" class="data-card revenue-card">
+          <div class="card-header">
+            <div class="card-title">本月营收</div>
+            <el-tag type="danger" effect="light">结算</el-tag>
+          </div>
+          <div class="card-value">¥128,500</div>
+          <div class="card-desc">
+            <span>较上月 <span class="trend-down">-1.5% ↘</span></span>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 图表与列表区域 -->
+    <el-row :gutter="20" class="content-row">
+      <!-- 最新订单 -->
+      <el-col :xs="24" :sm="24" :lg="16" class="card-panel-col">
+        <el-card shadow="hover" class="table-card">
+          <template #header>
+            <div class="clearfix">
+              <span class="section-title">最新订单明细</span>
+              <el-button style="float: right; padding: 3px 0" text>查看全部</el-button>
+            </div>
+          </template>
+          <el-table :data="orderList" style="width: 100%" height="350">
+            <el-table-column prop="orderNo" label="订单编号" width="130" />
+            <el-table-column prop="customer" label="客户名称" width="120" />
+            <el-table-column prop="product" label="商品信息" show-overflow-tooltip />
+            <el-table-column prop="amount" label="金额(元)" width="100">
+              <template #default="scope">
+                <span style="font-weight: bold; color: #f56c6c">¥{{ scope.row.amount }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="status" label="状态" width="90">
+              <template #default="scope">
+                <el-tag :type="getStatusType(scope.row.status)" size="small">
+                  {{ scope.row.status }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="date" label="下单时间" width="160" />
+          </el-table>
+        </el-card>
+      </el-col>
+
+      <!-- 热销商品榜单 -->
+      <el-col :xs="24" :sm="24" :lg="8" class="card-panel-col">
+        <el-card shadow="hover" class="list-card">
+          <template #header>
+            <div class="clearfix">
+              <span class="section-title">热销商品排行榜</span>
+            </div>
+          </template>
+          <div class="product-ranking">
+            <div v-for="(item, index) in productRankings" :key="index" class="ranking-item">
+              <div class="ranking-index" :class="{ 'top-three': index < 3 }">{{ index + 1 }}</div>
+              <div class="ranking-info">
+                <div class="product-name">{{ item.name }}</div>
+                <div class="product-sales">销量:{{ item.sales }} 件</div>
+              </div>
+              <div class="ranking-progress">
+                <el-progress :percentage="item.percentage" :color="getProgressColor(index)" :show-text="false" />
+              </div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
   </div>
 </template>
 
 <script setup name="Index" lang="ts">
-const goTarget = (url: string) => {
-  window.open(url, '__blank');
+import { ref } from 'vue';
+
+// 模拟订单数据
+const orderList = ref([
+  {
+    orderNo: 'ORD20231001',
+    customer: '张三网络',
+    product: '年度营销SaaS套餐(旗舰版)',
+    amount: '12800',
+    status: '已支付',
+    date: '2023-10-24 10:23:45'
+  },
+  { orderNo: 'ORD20231002', customer: '李四科技', product: '短信按量计费包(10万条)', amount: '4500', status: '待发货', date: '2023-10-24 09:15:30' },
+  { orderNo: 'ORD20231003', customer: '王五实业', product: '私有化部署实施服务费用', amount: '35000', status: '已完成', date: '2023-10-23 16:40:12' },
+  { orderNo: 'ORD20231004', customer: '赵六电商', product: '会员积分商城插件', amount: '899', status: '待支付', date: '2023-10-23 15:20:00' },
+  { orderNo: 'ORD20231005', customer: '钱七餐饮', product: '微信小程序点单系统', amount: '6800', status: '已完成', date: '2023-10-22 11:10:05' },
+  { orderNo: 'ORD20231006', customer: '孙八教育', product: '在线直播课程系统升级', amount: '15000', status: '已支付', date: '2023-10-22 09:05:22' }
+]);
+
+// 模拟商品排行榜数据
+const productRankings = ref([
+  { name: '年度营销SaaS套餐', sales: 1250, percentage: 90 },
+  { name: '微信小程序商城源码', sales: 980, percentage: 75 },
+  { name: '短信按量计费包', sales: 856, percentage: 65 },
+  { name: '私有化部署实施', sales: 420, percentage: 40 },
+  { name: '会员积分商城插件', sales: 315, percentage: 30 },
+  { name: '分销代理裂变系统', sales: 258, percentage: 20 }
+]);
+
+// 获取状态对应标签类型
+const getStatusType = (status: string) => {
+  const map: Record<string, string> = {
+    '已支付': 'primary',
+    '待发货': 'warning',
+    '已完成': 'success',
+    '待支付': 'danger'
+  };
+  return map[status] || ('info' as any);
+};
+
+// 排行榜进度条颜色
+const getProgressColor = (index: number) => {
+  if (index === 0) return '#f56c6c';
+  if (index === 1) return '#e6a23c';
+  if (index === 2) return '#409eff';
+  return '#c8c9cc';
 };
 </script>
 
 <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;
-  }
+  padding: 20px;
+  background-color: #f0f2f5;
+  min-height: calc(100vh - 84px);
 
-  ul {
-    padding: 0;
-    margin: 0;
+  .dashboard-header {
+    margin-bottom: 24px;
+    h2 {
+      margin: 0 0 10px 0;
+      font-size: 24px;
+      color: #303133;
+      font-weight: 600;
+      letter-spacing: 1px;
+    }
+    p {
+      margin: 0;
+      font-size: 14px;
+      color: #909399;
+    }
   }
 
-  font-family: 'open sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
-  font-size: 13px;
-  color: #676a6c;
-  overflow-x: hidden;
+  .panel-group {
+    margin-bottom: 24px;
 
-  ul {
-    list-style-type: none;
-  }
+    .card-panel-col {
+      margin-bottom: 20px;
+    }
 
-  h4 {
-    margin-top: 0px;
-  }
+    .data-card {
+      border-radius: 8px;
+      border: none;
+      transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
 
-  h2 {
-    margin-top: 10px;
-    font-size: 26px;
-    font-weight: 100;
-  }
+      &:hover {
+        transform: translateY(-5px);
+        box-shadow:
+          0 14px 28px rgba(0, 0, 0, 0.05),
+          0 10px 10px rgba(0, 0, 0, 0.02);
+      }
 
-  p {
-    margin-top: 10px;
+      .card-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 15px;
 
-    b {
-      font-weight: 700;
-    }
-  }
+        .card-title {
+          font-size: 14px;
+          color: #606266;
+          font-weight: bold;
+        }
+      }
 
-  .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;
-    }
-  }
-  .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 {
-      display: flex;
-    }
+      .card-value {
+        font-size: 32px;
+        font-weight: 700;
+        color: #303133;
+        margin-bottom: 15px;
+        font-family: 'Arial', sans-serif;
+      }
 
-    .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;
+      .card-desc {
+        font-size: 13px;
+        color: #909399;
+        display: flex;
+        justify-content: space-between;
 
-      &:hover {
-        color: #f06292;
-        transform: scale(1.1);
-        animation-play-state: paused;
+        .trend-up {
+          color: #67c23a;
+          font-weight: bold;
+          margin-left: 5px;
+        }
+
+        .trend-down {
+          color: #f56c6c;
+          font-weight: bold;
+          margin-left: 5px;
+        }
       }
     }
-  }
 
-  @keyframes typewriter-animation {
-    0% {
-      opacity: 0;
-      transform: translateY(20px) rotate(-5deg);
+    .customer-card .card-value {
+      color: #409eff;
+    }
+    .order-card .card-value {
+      color: #67c23a;
     }
-    50% {
-      opacity: 0.5;
-      transform: translateY(10px) rotate(-2deg);
+    .product-card .card-value {
+      color: #e6a23c;
     }
-    100% {
-      opacity: 1;
-      transform: translateY(0) rotate(0deg);
+    .revenue-card .card-value {
+      color: #f56c6c;
     }
   }
 
-  @keyframes pulse {
-    0% {
-      text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
-      transform: scale(1);
+  .content-row {
+    margin-bottom: 20px;
+
+    .card-panel-col {
+      margin-bottom: 20px;
     }
-    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);
+
+    .section-title {
+      font-size: 16px;
+      font-weight: bold;
+      color: #303133;
+      position: relative;
+      padding-left: 12px;
+
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        top: 2px;
+        bottom: 2px;
+        width: 4px;
+        background-color: #409eff;
+        border-radius: 2px;
+      }
     }
-    100% {
-      text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
-      transform: scale(1);
+
+    .table-card {
+      border-radius: 8px;
+      border: none;
+      height: 100%;
+    }
+
+    .list-card {
+      border-radius: 8px;
+      border: none;
+      height: 100%;
+
+      .product-ranking {
+        padding: 5px 0;
+
+        .ranking-item {
+          display: flex;
+          align-items: center;
+          margin-bottom: 20px;
+
+          &:last-child {
+            margin-bottom: 0;
+          }
+
+          .ranking-index {
+            width: 25px;
+            height: 25px;
+            line-height: 25px;
+            text-align: center;
+            background-color: #f4f4f5;
+            color: #909399;
+            border-radius: 50%;
+            font-size: 14px;
+            font-weight: bold;
+            margin-right: 15px;
+            flex-shrink: 0;
+
+            &.top-three {
+              background-color: #314659;
+              color: #fff;
+            }
+          }
+
+          .ranking-info {
+            flex: 1;
+            margin-right: 15px;
+            overflow: hidden;
+
+            .product-name {
+              font-size: 14px;
+              color: #303133;
+              margin-bottom: 5px;
+              white-space: nowrap;
+              overflow: hidden;
+              text-overflow: ellipsis;
+            }
+
+            .product-sales {
+              font-size: 12px;
+              color: #909399;
+            }
+          }
+
+          .ranking-progress {
+            width: 80px;
+            flex-shrink: 0;
+            margin-top: 5px;
+          }
+        }
+      }
     }
   }
 }

+ 1 - 3
src/views/order/orderReturn/index.vue

@@ -66,9 +66,7 @@
         <el-table-column label="退货原因" align="center" prop="returnReason" />
         <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
           <template #default="scope">
-            <el-button link type="primary" icon="Edit" @click="handleReview(scope.row)" v-hasPermi="['order:orderReturn:edit']"
-              >查看退货信息</el-button
-            >
+            <el-button link type="primary" icon="Edit" @click="handleReview(scope.row)">查看退货信息</el-button>
           </template>
         </el-table-column>
       </el-table>

+ 6 - 5
src/views/order/saleOrder/index.vue

@@ -105,11 +105,11 @@
             <dict-tag :options="order_source" :value="scope.row.orderSource" />
           </template>
         </el-table-column>
-        <el-table-column label="审核状态" align="center" prop="checkStatus">
+        <!-- <el-table-column label="审核状态" align="center" prop="checkStatus">
           <template #default="scope">
             <dict-tag :options="order_check_status" :value="scope.row.checkStatus" />
           </template>
-        </el-table-column>
+        </el-table-column> -->
         <el-table-column label="订单状态" align="center" prop="orderStatus">
           <template #default="scope">
             <dict-tag :options="order_status" :value="scope.row.orderStatus" />
@@ -287,6 +287,7 @@ const data = reactive<PageData<OrderMainForm, OrderMainQuery>>({
     afterSalePending: undefined,
     deliveryDesc: undefined,
     pushStatus: undefined,
+    checkStatus: '1', // 默认已审核
     attachmentPath: undefined,
     deliveryType: undefined,
     orderCategory: undefined,
@@ -596,9 +597,9 @@ 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) {