瀏覽代碼

Merge branch 'master' of http://121.4.16.100:3001/gebadi/aiZhuNong_Web_ui

zmj 9 月之前
父節點
當前提交
5e8058e879
共有 1 個文件被更改,包括 554 次插入80 次删除
  1. 554 80
      src/views/base/mall/index.vue

+ 554 - 80
src/views/base/mall/index.vue

@@ -1,13 +1,15 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="商品分类;0:推荐,1:种子,2:肥料,3:农药,4:农膜,5:农技配件" prop="productCategory">
-        <el-input
-          v-model="queryParams.productCategory"
-          placeholder="请输入商品分类;0:推荐,1:种子,2:肥料,3:农药,4:农膜,5:农技配件"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+      <el-form-item label="商品分类" prop="productCategory">
+        <el-select v-model="queryParams.productCategory" placeholder="请选择商品分类" clearable>
+          <el-option
+            v-for="dict in categoryOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="parseInt(dict.dictValue)"
+          ></el-option>
+        </el-select>
       </el-form-item>
       <el-form-item label="商品标题" prop="title">
         <el-input
@@ -17,29 +19,43 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="商品描述" prop="description">
-        <el-input
-          v-model="queryParams.description"
-          placeholder="请输入商品描述"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="当前价格" prop="price">
-        <el-input
-          v-model="queryParams.price"
-          placeholder="请输入当前价格"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+      <el-form-item label="价格" prop="originalPrice">
+        <div style="display: flex; align-items: center; gap: 8px;">
+          <el-input
+            v-model="queryParams.originalPriceMin"
+            placeholder="最低价格"
+            clearable
+            style="width: 120px;"
+            @keyup.enter.native="handleQuery"
+          />
+          <span>-</span>
+          <el-input
+            v-model="queryParams.originalPriceMax"
+            placeholder="最高价格"
+            clearable
+            style="width: 120px;"
+            @keyup.enter.native="handleQuery"
+          />
+        </div>
       </el-form-item>
-      <el-form-item label="原价" prop="originalPrice">
-        <el-input
-          v-model="queryParams.originalPrice"
-          placeholder="请输入原价"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+      <el-form-item label="优惠价格" prop="price">
+        <div style="display: flex; align-items: center; gap: 8px;">
+          <el-input
+            v-model="queryParams.priceMin"
+            placeholder="最低优惠价"
+            clearable
+            style="width: 120px;"
+            @keyup.enter.native="handleQuery"
+          />
+          <span>-</span>
+          <el-input
+            v-model="queryParams.priceMax"
+            placeholder="最高优惠价"
+            clearable
+            style="width: 120px;"
+            @keyup.enter.native="handleQuery"
+          />
+        </div>
       </el-form-item>
       <el-form-item label="商品规格" prop="specifications">
         <el-input
@@ -49,21 +65,12 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="轮播图URL数组" prop="swiperImages">
-        <el-input
-          v-model="queryParams.swiperImages"
-          placeholder="请输入轮播图URL数组"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="详情图URL数组" prop="detailImages">
-        <el-input
-          v-model="queryParams.detailImages"
-          placeholder="请输入详情图URL数组"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+      <el-form-item label="上架状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择上架状态" clearable>
+          <el-option label="已上架" :value="1"></el-option>
+          <el-option label="待上架" :value="2"></el-option>
+          <el-option label="已下架" :value="0"></el-option>
+        </el-select>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -71,6 +78,57 @@
       </el-form-item>
     </el-form>
 
+    <!-- 统计面板 -->
+    <div class="statistics-panel">
+      <el-row :gutter="12">
+        <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
+          <div class="stat-card total-card">
+            <div class="stat-content">
+              <div class="stat-title">商品总数</div>
+              <div class="stat-number">{{ statistics.totalCount || 0 }}</div>
+              <div class="stat-desc">累计商品数量</div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
+          <div class="stat-card on-sale-card">
+            <div class="stat-content">
+              <div class="stat-title">已上架</div>
+              <div class="stat-number">{{ statistics.onSaleCount || 0 }}</div>
+              <div class="stat-desc">正在销售中</div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
+          <div class="stat-card pending-card">
+            <div class="stat-content">
+              <div class="stat-title">待上架</div>
+              <div class="stat-number">{{ statistics.pendingCount || 0 }}</div>
+              <div class="stat-desc">等待上架商品</div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
+          <div class="stat-card off-sale-card">
+            <div class="stat-content">
+              <div class="stat-title">已下架</div>
+              <div class="stat-number">{{ statistics.offSaleCount || 0 }}</div>
+              <div class="stat-desc">暂停销售商品</div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
+          <div class="stat-card recommended-card">
+            <div class="stat-content">
+              <div class="stat-title">推荐商品</div>
+              <div class="stat-number">{{ statistics.recommendedCount || 0 }}</div>
+              <div class="stat-desc">重点推荐商品</div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
@@ -119,27 +177,86 @@
 
     <el-table v-loading="loading" :data="mallList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="商品ID" align="center" prop="id" />
-      <el-table-column label="商品分类;0:推荐,1:种子,2:肥料,3:农药,4:农膜,5:农技配件" align="center" prop="productCategory" />
+      <el-table-column label="序号" align="center" width="80" type="index">
+        <template slot-scope="scope">
+          <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="商品分类" align="center" prop="productCategory">
+        <template slot-scope="scope">
+          <span>{{ getCategoryText(scope.row.productCategory) }}</span>
+        </template>
+      </el-table-column>
       <el-table-column label="商品标题" align="center" prop="title" />
-      <el-table-column label="商品描述" align="center" prop="description" />
-      <el-table-column label="当前价格" align="center" prop="price" />
-      <el-table-column label="原价" align="center" prop="originalPrice" />
+      <el-table-column label="商品描述" align="center" prop="description" width="200" show-overflow-tooltip>
+        <template slot-scope="scope">
+          <div class="description-cell">
+            {{ scope.row.description && scope.row.description.length > 35 ? scope.row.description.substring(0, 35) + '...' : scope.row.description }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="价格" align="center" prop="originalPrice" />
+      <el-table-column label="优惠价格" align="center" prop="price" />
+      <el-table-column label="单位" align="center" prop="unit" />
       <el-table-column label="商品规格" align="center" prop="specifications" />
-      <el-table-column label="产品特点(JSON数组)" align="center" prop="features" />
-      <el-table-column label="使用说明" align="center" prop="usageGuide" />
-      <el-table-column label="轮播图URL数组" align="center" prop="swiperImages" />
-      <el-table-column label="详情图URL数组" align="center" prop="detailImages" />
-      <el-table-column label="状态 (1上架, 0下架)" align="center" prop="status" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="商品缩略图" align="center" prop="swiperImages" width="120">
         <template slot-scope="scope">
+          <el-image
+            v-if="getFirstImage(scope.row.swiperImages)"
+            :src="getFirstImage(scope.row.swiperImages)"
+            :preview-src-list="[getFirstImage(scope.row.swiperImages)]"
+            style="width: 80px; height: 80px; object-fit: cover; cursor: pointer;"
+            fit="cover"
+          >
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline"></i>
+            </div>
+          </el-image>
+          <span v-else>暂无图片</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="上架状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <el-tag 
+            :type="scope.row.status === 1 ? 'success' : scope.row.status === 2 ? 'warning' : 'danger'"
+            size="mini"
+          >
+            {{ scope.row.status === 1 ? '已上架' : scope.row.status === 2 ? '待上架' : '已下架' }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
+        <template slot-scope="scope">
+          <!-- 修改按钮:只有待上架(2)和已下架(0)可以修改 -->
           <el-button
+            v-if="scope.row.status === 2 || scope.row.status === 0"
             size="mini"
             type="text"
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
             v-hasPermi="['base:mall:edit']"
           >修改</el-button>
+          
+          <!-- 上架按钮:待上架(2)和已下架(0)都可以上架 -->
+          <el-button
+            v-if="scope.row.status === 2 || scope.row.status === 0"
+            size="mini"
+            type="text"
+            icon="el-icon-top"
+            @click="handleToggleStatus(scope.row, 1)"
+            v-hasPermi="['base:mall:edit']"
+          >上架</el-button>
+          
+          <!-- 下架按钮:只有已上架(1)可以下架 -->
+          <el-button
+            v-if="scope.row.status === 1"
+            size="mini"
+            type="text"
+            icon="el-icon-bottom"
+            @click="handleToggleStatus(scope.row, 0)"
+            v-hasPermi="['base:mall:edit']"
+          >下架</el-button>
+          
           <el-button
             size="mini"
             type="text"
@@ -160,36 +277,87 @@
     />
 
     <!-- 添加或修改农资商城对话框 -->
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="商品分类;0:推荐,1:种子,2:肥料,3:农药,4:农膜,5:农技配件" prop="productCategory">
-          <el-input v-model="form.productCategory" placeholder="请输入商品分类;0:推荐,1:种子,2:肥料,3:农药,4:农膜,5:农技配件" />
+    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="商品分类" prop="productCategory">
+          <el-select v-model="form.productCategory" placeholder="请选择商品分类" style="width: 100%">
+            <el-option
+              v-for="dict in categoryOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="parseInt(dict.dictValue)"
+            ></el-option>
+          </el-select>
         </el-form-item>
+        
         <el-form-item label="商品标题" prop="title">
           <el-input v-model="form.title" placeholder="请输入商品标题" />
         </el-form-item>
+        
         <el-form-item label="商品描述" prop="description">
-          <el-input v-model="form.description" placeholder="请输入商品描述" />
-        </el-form-item>
-        <el-form-item label="当前价格" prop="price">
-          <el-input v-model="form.price" placeholder="请输入当前价格" />
-        </el-form-item>
-        <el-form-item label="原价" prop="originalPrice">
-          <el-input v-model="form.originalPrice" placeholder="请输入原价" />
+          <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入商品描述" />
         </el-form-item>
+        
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="价格" prop="originalPrice">
+              <el-input-number
+                v-model="form.originalPrice"
+                :min="0"
+                :precision="2"
+                placeholder="请输入价格"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="优惠价格" prop="price">
+              <el-input-number
+                v-model="form.price"
+                :min="0"
+                :precision="2"
+                placeholder="请输入优惠价格"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="单位" prop="unit">
+              <el-input v-model="form.unit" placeholder="如:元/斤、元/袋" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        
         <el-form-item label="商品规格" prop="specifications">
           <el-input v-model="form.specifications" placeholder="请输入商品规格" />
         </el-form-item>
+        
+        <el-form-item label="产品特点" prop="features">
+          <el-input v-model="form.features" type="textarea" :rows="3" placeholder="请输入产品特点" />
+        </el-form-item>
+        
         <el-form-item label="使用说明" prop="usageGuide">
-          <el-input v-model="form.usageGuide" type="textarea" placeholder="请输入内容" />
+          <el-input v-model="form.usageGuide" type="textarea" :rows="4" placeholder="请输入使用说明" />
+        </el-form-item>
+        
+        <el-form-item label="商品缩略图" prop="swiperImages">
+          <image-upload v-model="form.swiperImages" :limit="5" />
+          <div style="color: #999; font-size: 12px; margin-top: 5px;">用于商品列表展示,建议上传3-5张</div>
         </el-form-item>
-        <el-form-item label="轮播图URL数组" prop="swiperImages">
-          <el-input v-model="form.swiperImages" placeholder="请输入轮播图URL数组" />
+        
+        <el-form-item label="商品详情图" prop="detailImages">
+          <image-upload v-model="form.detailImages" :limit="10" />
+          <div style="color: #999; font-size: 12px; margin-top: 5px;">用于商品详情页展示,建议上传5-10张</div>
         </el-form-item>
-        <el-form-item label="详情图URL数组" prop="detailImages">
-          <el-input v-model="form.detailImages" placeholder="请输入详情图URL数组" />
+        
+        <el-form-item label="是否推荐" prop="isRecommended">
+          <el-radio-group v-model="form.isRecommended">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
         </el-form-item>
       </el-form>
+      
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
@@ -200,6 +368,7 @@
 
 <script>
 import { listMall, getMall, delMall, addMall, updateMall } from "@/api/base/mall"
+import { getDicts } from "@/api/system/dict/data"
 
 export default {
   name: "Mall",
@@ -219,6 +388,16 @@ export default {
       total: 0,
       // 农资商城表格数据
       mallList: [],
+      // 商品分类字典数据
+      categoryOptions: [],
+      // 统计数据
+      statistics: {
+        totalCount: 0,
+        onSaleCount: 0,
+        offSaleCount: 0,
+        pendingCount: 0,
+        recommendedCount: 0
+      },
       // 弹出层标题
       title: "",
       // 是否显示弹出层
@@ -230,8 +409,10 @@ export default {
         productCategory: null,
         title: null,
         description: null,
-        price: null,
-        originalPrice: null,
+        priceMin: null,
+        priceMax: null,
+        originalPriceMin: null,
+        originalPriceMax: null,
         specifications: null,
         features: null,
         usageGuide: null,
@@ -244,7 +425,7 @@ export default {
       // 表单校验
       rules: {
         productCategory: [
-          { required: true, message: "商品分类;0:推荐,1:种子,2:肥料,3:农药,4:农膜,5:农技配件不能为空", trigger: "blur" }
+          { required: true, message: "商品分类不能为空", trigger: "change" }
         ],
         title: [
           { required: true, message: "商品标题不能为空", trigger: "blur" }
@@ -252,31 +433,68 @@ export default {
         description: [
           { required: true, message: "商品描述不能为空", trigger: "blur" }
         ],
+        originalPrice: [
+          { required: true, message: "价格不能为空", trigger: "blur" }
+        ],
         price: [
-          { required: true, message: "当前价格不能为空", trigger: "blur" }
+          { required: true, message: "优惠价格不能为空", trigger: "blur" }
+        ],
+        unit: [
+          { required: true, message: "单位不能为空", trigger: "blur" }
         ],
         specifications: [
           { required: true, message: "商品规格不能为空", trigger: "blur" }
         ],
         features: [
-          { required: true, message: "产品特点(JSON数组)不能为空", trigger: "blur" }
+          { required: true, message: "产品特点不能为空", trigger: "blur" }
         ],
         usageGuide: [
           { required: true, message: "使用说明不能为空", trigger: "blur" }
         ],
         swiperImages: [
-          { required: true, message: "轮播图URL数组不能为空", trigger: "blur" }
+          { required: true, message: "商品缩略图不能为空", trigger: "change" }
         ],
-        status: [
-          { required: true, message: "状态 (1上架, 0下架)不能为空", trigger: "change" }
+        detailImages: [
+          { required: true, message: "商品详情图不能为空", trigger: "change" }
         ],
       }
     }
   },
   created() {
     this.getList()
+    this.getDictData()
+    this.getStatistics()
   },
   methods: {
+    /** 获取字典数据 */
+    getDictData() {
+      getDicts("mall_product_category").then(response => {
+        this.categoryOptions = response.data
+      })
+    },
+    /** 获取统计数据 */
+    getStatistics() {
+      // 这里可以调用专门的统计API,目前先用列表数据计算
+      listMall({}).then(response => {
+        const data = response.rows || []
+        
+        this.statistics = {
+          totalCount: data.length,
+          onSaleCount: data.filter(item => item.status === 1).length,
+          offSaleCount: data.filter(item => item.status === 0).length,
+          pendingCount: data.filter(item => item.status === 2).length,
+          recommendedCount: data.filter(item => item.isRecommended === 1).length
+        }
+      }).catch(() => {
+        this.statistics = {
+          totalCount: 0,
+          onSaleCount: 0,
+          offSaleCount: 0,
+          pendingCount: 0,
+          recommendedCount: 0
+        }
+      })
+    },
     /** 查询农资商城列表 */
     getList() {
       this.loading = true
@@ -300,12 +518,14 @@ export default {
         description: null,
         price: null,
         originalPrice: null,
+        unit: null,
         specifications: null,
         features: null,
         usageGuide: null,
         swiperImages: null,
         detailImages: null,
-        status: null,
+        status: 2, // 默认待上架状态
+        isRecommended: 0, // 默认否
         createBy: null,
         createTime: null,
         updateBy: null,
@@ -354,12 +574,14 @@ export default {
               this.$modal.msgSuccess("修改成功")
               this.open = false
               this.getList()
+              this.getStatistics()
             })
           } else {
             addMall(this.form).then(response => {
               this.$modal.msgSuccess("新增成功")
               this.open = false
               this.getList()
+              this.getStatistics()
             })
           }
         }
@@ -372,6 +594,7 @@ export default {
         return delMall(ids)
       }).then(() => {
         this.getList()
+        this.getStatistics()
         this.$modal.msgSuccess("删除成功")
       }).catch(() => {})
     },
@@ -380,7 +603,258 @@ export default {
       this.download('base/mall/export', {
         ...this.queryParams
       }, `mall_${new Date().getTime()}.xlsx`)
+    },
+    /** 获取第一张图片 */
+    getFirstImage(swiperImages) {
+      if (!swiperImages) return null
+      
+      // 如果是字符串,尝试解析为JSON数组
+      if (typeof swiperImages === 'string') {
+        try {
+          const images = JSON.parse(swiperImages)
+          return Array.isArray(images) && images.length > 0 ? images[0] : null
+        } catch (e) {
+          // 如果解析失败,按逗号分割处理
+          const images = swiperImages.split(',').map(url => url.trim()).filter(url => url)
+          return images.length > 0 ? images[0] : null
+        }
+      }
+      
+      // 如果是数组,直接返回第一个元素
+      if (Array.isArray(swiperImages) && swiperImages.length > 0) {
+        return swiperImages[0]
+      }
+      
+      return null
+    },
+    /** 获取商品分类文字 */
+    getCategoryText(category) {
+      const categoryItem = this.categoryOptions.find(item => parseInt(item.dictValue) === category)
+      return categoryItem ? categoryItem.dictLabel : category
+    },
+    /** 切换商品上架状态 */
+    handleToggleStatus(row, targetStatus) {
+      const statusText = targetStatus === 1 ? '上架' : '下架'
+      
+      this.$modal.confirm(`确认要${statusText}商品"${row.title}"吗?`).then(() => {
+        const updateData = {
+          id: row.id,
+          status: targetStatus
+        }
+        
+        updateMall(updateData).then(response => {
+          this.$modal.msgSuccess(`${statusText}成功`)
+          this.getList()
+          this.getStatistics()
+        }).catch(() => {
+          this.$modal.msgError(`${statusText}失败`)
+        })
+      }).catch(() => {})
     }
   }
 }
 </script>
+
+<style scoped>
+.image-slot {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  height: 100%;
+  background: #f5f7fa;
+  color: #909399;
+  font-size: 24px;
+}
+
+.el-image {
+  border-radius: 4px;
+  border: 1px solid #ebeef5;
+}
+
+.description-cell {
+  max-width: 180px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  line-height: 1.5;
+  text-align: left;
+}
+
+/* 价格区间搜索样式 */
+.el-form .el-form-item__content > div {
+  align-items: center;
+}
+
+.el-form .el-form-item__content > div > span {
+  color: #606266;
+  margin: 0 4px;
+  font-weight: 500;
+}
+
+/* 统计面板样式 */
+.statistics-panel {
+  margin-bottom: 16px;
+  padding: 20px;
+  background: #fff;
+  border-radius: 12px;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
+}
+
+.statistics-panel .el-row {
+  display: flex;
+  justify-content: space-between;
+}
+
+.statistics-panel .el-col {
+  flex: 1;
+  max-width: none !important;
+}
+
+/* 统一各部分间距 */
+.app-container .el-form {
+  margin-bottom: 16px;
+}
+
+.app-container .mb8 {
+  margin-bottom: 16px !important;
+}
+
+.app-container .el-table {
+  margin-top: 0;
+}
+
+.stat-card {
+  border-radius: 12px;
+  padding: 16px;
+  height: 120px;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  transition: all 0.3s ease;
+  cursor: pointer;
+  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.05);
+  position: relative;
+  overflow: hidden;
+  color: #fff;
+  margin-bottom: 10px;
+}
+
+.stat-card:hover {
+  transform: translateY(-3px);
+  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15), 0 4px 10px rgba(0, 0, 0, 0.1);
+}
+
+.stat-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: flex-start;
+}
+
+.stat-title {
+  font-size: 13px;
+  font-weight: 600;
+  color: rgba(255, 255, 255, 0.9);
+  margin-bottom: 0;
+  line-height: 1.2;
+}
+
+.stat-number {
+  font-size: 32px;
+  font-weight: 700;
+  line-height: 1.0;
+  margin: 6px 0;
+  color: #fff;
+}
+
+.stat-desc {
+  font-size: 11px;
+  font-weight: 500;
+  color: rgba(255, 255, 255, 0.85);
+  line-height: 1.2;
+  margin: 0;
+}
+
+/* 不同卡片的主题色 */
+.total-card {
+  background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
+}
+
+.on-sale-card {
+  background: linear-gradient(135deg, #10b981 0%, #34d399 100%);
+}
+
+.pending-card {
+  background: linear-gradient(135deg, #f59e0b 0%, #fbbf24 100%);
+}
+
+.off-sale-card {
+  background: linear-gradient(135deg, #ef4444 0%, #f87171 100%);
+}
+
+.recommended-card {
+  background: linear-gradient(135deg, #ec4899 0%, #f472b6 100%);
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .stat-card {
+    padding: 14px;
+    height: 110px;
+  }
+  
+  .stat-title {
+    font-size: 12px;
+  }
+  
+  .stat-number {
+    font-size: 28px;
+    margin: 4px 0;
+  }
+  
+  .stat-desc {
+    font-size: 10px;
+  }
+}
+
+@media (max-width: 992px) {
+  .stat-card {
+    padding: 16px;
+    height: 120px;
+  }
+  
+  .stat-title {
+    font-size: 13px;
+  }
+  
+  .stat-number {
+    font-size: 30px;
+  }
+  
+  .stat-desc {
+    font-size: 11px;
+  }
+}
+
+@media (max-width: 768px) {
+  .stat-card {
+    padding: 20px;
+    height: 140px;
+  }
+  
+  .stat-title {
+    font-size: 14px;
+  }
+  
+  .stat-number {
+    font-size: 36px;
+    margin: 8px 0;
+  }
+  
+  .stat-desc {
+    font-size: 12px;
+  }
+}
+</style>