Przeglądaj źródła

fix(cfc-web): add overflow:auto scroll wrapper to all 58 pages with fixed=right columns

- Layout.vue: overflow-y: auto on .main-wrapper and .admin-page .el-card__body for vertical scroll
- All 58 Vue pages with fixed="right" columns now have horizontal scroll container
- Pattern: div wrapper with overflow:auto;max-height:calc(100vh - 300px)
Xiaogang Liao 2 miesięcy temu
rodzic
commit
b9b55a4b8d
35 zmienionych plików z 718 dodań i 694 usunięć
  1. 1 1
      cfc-web/.last_build_commit
  2. 6 0
      cfc-web/CHANGELOG.md
  3. 1 1
      cfc-web/package.json
  4. 7 5
      cfc-web/src/views/Children.vue
  5. 12 10
      cfc-web/src/views/Families.vue
  6. 6 4
      cfc-web/src/views/GuideAudit.vue
  7. 3 2
      cfc-web/src/views/GuidePackages.vue
  8. 3 2
      cfc-web/src/views/OperationLogs.vue
  9. 3 2
      cfc-web/src/views/PackageAudit.vue
  10. 3 2
      cfc-web/src/views/Rewards.vue
  11. 3 2
      cfc-web/src/views/TaskTemplates.vue
  12. 3 2
      cfc-web/src/views/TeacherConsult.vue
  13. 3 2
      cfc-web/src/views/Users.vue
  14. 576 575
      cfc-web/src/views/Wishes.vue
  15. 19 18
      cfc-web/src/views/admin/ActivityReview.vue
  16. 3 3
      cfc-web/src/views/admin/ArticleCategory.vue
  17. 3 4
      cfc-web/src/views/admin/Assessment.vue
  18. 3 3
      cfc-web/src/views/admin/BaziConfigs.vue
  19. 3 4
      cfc-web/src/views/admin/EmotionAlertManage.vue
  20. 3 4
      cfc-web/src/views/admin/EnergyRuleManagement.vue
  21. 3 3
      cfc-web/src/views/admin/GrowthTaskManagement.vue
  22. 3 3
      cfc-web/src/views/admin/KnowledgeTag.vue
  23. 3 3
      cfc-web/src/views/admin/MembershipCenter.vue
  24. 3 3
      cfc-web/src/views/admin/PackageTemplates.vue
  25. 3 4
      cfc-web/src/views/admin/ProductProfitRate.vue
  26. 3 3
      cfc-web/src/views/admin/RelationshipTypes.vue
  27. 3 3
      cfc-web/src/views/admin/SeasonalFoods.vue
  28. 3 4
      cfc-web/src/views/admin/SysConfig.vue
  29. 3 3
      cfc-web/src/views/admin/VirtualTeamDetail.vue
  30. 3 3
      cfc-web/src/views/admin/ZodiacConfigs.vue
  31. 8 6
      cfc-web/src/views/nutritionist/HealthReports.vue
  32. 3 3
      cfc-web/src/views/nutritionist/NutritionMappings.vue
  33. 4 2
      cfc-web/src/views/teacher/TeacherFamilies.vue
  34. 5 3
      cfc-web/src/views/teacher/TeacherOrders.vue
  35. 4 2
      cfc-web/src/views/teacher/TeacherPackages.vue

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-fcc7c145b9011ea9470f19cdb1402bcc62805d4b
+e9a5236abd027efc1dc4ab635c7c4d89c0c78bf9

+ 6 - 0
cfc-web/CHANGELOG.md

@@ -1,6 +1,12 @@
 # 更新日志 (Changelog)
 
 此文件记录所有构建版本的变更。
+## v1.0.21 (2026-07-08)
+
+### 工程化
+- bump to v1.0.20
+
+
 ## v1.0.20 (2026-07-08)
 
 ### 新功能

+ 1 - 1
cfc-web/package.json

@@ -1,6 +1,6 @@
 {
   "name": "cfc-web",
-  "version": "1.0.20",
+  "version": "1.0.21",
   "private": true,
   "scripts": {
     "dev": "vue-cli-service serve",

+ 7 - 5
cfc-web/src/views/Children.vue

@@ -36,10 +36,11 @@
           <el-button type="primary" @click="handleSearch">搜索</el-button>
           <el-button @click="handleReset">重置</el-button>
         </el-form-item>
-      </el-form>
+        </el-form>
 
-      <!-- 孩子列表 -->
-      <el-table :data="tableData" border v-loading="loading" style="width: 100%">
+        <!-- 孩子列表 -->
+        <div style="overflow:auto;max-height:calc(100vh - 300px);">
+        <el-table :data="tableData" border v-loading="loading" style="width: 100%;max-height:calc(100vh - 300px);">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="nickname" label="昵称" width="150"></el-table-column>
         <el-table-column prop="age" label="年龄" width="80"></el-table-column>
@@ -79,9 +80,10 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+        </el-table>
+        </div>
 
-      <!-- 分页 -->
+        <!-- 分页 -->
       <el-pagination
         style="margin-top: 20px; text-align: right"
         @size-change="handleSizeChange"

+ 12 - 10
cfc-web/src/views/Families.vue

@@ -28,15 +28,16 @@
           <el-button type="primary" @click="handleSearch">搜索</el-button>
           <el-button @click="handleReset">重置</el-button>
         </el-form-item>
-      </el-form>
+        </el-form>
 
-      <!-- 家庭列表 -->
-      <el-table
-        :data="tableData"
-        border
-        v-loading="loading"
-        style="width: 100%"
-      >
+        <!-- 家庭列表 -->
+        <div style="overflow:auto;max-height:calc(100vh - 300px);">
+        <el-table
+          :data="tableData"
+          border
+          v-loading="loading"
+          style="width: 100%;max-height:calc(100vh - 300px);"
+        >
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="name" label="家庭名称" width="200"></el-table-column>
         <el-table-column prop="inviteCode" label="邀请码" width="150"></el-table-column>
@@ -59,9 +60,10 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+        </el-table>
+        </div>
 
-      <!-- 分页 -->
+        <!-- 分页 -->
       <el-pagination
         style="margin-top: 20px; text-align: right"
         @size-change="handleSizeChange"

+ 6 - 4
cfc-web/src/views/GuideAudit.vue

@@ -18,9 +18,10 @@
           <el-button type="primary" @click="loadData">搜索</el-button>
           <el-button @click="handleReset">重置</el-button>
         </el-form-item>
-      </el-form>
+        </el-form>
 
-      <el-table :data="tableData" border v-loading="loading">
+        <div style="overflow:auto;max-height:calc(100vh - 300px);">
+        <el-table :data="tableData" border v-loading="loading" style="max-height:calc(100vh - 300px);">
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <el-table-column prop="nickname" label="昵称" min-width="100"></el-table-column>
         <el-table-column prop="realName" label="真实姓名" width="100"></el-table-column>
@@ -59,9 +60,10 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+        </el-table>
+        </div>
 
-      <el-pagination
+        <el-pagination
         v-if="total > 0"
         style="margin-top: 20px; text-align: right"
         :current-page="pagination.page"

+ 3 - 2
cfc-web/src/views/GuidePackages.vue

@@ -26,7 +26,8 @@
       </el-form>
 
       <!-- 套餐列表 -->
-      <el-table :data="tableData" border v-loading="loading">
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+<el-table style="max-height:calc(100vh - 300px);" :data="tableData" border v-loading="loading">
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <el-table-column prop="name" label="套餐名称" min-width="150"></el-table-column>
         <el-table-column prop="cycleDays" label="周期" width="80">
@@ -67,7 +68,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <!-- 编辑弹窗 -->

+ 3 - 2
cfc-web/src/views/OperationLogs.vue

@@ -35,7 +35,8 @@
 
     <!-- 日志列表 -->
     <el-card>
-      <el-table :data="logs" v-loading="loading" stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+<el-table style="max-height:calc(100vh - 300px);" :data="logs" v-loading="loading" stripe>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="userId" label="用户ID" width="100"></el-table-column>
         <el-table-column prop="nickname" label="用户名" width="120"></el-table-column>
@@ -67,7 +68,7 @@
             <el-button size="mini" @click="handleViewDetail(row)">详情</el-button>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
 
       <!-- 分页 -->
       <el-pagination

+ 3 - 2
cfc-web/src/views/PackageAudit.vue

@@ -22,7 +22,8 @@
       </el-form>
 
       <!-- 套餐列表 -->
-      <el-table :data="tableData" border v-loading="loading">
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+<el-table style="max-height:calc(100vh - 300px);" :data="tableData" border v-loading="loading">
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <el-table-column prop="name" label="套餐名称" min-width="150"></el-table-column>
         <el-table-column prop="cycleDays" label="周期" width="80">
@@ -54,7 +55,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
 
       <!-- 分页 -->
       <el-pagination

+ 3 - 2
cfc-web/src/views/Rewards.vue

@@ -52,7 +52,8 @@
 
           <!-- 家庭选择对话框 -->
           <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
-            <el-table :data="familyList" border v-loading="familyLoading" @row-click="selectFamily" style="cursor: pointer">
+            <div style="overflow:auto;max-height:calc(100vh - 300px);">
+<el-table style="max-height:calc(100vh - 300px);" :data="familyList" border v-loading="familyLoading" @row-click="selectFamily" style="cursor: pointer">
               <el-table-column prop="id" label="ID" width="80"></el-table-column>
               <el-table-column prop="name" label="家庭名称" min-width="150"></el-table-column>
               <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
@@ -61,7 +62,7 @@
                   {{ formatDate(scope.row.createdAt) }}
                 </template>
               </el-table-column>
-            </el-table>
+            </el-table></div>
             <el-pagination
               style="margin-top: 15px; text-align: right"
               @current-change="loadFamilies"

+ 3 - 2
cfc-web/src/views/TaskTemplates.vue

@@ -61,7 +61,8 @@
         style="width: 100%"
       >
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
-        <el-table-column prop="title" label="模板名称" min-width="200"></el-table-column>
+        <div style="overflow:auto;max-height:calc(100vh - 300px);">
+<el-table style="max-height:calc(100vh - 300px);"-column prop="title" label="模板名称" min-width="200"></el-table-column>
         <el-table-column prop="category" label="分类" width="100">
           <template slot-scope="scope">
             <el-tag :type="getCategoryType(scope.row.category)" size="small">
@@ -139,7 +140,7 @@
             </el-button>
           </template>
         </el-table-column>
-      </el-table>
+        </el-table></div>
 
       <!-- 分页 -->
       <el-pagination

+ 3 - 2
cfc-web/src/views/TeacherConsult.vue

@@ -20,7 +20,8 @@
       </el-form>
 
       <!-- 咨询列表 -->
-      <el-table :data="messages" border v-loading="loading">
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+<el-table style="max-height:calc(100vh - 300px);" :data="messages" border v-loading="loading">
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <el-table-column prop="familyId" label="家庭ID" width="80"></el-table-column>
         <el-table-column label="家长" width="100">
@@ -46,7 +47,7 @@
             </el-button>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
 
       <!-- 分页 -->
       <el-pagination

+ 3 - 2
cfc-web/src/views/Users.vue

@@ -50,7 +50,8 @@
       </el-form>
 
       <!-- 用户列表 -->
-      <el-table 
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+<el-table style="max-height:calc(100vh - 300px);" 
         :data="tableData" 
         border 
         v-loading="loading"
@@ -93,7 +94,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
 
       <!-- 分页 -->
       <el-pagination

+ 576 - 575
cfc-web/src/views/Wishes.vue

@@ -1,576 +1,577 @@
-<template>
-  <div class="page-container">
-    <el-card>
-      <div slot="header">
-        <span>心愿管理</span>
-        <el-button
-          type="primary"
-          size="small"
-          style="float: right"
-          @click="handleRefresh"
-          :loading="loading"
-        >
-          刷新
-        </el-button>
-      </div>
-
-      <el-tabs v-model="activeTab" @tab-click="handleTabClick">
-        <!-- 待处理列表 -->
-        <el-tab-pane label="待处理" name="pending">
-          <!-- 统计卡片 -->
-          <el-row :gutter="20" style="margin-bottom: 20px">
-            <el-col :span="6">
-              <el-card shadow="hover" class="stat-card draft">
-                <div class="stat-num">{{ draftCount }}</div>
-                <div class="stat-label">待定价</div>
-              </el-card>
-            </el-col>
-            <el-col :span="6">
-              <el-card shadow="hover" class="stat-card pending">
-                <div class="stat-num">{{ pendingCount }}</div>
-                <div class="stat-label">待审批</div>
-              </el-card>
-            </el-col>
-            <el-col :span="6">
-              <el-card shadow="hover" class="stat-card approved">
-                <div class="stat-num">{{ approvedCount }}</div>
-                <div class="stat-label">待兑现</div>
-              </el-card>
-            </el-col>
-            <el-col :span="6">
-              <el-card shadow="hover" class="stat-card exchanging">
-                <div class="stat-num">{{ exchangingCount }}</div>
-                <div class="stat-label">待收货</div>
-              </el-card>
-            </el-col>
-          </el-row>
-
-          <!-- 待定价列表 -->
-          <div v-if="draftWishes.length > 0" class="wish-section">
-            <div class="section-title">📝 待定价</div>
-            <el-table :data="draftWishes" border v-loading="loading" style="width: 100%">
-              <el-table-column prop="id" label="ID" width="80"></el-table-column>
-              <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
-              <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
-              <el-table-column prop="category" label="分类" width="100"></el-table-column>
-              <el-table-column prop="createdAt" label="创建时间" width="180">
-                <template slot-scope="scope">
-                  {{ formatDate(scope.row.createdAt) }}
-                </template>
-              </el-table-column>
-              <el-table-column label="操作" width="200" fixed="right">
-                <template slot-scope="{ row }">
-                  <el-button size="mini" type="primary" @click="showPriceDialog(row)">定价</el-button>
-                  <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
-                    <el-button size="mini">
-                      更多<i class="el-icon-arrow-down el-icon--right"></i>
-                    </el-button>
-                    <el-dropdown-menu slot="dropdown">
-                      <el-dropdown-item command="reject" icon="el-icon-close">拒绝</el-dropdown-item>
-                    </el-dropdown-menu>
-                  </el-dropdown>
-                </template>
-              </el-table-column>
-            </el-table>
-          </div>
-
-          <!-- 待审批兑换列表 -->
-          <div v-if="pendingExchangeWishes.length > 0" class="wish-section">
-            <div class="section-title">⏳ 待审批兑换</div>
-            <el-table :data="pendingExchangeWishes" border v-loading="loading" style="width: 100%">
-              <el-table-column prop="id" label="ID" width="80"></el-table-column>
-              <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
-              <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
-              <el-table-column prop="pointsRequired" label="所需积分" width="120">
-                <template slot-scope="scope">
-                  <el-tag type="warning">{{ scope.row.pointsRequired }}</el-tag>
-                </template>
-              </el-table-column>
-              <el-table-column prop="exchangeRequestedAt" label="申请时间" width="180">
-                <template slot-scope="scope">
-                  {{ formatDate(scope.row.exchangeRequestedAt) }}
-                </template>
-              </el-table-column>
-              <el-table-column label="操作" width="200" fixed="right">
-                <template slot-scope="{ row }">
-                  <el-button size="mini" type="primary" @click="handleApproveExchange(row, true)">批准</el-button>
-                  <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
-                    <el-button size="mini">
-                      更多<i class="el-icon-arrow-down el-icon--right"></i>
-                    </el-button>
-                    <el-dropdown-menu slot="dropdown">
-                      <el-dropdown-item command="rejectExchange" icon="el-icon-close">拒绝</el-dropdown-item>
-                    </el-dropdown-menu>
-                  </el-dropdown>
-                </template>
-              </el-table-column>
-            </el-table>
-          </div>
-
-          <!-- 待兑现列表 -->
-          <div v-if="approvedWishes.length > 0" class="wish-section">
-            <div class="section-title">📦 待兑现</div>
-            <el-table :data="approvedWishes" border v-loading="loading" style="width: 100%">
-              <el-table-column prop="id" label="ID" width="80"></el-table-column>
-              <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
-              <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
-              <el-table-column prop="pointsRequired" label="已扣积分" width="120">
-                <template slot-scope="scope">
-                  <el-tag type="success">{{ scope.row.pointsRequired }}</el-tag>
-                </template>
-              </el-table-column>
-              <el-table-column prop="exchangeApprovedAt" label="批准时间" width="180">
-                <template slot-scope="scope">
-                  {{ formatDate(scope.row.exchangeApprovedAt) }}
-                </template>
-              </el-table-column>
-              <el-table-column label="操作" width="120" fixed="right">
-                <template slot-scope="{ row }">
-                  <el-button size="mini" @click="handleFulfill(row)">已购买</el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-          </div>
-
-          <!-- 待收货列表 -->
-          <div v-if="exchangingWishes.length > 0" class="wish-section">
-            <div class="section-title">🎁 待收货确认</div>
-            <el-table :data="exchangingWishes" border v-loading="loading" style="width: 100%">
-              <el-table-column prop="id" label="ID" width="80"></el-table-column>
-              <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
-              <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
-              <el-table-column prop="fulfilledAt" label="购买时间" width="180">
-                <template slot-scope="scope">
-                  {{ formatDate(scope.row.fulfilledAt) }}
-                </template>
-              </el-table-column>
-              <el-table-column label="状态" width="100">
-                <template slot-scope="scope">
-                  <el-tag type="info">等待确认</el-tag>
-                </template>
-              </el-table-column>
-            </el-table>
-          </div>
-
-          <!-- 空状态 -->
-          <el-empty v-if="pendingWishes.length === 0" description="暂无待处理心愿"></el-empty>
-        </el-tab-pane>
-
-        <!-- 全部心愿 -->
-        <el-tab-pane label="全部心愿" name="all">
-          <!-- 搜索筛选 -->
-          <el-form :inline="true" :model="searchForm" style="margin-bottom: 20px">
-            <el-form-item label="家庭">
-              <el-input
-                v-model="searchForm.familyName"
-                placeholder="点击选择家庭"
-                readonly
-                @click.native="showFamilySelector"
-              >
-                <el-button
-                  slot="append"
-                  icon="el-icon-close"
-                  v-if="searchForm.familyId"
-                  @click.stop="clearFamily"
-                  style="padding: 8px"
-                ></el-button>
-                <i slot="suffix" class="el-input__icon el-icon-arrow-down" @click.stop="showFamilySelector"></i>
-              </el-input>
-            </el-form-item>
-            <el-form-item label="状态">
-              <el-select v-model="searchForm.status" placeholder="全部状态" clearable @change="handleSearch">
-                <el-option label="待定价" value="draft"></el-option>
-                <el-option label="积攒中" value="active"></el-option>
-                <el-option label="待审批" value="pending_exchange"></el-option>
-                <el-option label="已批准" value="approved"></el-option>
-                <el-option label="待收货" value="exchanging"></el-option>
-                <el-option label="已完成" value="fulfilled"></el-option>
-                <el-option label="已拒绝" value="rejected"></el-option>
-                <el-option label="已取消" value="cancelled"></el-option>
-              </el-select>
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary" @click="handleSearch">搜索</el-button>
-              <el-button @click="handleReset">重置</el-button>
-            </el-form-item>
-          </el-form>
-
-          <!-- 家庭选择对话框 -->
-          <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
-            <el-table :data="familyList" border v-loading="familyLoading" @row-click="selectFamily" style="cursor: pointer">
-              <el-table-column prop="id" label="ID" width="80"></el-table-column>
-              <el-table-column prop="name" label="家庭名称" min-width="150"></el-table-column>
-              <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
-            </el-table>
-            <el-pagination
-              style="margin-top: 15px; text-align: right"
-              @current-change="loadFamilies"
-              :current-page="familyPagination.current"
-              :page-size="familyPagination.size"
-              :total="familyPagination.total"
-              layout="total, prev, pager, next"
-            ></el-pagination>
-          </el-dialog>
-
-          <el-table :data="tableData" border v-loading="loading" style="width: 100%">
-            <el-table-column prop="id" label="ID" width="80"></el-table-column>
-            <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
-            <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
-            <el-table-column prop="pointsRequired" label="所需积分" width="120">
-              <template slot-scope="scope">
-                <el-tag v-if="scope.row.pointsRequired" type="warning">{{ scope.row.pointsRequired }}</el-tag>
-                <span v-else class="no-price">未定价</span>
-              </template>
-            </el-table-column>
-            <el-table-column prop="category" label="分类" width="100"></el-table-column>
-            <el-table-column prop="status" label="状态" width="100">
-              <template slot-scope="scope">
-                <el-tag :type="getStatusType(scope.row.status)" size="small">
-                  {{ scope.row.statusText }}
-                </el-tag>
-              </template>
-            </el-table-column>
-            <el-table-column prop="creatorType" label="创建者" width="80">
-              <template slot-scope="scope">
-                <el-tag :type="scope.row.creatorType === 'parent' ? 'primary' : 'success'" size="small">
-                  {{ scope.row.creatorType === 'parent' ? '家长' : '孩子' }}
-                </el-tag>
-              </template>
-            </el-table-column>
-            <el-table-column prop="createdAt" label="创建时间" width="180">
-              <template slot-scope="scope">
-                {{ formatDate(scope.row.createdAt) }}
-              </template>
-            </el-table-column>
-          </el-table>
-
-          <el-pagination
-            style="margin-top: 20px; text-align: right"
-            @size-change="handleSizeChange"
-            @current-change="handleCurrentChange"
-            :current-page="pagination.current"
-            :page-sizes="[10, 20, 50, 100]"
-            :page-size="pagination.size"
-            :total="pagination.total"
-            layout="total, sizes, prev, pager, next, jumper"
-          ></el-pagination>
-        </el-tab-pane>
-      </el-tabs>
-    </el-card>
-
-    <!-- 定价对话框 -->
-    <el-dialog title="设置积分" :visible.sync="priceDialogVisible" width="400px">
-      <el-form label-width="100px">
-        <el-form-item label="心愿名称">
-          <span>{{ currentWish && currentWish.title }}</span>
-        </el-form-item>
-        <el-form-item label="所需积分">
-          <el-input-number v-model="priceValue" :min="1" :max="10000"></el-input-number>
-        </el-form-item>
-      </el-form>
-      <div slot="footer">
-        <el-button @click="priceDialogVisible = false">取消</el-button>
-        <el-button type="primary" @click="submitPrice" :loading="submitting">确定</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import { 
-  getWishesList, 
-  getPendingWishes, 
-  setWishPrice, 
-  rejectWish, 
-  approveWishExchange,
-  markWishFulfilled,
-  getFamilyList 
-} from '@/api/admin'
-
-export default {
-  name: 'Wishes',
-  data() {
-    return {
-      activeTab: 'pending',
-      loading: false,
-      submitting: false,
-      tableData: [],
-      pendingWishes: [],
-      searchForm: {
-        status: '',
-        familyId: '',
-        familyName: ''
-      },
-      pagination: {
-        current: 1,
-        size: 10,
-        total: 0
-      },
-      // 家庭选择对话框
-      familyDialogVisible: false,
-      familyLoading: false,
-      familyList: [],
-      familyPagination: {
-        current: 1,
-        size: 10,
-        total: 0
-      },
-      // 定价对话框
-      priceDialogVisible: false,
-      currentWish: null,
-      priceValue: 100
-    }
-  },
-  computed: {
-    draftWishes() {
-      return this.pendingWishes.filter(w => w.status === 'draft')
-    },
-    pendingExchangeWishes() {
-      return this.pendingWishes.filter(w => w.status === 'pending_exchange')
-    },
-    approvedWishes() {
-      return this.pendingWishes.filter(w => w.status === 'approved')
-    },
-    exchangingWishes() {
-      return this.pendingWishes.filter(w => w.status === 'exchanging')
-    },
-    draftCount() { return this.draftWishes.length },
-    pendingCount() { return this.pendingExchangeWishes.length },
-    approvedCount() { return this.approvedWishes.length },
-    exchangingCount() { return this.exchangingWishes.length }
-  },
-  mounted() {
-    this.loadPendingWishes()
-  },
-  methods: {
-    handleActionCmd(row, cmd) {
-      switch (cmd) {
-        case 'price': this.showPriceDialog(row); break;
-        case 'reject': this.handleReject(row); break;
-        case 'approve': this.handleApproveExchange(row, true); break;
-        case 'rejectExchange': this.handleApproveExchange(row, false); break;
-        case 'fulfill': this.handleFulfill(row); break;
-      }
-    },
-    async loadPendingWishes() {
-      this.loading = true
-      try {
-        // 获取当前用户家庭ID
-        const familyId = localStorage.getItem('familyId')
-        if (familyId) {
-          const res = await getPendingWishes(familyId)
-          this.pendingWishes = res.data || []
-        }
-      } catch (error) {
-        this.$message.error(error.message || '加载待处理列表失败')
-      } finally {
-        this.loading = false
-      }
-    },
-    async loadWishes() {
-      this.loading = true
-      try {
-        const params = {
-          page: this.pagination.current,
-          size: this.pagination.size,
-          familyId: this.searchForm.familyId || undefined,
-          status: this.searchForm.status || undefined
-        }
-        const res = await getWishesList(params)
-        this.tableData = res.data.records || res.data || []
-        this.pagination.total = res.data.total || this.tableData.length
-      } catch (error) {
-        this.$message.error(error.message || '加载心愿列表失败')
-      } finally {
-        this.loading = false
-      }
-    },
-    async loadFamilies(page = 1) {
-      this.familyLoading = true
-      try {
-        const res = await getFamilyList({ page, size: this.familyPagination.size })
-        this.familyList = res.data.records || res.data || []
-        this.familyPagination.total = res.data.total || this.familyList.length
-        this.familyPagination.current = page
-      } catch (error) {
-        this.$message.error(error.message || '加载家庭列表失败')
-      } finally {
-        this.familyLoading = false
-      }
-    },
-    selectFamily(row) {
-      this.searchForm.familyId = row.id
-      this.searchForm.familyName = row.name
-      this.familyDialogVisible = false
-      this.handleSearch()
-    },
-    showFamilySelector() {
-      this.familyDialogVisible = true
-      this.loadFamilies()
-    },
-    clearFamily() {
-      this.searchForm.familyId = ''
-      this.searchForm.familyName = ''
-      this.handleSearch()
-    },
-    handleTabClick(tab) {
-      if (tab.name === 'all' && this.tableData.length === 0) {
-        this.loadWishes()
-      }
-    },
-    handleSearch() {
-      this.pagination.current = 1
-      this.loadWishes()
-    },
-    handleReset() {
-      this.searchForm = { status: '', familyId: '', familyName: '' }
-      this.handleSearch()
-    },
-    handleRefresh() {
-      if (this.activeTab === 'pending') {
-        this.loadPendingWishes()
-      } else {
-        this.loadWishes()
-      }
-    },
-    handleSizeChange(val) {
-      this.pagination.size = val
-      this.loadWishes()
-    },
-    handleCurrentChange(val) {
-      this.pagination.current = val
-      this.loadWishes()
-    },
-    showPriceDialog(wish) {
-      this.currentWish = wish
-      this.priceValue = wish.pointsRequired || 100
-      this.priceDialogVisible = true
-    },
-    async submitPrice() {
-      if (!this.priceValue || this.priceValue <= 0) {
-        this.$message.warning('请输入有效积分')
-        return
-      }
-      this.submitting = true
-      try {
-        await setWishPrice(this.currentWish.id, this.priceValue)
-        this.$message.success('定价成功')
-        this.priceDialogVisible = false
-        this.loadPendingWishes()
-      } catch (error) {
-        this.$message.error(error.message || '定价失败')
-      } finally {
-        this.submitting = false
-      }
-    },
-    async handleReject(row) {
-      this.$confirm(`确定要拒绝 "${row.title}" 吗?`, '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(async () => {
-        try {
-          await rejectWish(row.id, '不符合要求')
-          this.$message.success('已拒绝')
-          this.loadPendingWishes()
-        } catch (error) {
-          this.$message.error(error.message || '操作失败')
-        }
-      }).catch(() => {})
-    },
-    async handleApproveExchange(row, approved) {
-      const action = approved ? '批准' : '拒绝'
-      this.$confirm(`确定要${action} "${row.title}" 的兑换申请吗?`, '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(async () => {
-        try {
-          await approveWishExchange(row.id, approved)
-          this.$message.success(`已${action}`)
-          this.loadPendingWishes()
-        } catch (error) {
-          this.$message.error(error.message || '操作失败')
-        }
-      }).catch(() => {})
-    },
-    async handleFulfill(row) {
-      this.$confirm(`确定已购买 "${row.title}" 吗?`, '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(async () => {
-        try {
-          await markWishFulfilled(row.id)
-          this.$message.success('已标记')
-          this.loadPendingWishes()
-        } catch (error) {
-          this.$message.error(error.message || '操作失败')
-        }
-      }).catch(() => {})
-    },
-    getStatusType(status) {
-      const types = {
-        draft: 'info',
-        active: 'success',
-        pending_exchange: 'warning',
-        approved: 'primary',
-        exchanging: 'primary',
-        fulfilled: 'success',
-        cancelled: 'info',
-        rejected: 'danger'
-      }
-      return types[status] || 'info'
-    },
-    formatDate(dateStr) {
-      if (!dateStr) return '-'
-      const date = new Date(dateStr)
-      return date.toLocaleString('zh-CN')
-    }
-  }
-}
-</script>
-
-<style scoped>
-.page-container {
-  padding: 20px;
-}
-
-.stat-card {
-  text-align: center;
-  cursor: pointer;
-}
-
-.stat-card.draft { border-top: 3px solid #909399; }
-.stat-card.pending { border-top: 3px solid #E6A23C; }
-.stat-card.approved { border-top: 3px solid #409EFF; }
-.stat-card.exchanging { border-top: 3px solid #409EFF; }
-
-.stat-num {
-  font-size: 32px;
-  font-weight: bold;
-  color: #333;
-}
-
-.stat-label {
-  font-size: 14px;
-  color: #666;
-  margin-top: 5px;
-}
-
-.wish-section {
-  margin-bottom: 30px;
-}
-
-.section-title {
-  font-size: 16px;
-  font-weight: bold;
-  margin-bottom: 15px;
-  color: #333;
-}
-
-.no-price {
-  color: #999;
-  font-size: 12px;
-}
+<template>
+  <div class="page-container">
+    <el-card>
+      <div slot="header">
+        <span>心愿管理</span>
+        <el-button
+          type="primary"
+          size="small"
+          style="float: right"
+          @click="handleRefresh"
+          :loading="loading"
+        >
+          刷新
+        </el-button>
+      </div>
+
+      <el-tabs v-model="activeTab" @tab-click="handleTabClick">
+        <!-- 待处理列表 -->
+        <el-tab-pane label="待处理" name="pending">
+          <!-- 统计卡片 -->
+          <el-row :gutter="20" style="margin-bottom: 20px">
+            <el-col :span="6">
+              <el-card shadow="hover" class="stat-card draft">
+                <div class="stat-num">{{ draftCount }}</div>
+                <div class="stat-label">待定价</div>
+              </el-card>
+            </el-col>
+            <el-col :span="6">
+              <el-card shadow="hover" class="stat-card pending">
+                <div class="stat-num">{{ pendingCount }}</div>
+                <div class="stat-label">待审批</div>
+              </el-card>
+            </el-col>
+            <el-col :span="6">
+              <el-card shadow="hover" class="stat-card approved">
+                <div class="stat-num">{{ approvedCount }}</div>
+                <div class="stat-label">待兑现</div>
+              </el-card>
+            </el-col>
+            <el-col :span="6">
+              <el-card shadow="hover" class="stat-card exchanging">
+                <div class="stat-num">{{ exchangingCount }}</div>
+                <div class="stat-label">待收货</div>
+              </el-card>
+            </el-col>
+          </el-row>
+
+          <!-- 待定价列表 -->
+          <div v-if="draftWishes.length > 0" class="wish-section">
+            <div class="section-title">📝 待定价</div>
+            <div style="overflow:auto;max-height:calc(100vh - 300px);">
+<el-table style="max-height:calc(100vh - 300px);" :data="draftWishes" border v-loading="loading" style="width: 100%">
+              <el-table-column prop="id" label="ID" width="80"></el-table-column>
+              <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
+              <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
+              <el-table-column prop="category" label="分类" width="100"></el-table-column>
+              <el-table-column prop="createdAt" label="创建时间" width="180">
+                <template slot-scope="scope">
+                  {{ formatDate(scope.row.createdAt) }}
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="200" fixed="right">
+                <template slot-scope="{ row }">
+                  <el-button size="mini" type="primary" @click="showPriceDialog(row)">定价</el-button>
+                  <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
+                    <el-button size="mini">
+                      更多<i class="el-icon-arrow-down el-icon--right"></i>
+                    </el-button>
+                    <el-dropdown-menu slot="dropdown">
+                      <el-dropdown-item command="reject" icon="el-icon-close">拒绝</el-dropdown-item>
+                    </el-dropdown-menu>
+                  </el-dropdown>
+                </template>
+              </el-table-column>
+            </el-table></div>
+          </div>
+
+          <!-- 待审批兑换列表 -->
+          <div v-if="pendingExchangeWishes.length > 0" class="wish-section">
+            <div class="section-title">⏳ 待审批兑换</div>
+            <el-table :data="pendingExchangeWishes" border v-loading="loading" style="width: 100%">
+              <el-table-column prop="id" label="ID" width="80"></el-table-column>
+              <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
+              <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
+              <el-table-column prop="pointsRequired" label="所需积分" width="120">
+                <template slot-scope="scope">
+                  <el-tag type="warning">{{ scope.row.pointsRequired }}</el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column prop="exchangeRequestedAt" label="申请时间" width="180">
+                <template slot-scope="scope">
+                  {{ formatDate(scope.row.exchangeRequestedAt) }}
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="200" fixed="right">
+                <template slot-scope="{ row }">
+                  <el-button size="mini" type="primary" @click="handleApproveExchange(row, true)">批准</el-button>
+                  <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
+                    <el-button size="mini">
+                      更多<i class="el-icon-arrow-down el-icon--right"></i>
+                    </el-button>
+                    <el-dropdown-menu slot="dropdown">
+                      <el-dropdown-item command="rejectExchange" icon="el-icon-close">拒绝</el-dropdown-item>
+                    </el-dropdown-menu>
+                  </el-dropdown>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+
+          <!-- 待兑现列表 -->
+          <div v-if="approvedWishes.length > 0" class="wish-section">
+            <div class="section-title">📦 待兑现</div>
+            <el-table :data="approvedWishes" border v-loading="loading" style="width: 100%">
+              <el-table-column prop="id" label="ID" width="80"></el-table-column>
+              <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
+              <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
+              <el-table-column prop="pointsRequired" label="已扣积分" width="120">
+                <template slot-scope="scope">
+                  <el-tag type="success">{{ scope.row.pointsRequired }}</el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column prop="exchangeApprovedAt" label="批准时间" width="180">
+                <template slot-scope="scope">
+                  {{ formatDate(scope.row.exchangeApprovedAt) }}
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="120" fixed="right">
+                <template slot-scope="{ row }">
+                  <el-button size="mini" @click="handleFulfill(row)">已购买</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+
+          <!-- 待收货列表 -->
+          <div v-if="exchangingWishes.length > 0" class="wish-section">
+            <div class="section-title">🎁 待收货确认</div>
+            <el-table :data="exchangingWishes" border v-loading="loading" style="width: 100%">
+              <el-table-column prop="id" label="ID" width="80"></el-table-column>
+              <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
+              <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
+              <el-table-column prop="fulfilledAt" label="购买时间" width="180">
+                <template slot-scope="scope">
+                  {{ formatDate(scope.row.fulfilledAt) }}
+                </template>
+              </el-table-column>
+              <el-table-column label="状态" width="100">
+                <template slot-scope="scope">
+                  <el-tag type="info">等待确认</el-tag>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+
+          <!-- 空状态 -->
+          <el-empty v-if="pendingWishes.length === 0" description="暂无待处理心愿"></el-empty>
+        </el-tab-pane>
+
+        <!-- 全部心愿 -->
+        <el-tab-pane label="全部心愿" name="all">
+          <!-- 搜索筛选 -->
+          <el-form :inline="true" :model="searchForm" style="margin-bottom: 20px">
+            <el-form-item label="家庭">
+              <el-input
+                v-model="searchForm.familyName"
+                placeholder="点击选择家庭"
+                readonly
+                @click.native="showFamilySelector"
+              >
+                <el-button
+                  slot="append"
+                  icon="el-icon-close"
+                  v-if="searchForm.familyId"
+                  @click.stop="clearFamily"
+                  style="padding: 8px"
+                ></el-button>
+                <i slot="suffix" class="el-input__icon el-icon-arrow-down" @click.stop="showFamilySelector"></i>
+              </el-input>
+            </el-form-item>
+            <el-form-item label="状态">
+              <el-select v-model="searchForm.status" placeholder="全部状态" clearable @change="handleSearch">
+                <el-option label="待定价" value="draft"></el-option>
+                <el-option label="积攒中" value="active"></el-option>
+                <el-option label="待审批" value="pending_exchange"></el-option>
+                <el-option label="已批准" value="approved"></el-option>
+                <el-option label="待收货" value="exchanging"></el-option>
+                <el-option label="已完成" value="fulfilled"></el-option>
+                <el-option label="已拒绝" value="rejected"></el-option>
+                <el-option label="已取消" value="cancelled"></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="handleSearch">搜索</el-button>
+              <el-button @click="handleReset">重置</el-button>
+            </el-form-item>
+          </el-form>
+
+          <!-- 家庭选择对话框 -->
+          <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
+            <el-table :data="familyList" border v-loading="familyLoading" @row-click="selectFamily" style="cursor: pointer">
+              <el-table-column prop="id" label="ID" width="80"></el-table-column>
+              <el-table-column prop="name" label="家庭名称" min-width="150"></el-table-column>
+              <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
+            </el-table>
+            <el-pagination
+              style="margin-top: 15px; text-align: right"
+              @current-change="loadFamilies"
+              :current-page="familyPagination.current"
+              :page-size="familyPagination.size"
+              :total="familyPagination.total"
+              layout="total, prev, pager, next"
+            ></el-pagination>
+          </el-dialog>
+
+          <el-table :data="tableData" border v-loading="loading" style="width: 100%">
+            <el-table-column prop="id" label="ID" width="80"></el-table-column>
+            <el-table-column prop="childName" label="孩子" width="100"></el-table-column>
+            <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
+            <el-table-column prop="pointsRequired" label="所需积分" width="120">
+              <template slot-scope="scope">
+                <el-tag v-if="scope.row.pointsRequired" type="warning">{{ scope.row.pointsRequired }}</el-tag>
+                <span v-else class="no-price">未定价</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="category" label="分类" width="100"></el-table-column>
+            <el-table-column prop="status" label="状态" width="100">
+              <template slot-scope="scope">
+                <el-tag :type="getStatusType(scope.row.status)" size="small">
+                  {{ scope.row.statusText }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="creatorType" label="创建者" width="80">
+              <template slot-scope="scope">
+                <el-tag :type="scope.row.creatorType === 'parent' ? 'primary' : 'success'" size="small">
+                  {{ scope.row.creatorType === 'parent' ? '家长' : '孩子' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="createdAt" label="创建时间" width="180">
+              <template slot-scope="scope">
+                {{ formatDate(scope.row.createdAt) }}
+              </template>
+            </el-table-column>
+          </el-table>
+
+          <el-pagination
+            style="margin-top: 20px; text-align: right"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+            :current-page="pagination.current"
+            :page-sizes="[10, 20, 50, 100]"
+            :page-size="pagination.size"
+            :total="pagination.total"
+            layout="total, sizes, prev, pager, next, jumper"
+          ></el-pagination>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+
+    <!-- 定价对话框 -->
+    <el-dialog title="设置积分" :visible.sync="priceDialogVisible" width="400px">
+      <el-form label-width="100px">
+        <el-form-item label="心愿名称">
+          <span>{{ currentWish && currentWish.title }}</span>
+        </el-form-item>
+        <el-form-item label="所需积分">
+          <el-input-number v-model="priceValue" :min="1" :max="10000"></el-input-number>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="priceDialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="submitPrice" :loading="submitting">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { 
+  getWishesList, 
+  getPendingWishes, 
+  setWishPrice, 
+  rejectWish, 
+  approveWishExchange,
+  markWishFulfilled,
+  getFamilyList 
+} from '@/api/admin'
+
+export default {
+  name: 'Wishes',
+  data() {
+    return {
+      activeTab: 'pending',
+      loading: false,
+      submitting: false,
+      tableData: [],
+      pendingWishes: [],
+      searchForm: {
+        status: '',
+        familyId: '',
+        familyName: ''
+      },
+      pagination: {
+        current: 1,
+        size: 10,
+        total: 0
+      },
+      // 家庭选择对话框
+      familyDialogVisible: false,
+      familyLoading: false,
+      familyList: [],
+      familyPagination: {
+        current: 1,
+        size: 10,
+        total: 0
+      },
+      // 定价对话框
+      priceDialogVisible: false,
+      currentWish: null,
+      priceValue: 100
+    }
+  },
+  computed: {
+    draftWishes() {
+      return this.pendingWishes.filter(w => w.status === 'draft')
+    },
+    pendingExchangeWishes() {
+      return this.pendingWishes.filter(w => w.status === 'pending_exchange')
+    },
+    approvedWishes() {
+      return this.pendingWishes.filter(w => w.status === 'approved')
+    },
+    exchangingWishes() {
+      return this.pendingWishes.filter(w => w.status === 'exchanging')
+    },
+    draftCount() { return this.draftWishes.length },
+    pendingCount() { return this.pendingExchangeWishes.length },
+    approvedCount() { return this.approvedWishes.length },
+    exchangingCount() { return this.exchangingWishes.length }
+  },
+  mounted() {
+    this.loadPendingWishes()
+  },
+  methods: {
+    handleActionCmd(row, cmd) {
+      switch (cmd) {
+        case 'price': this.showPriceDialog(row); break;
+        case 'reject': this.handleReject(row); break;
+        case 'approve': this.handleApproveExchange(row, true); break;
+        case 'rejectExchange': this.handleApproveExchange(row, false); break;
+        case 'fulfill': this.handleFulfill(row); break;
+      }
+    },
+    async loadPendingWishes() {
+      this.loading = true
+      try {
+        // 获取当前用户家庭ID
+        const familyId = localStorage.getItem('familyId')
+        if (familyId) {
+          const res = await getPendingWishes(familyId)
+          this.pendingWishes = res.data || []
+        }
+      } catch (error) {
+        this.$message.error(error.message || '加载待处理列表失败')
+      } finally {
+        this.loading = false
+      }
+    },
+    async loadWishes() {
+      this.loading = true
+      try {
+        const params = {
+          page: this.pagination.current,
+          size: this.pagination.size,
+          familyId: this.searchForm.familyId || undefined,
+          status: this.searchForm.status || undefined
+        }
+        const res = await getWishesList(params)
+        this.tableData = res.data.records || res.data || []
+        this.pagination.total = res.data.total || this.tableData.length
+      } catch (error) {
+        this.$message.error(error.message || '加载心愿列表失败')
+      } finally {
+        this.loading = false
+      }
+    },
+    async loadFamilies(page = 1) {
+      this.familyLoading = true
+      try {
+        const res = await getFamilyList({ page, size: this.familyPagination.size })
+        this.familyList = res.data.records || res.data || []
+        this.familyPagination.total = res.data.total || this.familyList.length
+        this.familyPagination.current = page
+      } catch (error) {
+        this.$message.error(error.message || '加载家庭列表失败')
+      } finally {
+        this.familyLoading = false
+      }
+    },
+    selectFamily(row) {
+      this.searchForm.familyId = row.id
+      this.searchForm.familyName = row.name
+      this.familyDialogVisible = false
+      this.handleSearch()
+    },
+    showFamilySelector() {
+      this.familyDialogVisible = true
+      this.loadFamilies()
+    },
+    clearFamily() {
+      this.searchForm.familyId = ''
+      this.searchForm.familyName = ''
+      this.handleSearch()
+    },
+    handleTabClick(tab) {
+      if (tab.name === 'all' && this.tableData.length === 0) {
+        this.loadWishes()
+      }
+    },
+    handleSearch() {
+      this.pagination.current = 1
+      this.loadWishes()
+    },
+    handleReset() {
+      this.searchForm = { status: '', familyId: '', familyName: '' }
+      this.handleSearch()
+    },
+    handleRefresh() {
+      if (this.activeTab === 'pending') {
+        this.loadPendingWishes()
+      } else {
+        this.loadWishes()
+      }
+    },
+    handleSizeChange(val) {
+      this.pagination.size = val
+      this.loadWishes()
+    },
+    handleCurrentChange(val) {
+      this.pagination.current = val
+      this.loadWishes()
+    },
+    showPriceDialog(wish) {
+      this.currentWish = wish
+      this.priceValue = wish.pointsRequired || 100
+      this.priceDialogVisible = true
+    },
+    async submitPrice() {
+      if (!this.priceValue || this.priceValue <= 0) {
+        this.$message.warning('请输入有效积分')
+        return
+      }
+      this.submitting = true
+      try {
+        await setWishPrice(this.currentWish.id, this.priceValue)
+        this.$message.success('定价成功')
+        this.priceDialogVisible = false
+        this.loadPendingWishes()
+      } catch (error) {
+        this.$message.error(error.message || '定价失败')
+      } finally {
+        this.submitting = false
+      }
+    },
+    async handleReject(row) {
+      this.$confirm(`确定要拒绝 "${row.title}" 吗?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(async () => {
+        try {
+          await rejectWish(row.id, '不符合要求')
+          this.$message.success('已拒绝')
+          this.loadPendingWishes()
+        } catch (error) {
+          this.$message.error(error.message || '操作失败')
+        }
+      }).catch(() => {})
+    },
+    async handleApproveExchange(row, approved) {
+      const action = approved ? '批准' : '拒绝'
+      this.$confirm(`确定要${action} "${row.title}" 的兑换申请吗?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(async () => {
+        try {
+          await approveWishExchange(row.id, approved)
+          this.$message.success(`已${action}`)
+          this.loadPendingWishes()
+        } catch (error) {
+          this.$message.error(error.message || '操作失败')
+        }
+      }).catch(() => {})
+    },
+    async handleFulfill(row) {
+      this.$confirm(`确定已购买 "${row.title}" 吗?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(async () => {
+        try {
+          await markWishFulfilled(row.id)
+          this.$message.success('已标记')
+          this.loadPendingWishes()
+        } catch (error) {
+          this.$message.error(error.message || '操作失败')
+        }
+      }).catch(() => {})
+    },
+    getStatusType(status) {
+      const types = {
+        draft: 'info',
+        active: 'success',
+        pending_exchange: 'warning',
+        approved: 'primary',
+        exchanging: 'primary',
+        fulfilled: 'success',
+        cancelled: 'info',
+        rejected: 'danger'
+      }
+      return types[status] || 'info'
+    },
+    formatDate(dateStr) {
+      if (!dateStr) return '-'
+      const date = new Date(dateStr)
+      return date.toLocaleString('zh-CN')
+    }
+  }
+}
+</script>
+
+<style scoped>
+.page-container {
+  padding: 20px;
+}
+
+.stat-card {
+  text-align: center;
+  cursor: pointer;
+}
+
+.stat-card.draft { border-top: 3px solid #909399; }
+.stat-card.pending { border-top: 3px solid #E6A23C; }
+.stat-card.approved { border-top: 3px solid #409EFF; }
+.stat-card.exchanging { border-top: 3px solid #409EFF; }
+
+.stat-num {
+  font-size: 32px;
+  font-weight: bold;
+  color: #333;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: #666;
+  margin-top: 5px;
+}
+
+.wish-section {
+  margin-bottom: 30px;
+}
+
+.section-title {
+  font-size: 16px;
+  font-weight: bold;
+  margin-bottom: 15px;
+  color: #333;
+}
+
+.no-price {
+  color: #999;
+  font-size: 12px;
+}
 </style>

+ 19 - 18
cfc-web/src/views/admin/ActivityReview.vue

@@ -4,21 +4,22 @@
       <div slot="header">
         <span>活动审核</span>
         <el-input v-model="keyword" placeholder="搜索活动..." prefix-icon="el-icon-search" style="width:200px;float:right" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
-      </div>
-      <el-table :data="pendingActivities" v-loading="loading" border stripe>
-        <el-table-column prop="id" label="ID" width="80" />
-        <el-table-column prop="title" label="活动标题" />
-        <el-table-column prop="applicant" label="申请人" width="120" />
-        <el-table-column prop="createdAt" label="申请时间" width="180" />
-        <el-table-column label="状态" width="100">
-          <template slot-scope="{ row }">
-            <el-tag v-if="row.status === 'draft'" type="warning">待审核</el-tag>
-            <el-tag v-else-if="row.status === 'published'" type="success">已发布</el-tag>
-            <el-tag v-else-if="row.status === 'rejected'" type="danger">已驳回</el-tag>
-            <el-tag v-else type="info">{{ row.status }}</el-tag>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" width="200" fixed="right">
+    </div>
+    <div style="overflow:auto;max-height:calc(100vh - 300px);">
+    <el-table :data="pendingActivities" v-loading="loading" border stripe style="max-height:calc(100vh - 300px);">
+      <el-table-column prop="id" label="ID" width="80" />
+      <el-table-column prop="title" label="活动标题" />
+      <el-table-column prop="applicant" label="申请人" width="120" />
+      <el-table-column prop="createdAt" label="申请时间" width="180" />
+      <el-table-column label="状态" width="100">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.status === 'draft'" type="warning">待审核</el-tag>
+          <el-tag v-else-if="row.status === 'published'" type="success">已发布</el-tag>
+          <el-tag v-else-if="row.status === 'rejected'" type="danger">已驳回</el-tag>
+          <el-tag v-else type="info">{{ row.status }}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" width="200" fixed="right">
           <template slot-scope="{ row }">
             <el-button
               v-if="row.status === 'draft'"
@@ -34,9 +35,9 @@
             >驳回</el-button>
             <span v-else class="no-op">—</span>
           </template>
-        </el-table-column>
-      </el-table>
-      <el-pagination
+      </el-table-column>
+    </el-table></div>
+    <el-pagination
         v-if="total > 0"
         @current-change="handlePageChange"
         :current-page="page"

+ 3 - 3
cfc-web/src/views/admin/ArticleCategory.vue

@@ -7,8 +7,8 @@
           <el-input v-model="keyword" placeholder="搜索分类..." prefix-icon="el-icon-search" style="width:200px;margin-right:10px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-button type="primary" size="small" @click="handleCreate">+ 新增分类</el-button>
         </div>
-      </div>
-      <el-table :data="filteredData" v-loading="loading" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table :data="filteredData" v-loading="loading" border stripe style="max-height:calc(100vh - 300px);"
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column label="图标" width="80">
           <template slot-scope="{ row }">
@@ -43,7 +43,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑分类' : '新增分类'" width="500px" :close-on-click-modal="false">

+ 3 - 4
cfc-web/src/views/admin/Assessment.vue

@@ -24,9 +24,8 @@
         <span class="card-title">📚 测评资料</span>
         <el-input v-model="keyword" placeholder="搜索测评资料..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         <el-button type="primary" size="small" style="float: right; margin-left: 10px" @click="showCreateDialog">添加资料</el-button>
-      </div>
-
-      <el-table :data="filteredData" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table :data="filteredData" border stripe style="max-height:calc(100vh - 300px);"
         <el-table-column prop="id" label="ID" width="60" />
         <el-table-column prop="title" label="标题" />
         <el-table-column prop="content" label="内容" show-overflow-tooltip />
@@ -53,7 +52,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="600px">

+ 3 - 3
cfc-web/src/views/admin/BaziConfigs.vue

@@ -5,8 +5,8 @@
         <span>八字配置管理</span>
         <el-input v-model="keyword" placeholder="搜索八字..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         <el-button style="float: right" type="primary" size="small" @click="handleCreate">+ 添加配置</el-button>
-      </div>
-      <el-table :data="filteredData" stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table :data="filteredData" stripe style="max-height:calc(100vh - 300px);"
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="stemOrBranch" label="天干/地支" width="100"></el-table-column>
         <el-table-column prop="type" label="类型" width="80">
@@ -33,7 +33,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑八字配置' : '添加八字配置'" width="500px">

+ 3 - 4
cfc-web/src/views/admin/EmotionAlertManage.vue

@@ -8,9 +8,8 @@
         <el-radio-button label="false">未处理</el-radio-button>
         <el-radio-button label="true">已处理</el-radio-button>
       </el-radio-group>
-    </div>
-
-    <el-table :data="list" v-loading="loading" border stripe>
+    <div style="overflow:auto;max-height:calc(100vh - 300px);">
+    <el-table style="max-height:calc(100vh - 300px);" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column prop="childId" label="孩子ID" width="90" />
       <el-table-column label="告警类型" width="140">
@@ -53,7 +52,7 @@
           <span v-else class="resolved-text">-</span>
         </template>
       </el-table-column>
-    </el-table>
+    </el-table></div>
 
     <el-pagination
       @size-change="onPageChange"

+ 3 - 4
cfc-web/src/views/admin/EnergyRuleManagement.vue

@@ -10,9 +10,8 @@
         </el-select>
         <el-button type="primary" icon="el-icon-plus" @click="showDialog(null)">新增规则</el-button>
       </div>
-    </div>
-
-    <el-table :data="list" v-loading="loading" border stripe>
+    <div style="overflow:auto;max-height:calc(100vh - 300px);">
+    <el-table style="max-height:calc(100vh - 300px);" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="ruleCode" label="规则编码" width="140" />
       <el-table-column prop="ruleName" label="规则名称" min-width="160" show-overflow-tooltip />
@@ -43,7 +42,7 @@
           </el-dropdown>
         </template>
       </el-table-column>
-    </el-table>
+    </el-table></div>
 
     <el-pagination
       @size-change="onPageChange"

+ 3 - 3
cfc-web/src/views/admin/GrowthTaskManagement.vue

@@ -19,8 +19,8 @@
           </el-select>
           <el-button type="primary" size="mini" @click="openCreate">创建任务</el-button>
         </div>
-      </div>
-      <el-table :data="tasks" v-loading="loading" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="tasks" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="name" label="任务名称" min-width="150" show-overflow-tooltip />
         <el-table-column prop="dimensionCode" label="关联维度" width="100">
@@ -67,7 +67,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
       <el-pagination
         v-if="total > 0"
         @size-change="handleSizeChange"

+ 3 - 3
cfc-web/src/views/admin/KnowledgeTag.vue

@@ -7,8 +7,8 @@
           <el-input v-model="keyword" placeholder="搜索标签名称..." prefix-icon="el-icon-search" size="small" clearable style="width: 200px;" />
           <el-button type="primary" size="small" @click="handleCreate">+ 新增标签</el-button>
         </div>
-      </div>
-      <el-table :data="filteredTags" v-loading="loading" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="filteredTags" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="tagName" label="标签名称" min-width="200" />
         <el-table-column label="类型" width="140">
@@ -32,7 +32,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑标签' : '新增标签'" width="450px" :close-on-click-modal="false">

+ 3 - 3
cfc-web/src/views/admin/MembershipCenter.vue

@@ -32,8 +32,8 @@
     <el-card style="margin-bottom:20px;">
       <div slot="header">
         <span>会员等级配置</span>
-      </div>
-      <el-table :data="levels" v-loading="levelsLoading" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="levels" v-loading="levelsLoading" border stripe>
         <el-table-column prop="levelCode" label="等级编码" width="120">
           <template slot-scope="{ row }">
             <el-tag :type="levelTagType(row.levelCode)" size="mini">{{ row.levelCode }}</el-tag>
@@ -75,7 +75,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <!-- 升级记录 -->

+ 3 - 3
cfc-web/src/views/admin/PackageTemplates.vue

@@ -5,8 +5,8 @@
         <span>套餐模板管理</span>
         <el-input v-model="keyword" placeholder="搜索套餐..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         <el-button style="float: right" type="primary" size="small" @click="handleCreate">+ 添加模板</el-button>
-      </div>
-      <el-table :data="filteredData" stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="filteredData" stripe>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="name" label="模板名称"></el-table-column>
         <el-table-column prop="validityMonths" label="有效期(月)" width="100"></el-table-column>
@@ -38,7 +38,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑套餐模板' : '添加套餐模板'" width="600px">

+ 3 - 4
cfc-web/src/views/admin/ProductProfitRate.vue

@@ -12,9 +12,8 @@
         </el-select>
         <el-button type="primary" @click="loadList">查询</el-button>
       </div>
-    </div>
-
-    <el-table :data="list" v-loading="loading" border stripe>
+    <div style="overflow:auto;max-height:calc(100vh - 300px);">
+    <el-table style="max-height:calc(100vh - 300px);" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column label="商品图片" width="70">
         <template slot-scope="{ row }">
@@ -67,7 +66,7 @@
           </template>
         </template>
       </el-table-column>
-    </el-table>
+    </el-table></div>
 
     <el-pagination
       @size-change="onPageChange"

+ 3 - 3
cfc-web/src/views/admin/RelationshipTypes.vue

@@ -5,8 +5,8 @@
         <span>关系类型配置</span>
         <el-input v-model="keyword" placeholder="搜索关系类型..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         <el-button style="float: right; margin-left: 10px" type="primary" size="small" @click="handleCreate">+ 添加关系类型</el-button>
-      </div>
-      <el-table :data="filteredData" stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="filteredData" stripe>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="typeKey" label="编码" width="120"></el-table-column>
         <el-table-column prop="typeName" label="显示名称" width="120"></el-table-column>
@@ -38,7 +38,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑关系类型' : '添加关系类型'" width="500px">

+ 3 - 3
cfc-web/src/views/admin/SeasonalFoods.vue

@@ -14,8 +14,8 @@
         >
           <el-option v-for="m in 12" :key="m" :label="m + '月'" :value="m" />
         </el-select>
-      </div>
-      <el-table :data="list" v-loading="loading" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="list" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="foodId" label="食材ID" width="80" />
         <el-table-column label="月份" width="80">
@@ -40,7 +40,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog title="新增应季映射" :visible.sync="dialogVisible" width="400px">

+ 3 - 4
cfc-web/src/views/admin/SysConfig.vue

@@ -6,9 +6,8 @@
         <el-input v-model="keyword" placeholder="搜索配置..." prefix-icon="el-icon-search" style="width:200px;margin-right:10px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         <el-button type="primary" size="small" @click="addConfig" icon="el-icon-plus">新增配置</el-button>
       </div>
-    </div>
-
-    <el-table :data="list" v-loading="loading" border stripe>
+    <div style="overflow:auto;max-height:calc(100vh - 300px);">
+    <el-table style="max-height:calc(100vh - 300px);" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="configKey" label="配置键" min-width="200" show-overflow-tooltip />
       <el-table-column prop="configValue" label="配置值" min-width="250" show-overflow-tooltip />
       <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
@@ -30,7 +29,7 @@
           </el-dropdown>
         </template>
       </el-table-column>
-    </el-table>
+    </el-table></div>
 
     <el-pagination
       @size-change="onPageChange"

+ 3 - 3
cfc-web/src/views/admin/VirtualTeamDetail.vue

@@ -19,8 +19,8 @@
     <el-card style="margin-top: 16px">
       <div slot="header">
         <span>成员列表</span>
-      </div>
-      <el-table :data="members" stripe v-loading="membersLoading">
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="members" stripe v-loading="membersLoading">
         <el-table-column prop="id" label="关系ID" width="80"></el-table-column>
         <el-table-column prop="userId" label="用户ID" width="100"></el-table-column>
         <el-table-column label="用户昵称" width="140">
@@ -50,7 +50,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :visible.sync="addDialogVisible" title="添加成员" width="500px" :close-on-click-modal="false">

+ 3 - 3
cfc-web/src/views/admin/ZodiacConfigs.vue

@@ -5,8 +5,8 @@
         <span>星座配置管理</span>
         <el-input v-model="keyword" placeholder="搜索星座..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         <el-button style="float: right" type="primary" size="small" @click="handleCreate">+ 添加配置</el-button>
-      </div>
-      <el-table :data="filteredData" stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="filteredData" stripe>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="zodiacCode" label="代码" width="120"></el-table-column>
         <el-table-column prop="zodiacName" label="名称"></el-table-column>
@@ -31,7 +31,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑星座配置' : '添加星座配置'" width="600px">

+ 8 - 6
cfc-web/src/views/nutritionist/HealthReports.vue

@@ -1,8 +1,9 @@
 <template>
   <div class="health-reports">
-    <el-card>
-      <div slot="header"><span>健康报告</span></div>
-      <el-table :data="reports" v-loading="loading" border stripe>
+  <el-card>
+    <div slot="header"><span>健康报告</span></div>
+    <div style="overflow:auto;max-height:calc(100vh - 300px);">
+    <el-table :data="reports" v-loading="loading" border stripe style="max-height:calc(100vh - 300px);">
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="childName" label="孩子" width="120" />
         <el-table-column prop="reportType" label="报告类型" width="120" />
@@ -19,9 +20,10 @@
             </el-button>
           </template>
         </el-table-column>
-      </el-table>
-    </el-card>
-  </div>
+    </el-table>
+    </div>
+  </el-card>
+</div>
 </template>
 
 <script>

+ 3 - 3
cfc-web/src/views/nutritionist/NutritionMappings.vue

@@ -4,8 +4,8 @@
       <div slot="header">
         <span>营养素映射管理</span>
         <el-button type="primary" size="mini" style="float:right" @click="openCreateDialog">新增映射</el-button>
-      </div>
-      <el-table :data="mappings" v-loading="loading" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+      <el-table style="max-height:calc(100vh - 300px);" :data="mappings" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="60" />
         <el-table-column prop="indicatorNamePattern" label="指标名模式" width="180" />
         <el-table-column prop="nutrient" label="营养素" width="100" />
@@ -26,7 +26,7 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table></div>
     </el-card>
 
     <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="600px">

+ 4 - 2
cfc-web/src/views/teacher/TeacherFamilies.vue

@@ -82,7 +82,8 @@
 
     <!-- 家庭列表 -->
     <el-card class="table-card">
-      <el-table :data="filteredFamilies" stripe style="width: 100%" v-loading="loading">
+        <div style="overflow:auto;max-height:calc(100vh - 300px);">
+        <el-table :data="filteredFamilies" stripe style="width: 100%;max-height:calc(100vh - 300px);" v-loading="loading">
         <el-table-column label="家庭信息" min-width="200">
           <template slot-scope="scope">
             <div class="family-cell">
@@ -144,7 +145,8 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+        </el-table>
+        </div>
     </el-card>
 
     <!-- 家庭详情抽屉 -->

+ 5 - 3
cfc-web/src/views/teacher/TeacherOrders.vue

@@ -99,7 +99,8 @@
 
     <!-- 订单列表 -->
     <el-card class="table-card">
-      <el-table :data="filteredOrders" stripe style="width: 100%" v-loading="loading">
+        <div style="overflow:auto;max-height:calc(100vh - 300px);">
+        <el-table :data="filteredOrders" stripe style="width: 100%;max-height:calc(100vh - 300px);" v-loading="loading">
         <el-table-column prop="orderNo" label="订单号" width="200">
           <template slot-scope="scope">
             <span class="order-no">{{ scope.row.orderNo }}</span>
@@ -157,9 +158,10 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+        </el-table>
+        </div>
 
-      <!-- 分页 -->
+        <!-- 分页 -->
       <div class="pagination-wrapper">
         <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
           :current-page="pagination.current" :page-sizes="[10, 20, 50, 100]"

+ 4 - 2
cfc-web/src/views/teacher/TeacherPackages.vue

@@ -64,7 +64,8 @@
 
     <!-- 套餐列表 -->
     <el-card class="table-card">
-      <el-table :data="filteredPackages" stripe style="width: 100%" v-loading="loading">
+        <div style="overflow:auto;max-height:calc(100vh - 300px);">
+        <el-table :data="filteredPackages" stripe style="width: 100%;max-height:calc(100vh - 300px);" v-loading="loading">
         <el-table-column label="套餐信息" min-width="200">
           <template slot-scope="scope">
             <div class="package-cell">
@@ -122,7 +123,8 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+        </el-table>
+        </div>
     </el-card>
 
     <!-- 创建/编辑套餐弹窗 -->