Просмотр исходного кода

Merge branch 'refs/heads/cfclub-jiapu' into cfclub

# Conflicts:
#	cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java
#	cfc-backend/src/main/resources/schema.sql
#	cfc-frontend/components/DimensionActivities.vue
#	cfc-frontend/components/DimensionProducts.vue
#	cfc-web/.last_build_commit
#	cfc-web/package.json
#	cfc-web/public/CHANGELOG.md
jiapu 3 месяцев назад
Родитель
Сommit
0c949900f8
100 измененных файлов с 995 добавлено и 261 удалено
  1. 15 0
      cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java
  2. 13 2
      cfc-backend/src/main/java/com/etotem/cfc/controller/DanAssessmentController.java
  3. 99 0
      cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminController.java
  4. 2 1
      cfc-backend/src/main/java/com/etotem/cfc/controller/assessment/AssessmentAppointmentController.java
  5. 4 0
      cfc-backend/src/main/java/com/etotem/cfc/entity/AssessmentAppointment.java
  6. 6 2
      cfc-backend/src/main/java/com/etotem/cfc/service/AssessmentAppointmentService.java
  7. 1 1
      cfc-backend/src/main/resources/schema.sql
  8. 1 1
      cfc-frontend/components/ActionArticleRecommend.vue
  9. 1 1
      cfc-frontend/components/ContactCard.vue
  10. 1 1
      cfc-frontend/components/HealthDimensionsSection.vue
  11. 1 1
      cfc-frontend/components/member-detail-sections/mind-section.vue
  12. 1 1
      cfc-frontend/config.js
  13. 3 3
      cfc-frontend/pages/health/report-confirm.vue
  14. 1 1
      cfc-frontend/pages/index/index.vue
  15. 1 1
      cfc-frontend/pages/index/parent-index.vue
  16. 51 20
      cfc-frontend/pages/profile-extra/edit-child.vue
  17. 5 1
      cfc-frontend/pages/profile-extra/family-members.vue
  18. 1 1
      cfc-frontend/pages/shop/address-edit/address-edit.vue
  19. 1 1
      cfc-web/.env.development
  20. 18 0
      cfc-web/public/CHANGELOG-v$(node.undefined.md
  21. 25 0
      cfc-web/src/api/admin.js
  22. 6 0
      cfc-web/src/router/index.js
  23. 7 3
      cfc-web/src/views/Children.vue
  24. 10 3
      cfc-web/src/views/Families.vue
  25. 11 8
      cfc-web/src/views/GuideFamilyTask.vue
  26. 8 4
      cfc-web/src/views/GuidePackages.vue
  27. 1 4
      cfc-web/src/views/Layout.vue
  28. 7 3
      cfc-web/src/views/OperationLogs.vue
  29. 7 1
      cfc-web/src/views/Points.vue
  30. 12 7
      cfc-web/src/views/Rewards.vue
  31. 9 3
      cfc-web/src/views/TaskTemplates.vue
  32. 8 2
      cfc-web/src/views/Tasks.vue
  33. 5 3
      cfc-web/src/views/TeacherConsult.vue
  34. 10 3
      cfc-web/src/views/Users.vue
  35. 11 8
      cfc-web/src/views/Wishes.vue
  36. 8 4
      cfc-web/src/views/admin/Activities.vue
  37. 5 3
      cfc-web/src/views/admin/ActivityRegistrationReview.vue
  38. 7 3
      cfc-web/src/views/admin/ActivityReview.vue
  39. 4 1
      cfc-web/src/views/admin/ArticleCategory.vue
  40. 7 2
      cfc-web/src/views/admin/ArticleManage.vue
  41. 5 3
      cfc-web/src/views/admin/Assessment.vue
  42. 185 0
      cfc-web/src/views/admin/AssessmentAssign.vue
  43. 6 1
      cfc-web/src/views/admin/AssessmentPlanRules.vue
  44. 7 2
      cfc-web/src/views/admin/AssessmentProducts.vue
  45. 4 1
      cfc-web/src/views/admin/BaziConfigs.vue
  46. 4 1
      cfc-web/src/views/admin/BloodTypeConfigs.vue
  47. 13 4
      cfc-web/src/views/admin/CouponManagement.vue
  48. 10 2
      cfc-web/src/views/admin/EcomSupplierManage.vue
  49. 15 5
      cfc-web/src/views/admin/EmotionAlertManage.vue
  50. 14 5
      cfc-web/src/views/admin/EnergyRuleManagement.vue
  51. 4 1
      cfc-web/src/views/admin/EnergySandbox.vue
  52. 7 2
      cfc-web/src/views/admin/FamilyEarnings.vue
  53. 6 1
      cfc-web/src/views/admin/FamilyEarningsWithdraw.vue
  54. 7 3
      cfc-web/src/views/admin/Foods.vue
  55. 7 3
      cfc-web/src/views/admin/GrowthTaskManagement.vue
  56. 5 3
      cfc-web/src/views/admin/KnowledgeTag.vue
  57. 8 6
      cfc-web/src/views/admin/MembershipCenter.vue
  58. 8 3
      cfc-web/src/views/admin/OrderManage.vue
  59. 6 1
      cfc-web/src/views/admin/PendingRefund.vue
  60. 6 1
      cfc-web/src/views/admin/PlanManagement.vue
  61. 7 3
      cfc-web/src/views/admin/PointsLog.vue
  62. 7 3
      cfc-web/src/views/admin/ProductManage.vue
  63. 14 4
      cfc-web/src/views/admin/ProductPpointManage.vue
  64. 15 5
      cfc-web/src/views/admin/ProductProfitRate.vue
  65. 5 6
      cfc-web/src/views/admin/PromotionManagement.vue
  66. 6 1
      cfc-web/src/views/admin/Recipes.vue
  67. 4 1
      cfc-web/src/views/admin/RelationshipTypes.vue
  68. 6 1
      cfc-web/src/views/admin/SeasonalFoods.vue
  69. 8 3
      cfc-web/src/views/admin/SubscriptionManagement.vue
  70. 6 3
      cfc-web/src/views/admin/SupplierProductManage.vue
  71. 13 4
      cfc-web/src/views/admin/SysConfig.vue
  72. 5 3
      cfc-web/src/views/admin/VirtualTeamDetail.vue
  73. 5 2
      cfc-web/src/views/admin/VirtualTeamList.vue
  74. 4 1
      cfc-web/src/views/admin/ZodiacConfigs.vue
  75. 4 3
      cfc-web/src/views/admin/components/ProductSkuEditor.vue
  76. 7 4
      cfc-web/src/views/admin/data-source-config.vue
  77. 4 3
      cfc-web/src/views/admin/dimension-config.vue
  78. 4 3
      cfc-web/src/views/admin/dimension/index.vue
  79. 7 2
      cfc-web/src/views/admin/energy-config/WuxingConfig.vue
  80. 6 1
      cfc-web/src/views/admin/health-knowledge.vue
  81. 7 3
      cfc-web/src/views/admin/indicators/index.vue
  82. 7 3
      cfc-web/src/views/admin/review/ActivityAudit.vue
  83. 7 3
      cfc-web/src/views/admin/review/ActivityRegistrationAudit.vue
  84. 7 3
      cfc-web/src/views/admin/review/ArticleAudit.vue
  85. 7 3
      cfc-web/src/views/admin/review/ButlerAudit.vue
  86. 7 3
      cfc-web/src/views/admin/review/GuideAudit.vue
  87. 7 3
      cfc-web/src/views/admin/review/HierarchyAudit.vue
  88. 7 3
      cfc-web/src/views/admin/review/NutritionistAudit.vue
  89. 7 3
      cfc-web/src/views/admin/review/PackageAudit.vue
  90. 7 3
      cfc-web/src/views/admin/review/ProductAudit.vue
  91. 7 3
      cfc-web/src/views/admin/review/VendorAudit.vue
  92. 7 3
      cfc-web/src/views/admin/review/WithdrawAudit.vue
  93. 6 1
      cfc-web/src/views/admin/supply-hierarchy/ChangeRequest.vue
  94. 6 3
      cfc-web/src/views/admin/supply-manage/List.vue
  95. 10 5
      cfc-web/src/views/admin/supply-system/Detail.vue
  96. 6 1
      cfc-web/src/views/admin/supply-system/List.vue
  97. 7 4
      cfc-web/src/views/health/HealthReportAudit.vue
  98. 6 1
      cfc-web/src/views/nutritionist/HealthCheckins.vue
  99. 6 1
      cfc-web/src/views/nutritionist/HealthIndicators.vue
  100. 6 1
      cfc-web/src/views/nutritionist/HealthReports.vue

+ 15 - 0
cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java

@@ -6048,4 +6048,19 @@ try {
         log.error("迁移95 Step2 失败: " + e.getMessage());
         log.error("迁移95 Step2 失败: " + e.getMessage());
     }
     }
     }
     }
+
+    private void runMigration97() {
+        // 迁移93: users表添加roles字段
+        ensureColumn("users", "roles", "VARCHAR(100) COMMENT '角色列表'");
+    }
+
+    private void runMigration96() {
+        // 迁移96: 修复assessment_appointments.status列类型为TINYINT(原库可能为VARCHAR/ENUM导致Data truncated)
+        try {
+            jdbcTemplate.execute("ALTER TABLE assessment_appointments MODIFY COLUMN status TINYINT DEFAULT 0 COMMENT '0=待确认,1=已确认,2=已完成,3=已取消,4=未到'");
+            log.info("已修复assessment_appointments.status列类型为TINYINT");
+        } catch (Exception e) {
+            log.warn("Migration 96 skipped: {}", e.getMessage());
+        }
+    }
 }
 }

+ 13 - 2
cfc-backend/src/main/java/com/etotem/cfc/controller/DanAssessmentController.java

@@ -167,14 +167,25 @@ public class DanAssessmentController {
     @PostMapping("/appointment/create")
     @PostMapping("/appointment/create")
     public Result<AssessmentAppointment> createAppointment(@RequestBody Map<String, Object> body) {
     public Result<AssessmentAppointment> createAppointment(@RequestBody Map<String, Object> body) {
         Long userId = body.get("userId") != null ? Long.valueOf(body.get("userId").toString()) : null;
         Long userId = body.get("userId") != null ? Long.valueOf(body.get("userId").toString()) : null;
+        Long familyId = body.get("familyId") != null ? Long.valueOf(body.get("familyId").toString()) : null;
         Long childId = Long.valueOf(body.get("childId").toString());
         Long childId = Long.valueOf(body.get("childId").toString());
-        Long guideId = Long.valueOf(body.get("guideId").toString());
+        // 兼容前端 teacherId / guideId 字段,允许为 null(系统安排)
+        Long guideId = null;
+        if (body.get("guideId") != null) {
+            guideId = Long.valueOf(body.get("guideId").toString());
+        } else if (body.get("teacherId") != null) {
+            guideId = Long.valueOf(body.get("teacherId").toString());
+        }
         Long packageId = body.get("packageId") != null ? Long.valueOf(body.get("packageId").toString()) : null;
         Long packageId = body.get("packageId") != null ? Long.valueOf(body.get("packageId").toString()) : null;
         String appointmentDate = (String) body.get("appointmentDate");
         String appointmentDate = (String) body.get("appointmentDate");
         String appointmentTime = (String) body.get("appointmentTime");
         String appointmentTime = (String) body.get("appointmentTime");
+        String appointmentType = body.get("appointmentType") != null ? body.get("appointmentType").toString() : null;
+        Integer durationMinutes = body.get("durationMinutes") != null
+                ? Integer.valueOf(body.get("durationMinutes").toString()) : null;
         String notes = (String) body.get("notes");
         String notes = (String) body.get("notes");
         AssessmentAppointment appointment = appointmentService.createAppointment(
         AssessmentAppointment appointment = appointmentService.createAppointment(
-                userId, childId, guideId, packageId, appointmentDate, appointmentTime, notes);
+                userId, familyId, childId, guideId, packageId,
+                appointmentDate, appointmentTime, appointmentType, durationMinutes, notes);
         return Result.success(appointment);
         return Result.success(appointment);
     }
     }
 
 

+ 99 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminController.java

@@ -63,6 +63,9 @@ public class AdminController {
     @Resource
     @Resource
     private MemberUpgradeRecordMapper memberUpgradeRecordMapper;
     private MemberUpgradeRecordMapper memberUpgradeRecordMapper;
 
 
+    @Resource
+    private AssessmentAppointmentMapper assessmentAppointmentMapper;
+
     // 用户管理
     // 用户管理
     @PostMapping("/users")
     @PostMapping("/users")
     public Result<Page<User>> getUsers(@RequestBody Map<String, Object> params) {
     public Result<Page<User>> getUsers(@RequestBody Map<String, Object> params) {
@@ -978,4 +981,100 @@ public class AdminController {
                         .orderByDesc(MemberUpgradeRecord::getCreatedAt));
                         .orderByDesc(MemberUpgradeRecord::getCreatedAt));
         return Result.success(result);
         return Result.success(result);
     }
     }
+
+    // ========== 测评待分配规划师 ==========
+
+    @PostMapping("/assessment/pending-list")
+    public Result<Map<String, Object>> getPendingAssessmentList(@RequestBody Map<String, Object> params) {
+        int page = params.get("page") != null ? ((Number) params.get("page")).intValue() : 1;
+        int size = params.get("size") != null ? ((Number) params.get("size")).intValue() : 10;
+        Page<AssessmentAppointment> pageParam = new Page<>(page, size);
+
+        Page<AssessmentAppointment> result = assessmentAppointmentMapper.selectPage(pageParam,
+                new LambdaQueryWrapper<AssessmentAppointment>()
+                        .isNull(AssessmentAppointment::getGuideId)
+                        .orderByDesc(AssessmentAppointment::getCreatedAt));
+
+        java.util.List<Map<String, Object>> list = new java.util.ArrayList<>();
+        for (AssessmentAppointment app : result.getRecords()) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("id", app.getId());
+            item.put("familyId", app.getFamilyId());
+            item.put("childId", app.getChildId());
+            item.put("appointmentDate", app.getAppointmentDate());
+            item.put("appointmentTime", app.getAppointmentTime());
+            item.put("durationMinutes", app.getDurationMinutes());
+            item.put("status", app.getStatus());
+            item.put("appointmentType", app.getAppointmentType());
+            item.put("notes", app.getNotes());
+            item.put("contactPhone", app.getContactPhone());
+            item.put("createdAt", app.getCreatedAt());
+
+            // 关联查询用户昵称
+            User user = userMapper.selectById(app.getUserId());
+            item.put("userName", user != null ? user.getNickname() : "未知用户");
+
+            // 关联查询家庭成员名称(孩子)
+            if (app.getChildId() != null) {
+                FamilyMember child = familyMemberMapper.selectById(app.getChildId());
+                item.put("childName", child != null ? child.getNickname() : "未知");
+            } else {
+                item.put("childName", "");
+            }
+
+            list.add(item);
+        }
+
+        Map<String, Object> resultMap = new HashMap<>();
+        resultMap.put("records", list);
+        resultMap.put("total", result.getTotal());
+        resultMap.put("current", result.getCurrent());
+        resultMap.put("size", result.getSize());
+        return Result.success(resultMap);
+    }
+
+    @PostMapping("/assessment/available-guides")
+    public Result<java.util.List<Map<String, Object>>> getAvailableGuides() {
+        java.util.List<User> teachers = userMapper.selectList(
+                new LambdaQueryWrapper<User>()
+                        .eq(User::getRole, "teacher")
+                        .eq(User::getTeacherStatus, "approved")
+                        .select(User::getId, User::getNickname, User::getRealName, User::getPhone, User::getTeacherNo));
+        java.util.List<Map<String, Object>> list = new java.util.ArrayList<>();
+        for (User t : teachers) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("id", t.getId());
+            item.put("nickname", t.getNickname());
+            item.put("realName", t.getRealName());
+            item.put("phone", t.getPhone());
+            item.put("teacherNo", t.getTeacherNo());
+            list.add(item);
+        }
+        return Result.success(list);
+    }
+
+    @PostMapping("/assessment/assign-guide")
+    public Result<Void> assignGuide(@RequestBody Map<String, Object> body) {
+        Long appointmentId = body.get("appointmentId") != null ? Long.valueOf(body.get("appointmentId").toString()) : null;
+        Long guideId = body.get("guideId") != null ? Long.valueOf(body.get("guideId").toString()) : null;
+        if (appointmentId == null || guideId == null) {
+            return Result.error("appointmentId 和 guideId 不能为空");
+        }
+
+        AssessmentAppointment appointment = assessmentAppointmentMapper.selectById(appointmentId);
+        if (appointment == null) {
+            return Result.error("预约记录不存在");
+        }
+
+        User guide = userMapper.selectById(guideId);
+        if (guide == null || !"teacher".equals(guide.getRole())) {
+            return Result.error("规划师不存在或角色不正确");
+        }
+
+        appointment.setGuideId(guideId);
+        appointment.setTeacherId(guideId);
+        appointment.setStatus(1); // 已确认
+        assessmentAppointmentMapper.updateById(appointment);
+        return Result.success(null);
+    }
 }
 }

+ 2 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/assessment/AssessmentAppointmentController.java

@@ -63,7 +63,8 @@ public class AssessmentAppointmentController {
         }
         }
 
 
         AssessmentAppointment appointment = appointmentService.createAppointment(
         AssessmentAppointment appointment = appointmentService.createAppointment(
-                userId, childId, guideId, null, appointmentDate, appointmentTime, notes);
+                userId, user.getFamilyId(), childId, guideId, null,
+                appointmentDate, appointmentTime, null, null, notes);
 
 
         // 创建执行记录
         // 创建执行记录
         AssessmentExecution exec = executionService.create(quotaId, childId, appointment.getId());
         AssessmentExecution exec = executionService.create(quotaId, childId, appointment.getId());

+ 4 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/AssessmentAppointment.java

@@ -1,6 +1,8 @@
 package com.etotem.cfc.entity;
 package com.etotem.cfc.entity;
 
 
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.Data;
@@ -18,7 +20,9 @@ public class AssessmentAppointment implements Serializable {
     private Long userId;
     private Long userId;
     private Long familyId;
     private Long familyId;
     private Long childId;
     private Long childId;
+    @TableField(insertStrategy = FieldStrategy.IGNORED)
     private Long teacherId;
     private Long teacherId;
+    @TableField(insertStrategy = FieldStrategy.IGNORED)
     private Long guideId;
     private Long guideId;
     private Long packageId;
     private Long packageId;
     private String appointmentDate;
     private String appointmentDate;

+ 6 - 2
cfc-backend/src/main/java/com/etotem/cfc/service/AssessmentAppointmentService.java

@@ -23,16 +23,20 @@ public class AssessmentAppointmentService extends ServiceImpl<AssessmentAppointm
     @Resource
     @Resource
     private EnergyService energyService;
     private EnergyService energyService;
 
 
-    public AssessmentAppointment createAppointment(Long userId, Long childId, Long guideId,
-                                                    Long packageId, String appointmentDate, String appointmentTime, String notes) {
+    public AssessmentAppointment createAppointment(Long userId, Long familyId, Long childId, Long guideId,
+                                                    Long packageId, String appointmentDate, String appointmentTime,
+                                                    String appointmentType, Integer durationMinutes, String notes) {
         AssessmentAppointment appointment = new AssessmentAppointment();
         AssessmentAppointment appointment = new AssessmentAppointment();
         appointment.setUserId(userId);
         appointment.setUserId(userId);
+        appointment.setFamilyId(familyId);
         appointment.setChildId(childId);
         appointment.setChildId(childId);
         appointment.setGuideId(guideId);
         appointment.setGuideId(guideId);
         appointment.setPackageId(packageId);
         appointment.setPackageId(packageId);
         appointment.setAppointmentDate(appointmentDate);
         appointment.setAppointmentDate(appointmentDate);
         appointment.setAppointmentTime(appointmentTime);
         appointment.setAppointmentTime(appointmentTime);
         appointment.setTeacherId(guideId);
         appointment.setTeacherId(guideId);
+        appointment.setAppointmentType(appointmentType);
+        appointment.setDurationMinutes(durationMinutes);
         appointment.setStatus(0); // pending
         appointment.setStatus(0); // pending
         appointment.setNotes(notes);
         appointment.setNotes(notes);
         appointment.setCreatedAt(new Date());
         appointment.setCreatedAt(new Date());

+ 1 - 1
cfc-backend/src/main/resources/schema.sql

@@ -321,7 +321,7 @@ CREATE TABLE IF NOT EXISTS assessment_appointments (
     child_id BIGINT COMMENT '孩子ID',
     child_id BIGINT COMMENT '孩子ID',
     teacher_id BIGINT COMMENT '教师ID',
     teacher_id BIGINT COMMENT '教师ID',
     guide_id BIGINT COMMENT '规划师ID',
     guide_id BIGINT COMMENT '规划师ID',
-    package_id BIGINT COMMENT '套餐ID',
+    package_id BIGINT COMMENT '任务模板ID',
     appointment_date VARCHAR(20) COMMENT '预约日期 yyyy-MM-dd',
     appointment_date VARCHAR(20) COMMENT '预约日期 yyyy-MM-dd',
     appointment_time VARCHAR(20) COMMENT '预约时间 HH:mm',
     appointment_time VARCHAR(20) COMMENT '预约时间 HH:mm',
     duration_minutes INT COMMENT '测评时长',
     duration_minutes INT COMMENT '测评时长',

+ 1 - 1
cfc-frontend/components/ActionArticleRecommend.vue

@@ -18,7 +18,7 @@
       <view
       <view
         class="rec-card"
         class="rec-card"
         v-for="(article, idx) in displayArticles"
         v-for="(article, idx) in displayArticles"
-        :key="article.id || idx"
+        :key="idx"
         @click="$emit('articleClick', article)"
         @click="$emit('articleClick', article)"
       >
       >
         <!-- 封面图(可选) -->
         <!-- 封面图(可选) -->

+ 1 - 1
cfc-frontend/components/ContactCard.vue

@@ -46,9 +46,9 @@
           <view class="modal-btn cancel" @click="showInviteModal = false">取消</view>
           <view class="modal-btn cancel" @click="showInviteModal = false">取消</view>
           <view class="modal-btn confirm" @click="confirmInvite">确认邀请</view>
           <view class="modal-btn confirm" @click="confirmInvite">确认邀请</view>
         </view>
         </view>
-      </view>
     </view>
     </view>
   </view>
   </view>
+  </view>
 </template>
 </template>
 
 
 <script>
 <script>

+ 1 - 1
cfc-frontend/components/HealthDimensionsSection.vue

@@ -15,7 +15,7 @@
       <view
       <view
         class="dimension-item"
         class="dimension-item"
         v-for="dim in displayDimensions"
         v-for="dim in displayDimensions"
-        :key="dim.dimension || dim.key"
+        :key="dim.dimension"
         @click="goDimensionDetail(dim)">
         @click="goDimensionDetail(dim)">
         <text class="dimension-icon">{{ getDimIcon(dim.dimension || dim.key) }}</text>
         <text class="dimension-icon">{{ getDimIcon(dim.dimension || dim.key) }}</text>
         <text class="dimension-name">{{ dim.label }}</text>
         <text class="dimension-name">{{ dim.label }}</text>

+ 1 - 1
cfc-frontend/components/member-detail-sections/mind-section.vue

@@ -42,7 +42,7 @@
       <view class="section-header">
       <view class="section-header">
         <text class="section-title">🎯 即将到来的里程碑</text>
         <text class="section-title">🎯 即将到来的里程碑</text>
       </view>
       </view>
-      <view class="milestone-item" v-for="ms in milestones" :key="ms.id || ms.title">
+      <view class="milestone-item" v-for="ms in milestones" :key="ms.id">
         <text class="milestone-title">{{ ms.title }}</text>
         <text class="milestone-title">{{ ms.title }}</text>
         <text class="milestone-date">{{ ms.date }}</text>
         <text class="milestone-date">{{ ms.date }}</text>
       </view>
       </view>

+ 1 - 1
cfc-frontend/config.js

@@ -19,7 +19,7 @@ try {
   if (env) {
   if (env) {
     switch (env) {
     switch (env) {
       case 'develop':
       case 'develop':
-        API_BASE_URL = 'https://cfc.etotem.com.cn'
+        API_BASE_URL = 'http://localhost:9082'
         break
         break
       case 'trial':
       case 'trial':
         API_BASE_URL = 'https://cfc.iwintrue.com'
         API_BASE_URL = 'https://cfc.iwintrue.com'

+ 3 - 3
cfc-frontend/pages/health/report-confirm.vue

@@ -64,7 +64,7 @@
           <view
           <view
             class="candidate-item"
             class="candidate-item"
             v-for="(cand, idx) in candidates"
             v-for="(cand, idx) in candidates"
-            :key="cand.id || idx"
+            :key="idx"
             :class="{ 'candidate-selected': selectedMemberId === (cand.id || cand.userId) }"
             :class="{ 'candidate-selected': selectedMemberId === (cand.id || cand.userId) }"
             @click="selectCandidate(cand)"
             @click="selectCandidate(cand)"
           >
           >
@@ -89,8 +89,8 @@
         <view class="member-list" v-if="familyMembers.length > 0 && (candidates.length === 0 || !showCandidatesOnly)">
         <view class="member-list" v-if="familyMembers.length > 0 && (candidates.length === 0 || !showCandidatesOnly)">
           <view
           <view
             class="member-item"
             class="member-item"
-            v-for="member in familyMembers"
-            :key="member.userId || member.id"
+            v-for="(member, idx) in familyMembers"
+            :key="idx"
             :class="{ 'member-selected': selectedMemberId === (member.userId || member.id) }"
             :class="{ 'member-selected': selectedMemberId === (member.userId || member.id) }"
             @click="selectMember(member)"
             @click="selectMember(member)"
           >
           >

+ 1 - 1
cfc-frontend/pages/index/index.vue

@@ -137,7 +137,7 @@
         </view>
         </view>
         <!-- 无数据时显示占位卡片 -->
         <!-- 无数据时显示占位卡片 -->
         <template v-else-if="indexArticles.length === 0">
         <template v-else-if="indexArticles.length === 0">
-          <view class="article-card" v-for="i in 3" :key="'ph-' + i">
+          <view class="article-card" v-for="i in 3" :key="i">
             <view class="article-category" :style="{ background: gradientColors[(i-1) % gradientColors.length] }">
             <view class="article-category" :style="{ background: gradientColors[(i-1) % gradientColors.length] }">
               <text class="article-category-text">推荐文章</text>
               <text class="article-category-text">推荐文章</text>
             </view>
             </view>

+ 1 - 1
cfc-frontend/pages/index/parent-index.vue

@@ -258,7 +258,7 @@
           </view>
           </view>
           <!-- 无数据时显示占位卡片 -->
           <!-- 无数据时显示占位卡片 -->
           <template v-else-if="indexArticles.length === 0">
           <template v-else-if="indexArticles.length === 0">
-            <view class="article-card" v-for="i in 3" :key="'ph-' + i">
+            <view class="article-card" v-for="i in 3" :key="i">
               <view class="article-category" :style="{ background: gradientColors[(i-1) % gradientColors.length] }">
               <view class="article-category" :style="{ background: gradientColors[(i-1) % gradientColors.length] }">
                 <text class="article-category-text">推荐文章</text>
                 <text class="article-category-text">推荐文章</text>
               </view>
               </view>

+ 51 - 20
cfc-frontend/pages/profile-extra/edit-child.vue

@@ -47,22 +47,22 @@
         <input class="input" v-model="form.idCard" placeholder="请输入身份证号" maxlength="18" />
         <input class="input" v-model="form.idCard" placeholder="请输入身份证号" maxlength="18" />
       </view>
       </view>
 
 
-      <!-- 扣分开关 -->
-      <view class="form-item">
+      <!-- 扣分开关(仅 children 系统支持) -->
+      <view class="form-item" v-if="!isFamilyMember">
         <text class="label">扣分开关</text>
         <text class="label">扣分开关</text>
         <switch :checked="form.penaltyEnabled === 1" @change="onPenaltyChange" color="#F97316" />
         <switch :checked="form.penaltyEnabled === 1" @change="onPenaltyChange" color="#F97316" />
         <text class="hint">开启后,超时未完成任务将扣减积分</text>
         <text class="hint">开启后,超时未完成任务将扣减积分</text>
       </view>
       </view>
 
 
-      <!-- 对家庭成员可见 -->
-      <view class="form-item">
+      <!-- 对家庭成员可见(仅 children 系统支持) -->
+      <view class="form-item" v-if="!isFamilyMember">
         <text class="label">对家庭成员可见</text>
         <text class="label">对家庭成员可见</text>
         <switch :checked="form.showToFamily !== 0" @change="onShowToFamilyChange" color="#5B9BD5" />
         <switch :checked="form.showToFamily !== 0" @change="onShowToFamilyChange" color="#5B9BD5" />
         <text class="hint">关闭后,其他家庭成员将看不到此孩子</text>
         <text class="hint">关闭后,其他家庭成员将看不到此孩子</text>
       </view>
       </view>
 
 
-      <!-- 主题风格 -->
-      <view class="form-item">
+      <!-- 主题风格(仅 children 系统支持) -->
+      <view class="form-item" v-if="!isFamilyMember">
         <text class="label">主题风格</text>
         <text class="label">主题风格</text>
         <picker :range="themes" range-key="label" @change="onThemeChange">
         <picker :range="themes" range-key="label" @change="onThemeChange">
           <view class="picker">
           <view class="picker">
@@ -77,12 +77,14 @@
 </template>
 </template>
 
 
 <script>
 <script>
-import { getChildren, updateChild } from '../../utils/api.js'
+import { getChildren, updateChild, updateFamilyMember } from '../../utils/api.js'
 
 
 export default {
 export default {
   data() {
   data() {
     return {
     return {
       childId: '',
       childId: '',
+      memberId: '',
+      isFamilyMember: false,
       submitting: false,
       submitting: false,
       form: {
       form: {
         nickname: '',
         nickname: '',
@@ -133,12 +135,19 @@ export default {
   },
   },
   onLoad(options) {
   onLoad(options) {
     this.childId = options.childId || ''
     this.childId = options.childId || ''
-    if (!this.childId) {
+    this.memberId = options.memberId || ''
+    if (!this.childId && !this.memberId) {
       uni.showToast({ title: '参数错误', icon: 'none' })
       uni.showToast({ title: '参数错误', icon: 'none' })
       setTimeout(() => uni.navigateBack(), 1500)
       setTimeout(() => uni.navigateBack(), 1500)
       return
       return
     }
     }
-    this.loadChildData()
+    // 优先按 childId 从 children 系统加载,找不到则按 memberId 从 family-member 系统加载
+    if (this.childId) {
+      this.loadChildData()
+    } else {
+      this.isFamilyMember = true
+      this.loadFamilyMemberData(options)
+    }
   },
   },
   methods: {
   methods: {
     async loadChildData() {
     async loadChildData() {
@@ -158,12 +167,24 @@ export default {
             showToFamily: child.showToFamily !== 0 ? 1 : 0,
             showToFamily: child.showToFamily !== 0 ? 1 : 0,
             theme: child.theme || 'default'
             theme: child.theme || 'default'
           }
           }
+        } else {
+          // children 系统找不到,尝试作为 family member 加载
+          this.isFamilyMember = true
+          this.memberId = this.childId
+          this.childId = ''
         }
         }
       } catch (e) {
       } catch (e) {
         console.error('加载孩子数据失败', e)
         console.error('加载孩子数据失败', e)
         uni.showToast({ title: '加载失败', icon: 'none' })
         uni.showToast({ title: '加载失败', icon: 'none' })
       }
       }
     },
     },
+    loadFamilyMemberData(options) {
+      // 从 URL 参数中填充基本信息(family member 系统字段有限)
+      this.form.nickname = options.nickname ? decodeURIComponent(options.nickname) : ''
+      this.form.gender = options.gender || ''
+      this.form.phone = options.phone || ''
+      this.form.birthday = options.birthday || ''
+    },
     onBirthdayChange(e) {
     onBirthdayChange(e) {
       this.form.birthday = e.detail.value
       this.form.birthday = e.detail.value
       // 根据出生日期自动计算年龄
       // 根据出生日期自动计算年龄
@@ -204,17 +225,27 @@ export default {
 
 
       this.submitting = true
       this.submitting = true
       try {
       try {
-        await updateChild(this.childId, {
-          nickname: this.form.nickname,
-          birthday: this.form.birthday,
-          gender: this.form.gender,
-          age: this.form.age,
-          phone: this.form.phone,
-          idCard: this.form.idCard,
-          penaltyEnabled: this.form.penaltyEnabled,
-          showToFamily: this.form.showToFamily,
-          theme: this.form.theme
-        })
+        if (this.isFamilyMember) {
+          await updateFamilyMember({
+            memberId: this.memberId,
+            nickname: this.form.nickname,
+            birthday: this.form.birthday,
+            gender: this.form.gender,
+            phone: this.form.phone
+          })
+        } else {
+          await updateChild(this.childId, {
+            nickname: this.form.nickname,
+            birthday: this.form.birthday,
+            gender: this.form.gender,
+            age: this.form.age,
+            phone: this.form.phone,
+            idCard: this.form.idCard,
+            penaltyEnabled: this.form.penaltyEnabled,
+            showToFamily: this.form.showToFamily,
+            theme: this.form.theme
+          })
+        }
         uni.showToast({ title: '保存成功', icon: 'success' })
         uni.showToast({ title: '保存成功', icon: 'success' })
         setTimeout(() => uni.navigateBack(), 1500)
         setTimeout(() => uni.navigateBack(), 1500)
       } catch (e) {
       } catch (e) {

+ 5 - 1
cfc-frontend/pages/profile-extra/family-members.vue

@@ -359,7 +359,11 @@ export default {
     },
     },
     onEditRelation(member) {
     onEditRelation(member) {
       this.showMemberDetailModal = false
       this.showMemberDetailModal = false
-      uni.navigateTo({ url: '/pages/profile/user-edit?memberId=' + member.id + '&nickname=' + encodeURIComponent(member.nickname || '') })
+      var params = 'memberId=' + member.id + '&nickname=' + encodeURIComponent(member.nickname || '')
+      if (member.gender) params += '&gender=' + member.gender
+      if (member.phone) params += '&phone=' + member.phone
+      if (member.birthday) params += '&birthday=' + member.birthday
+      uni.navigateTo({ url: '/pages/profile/edit-child?' + params })
     },
     },
     doQuestionnaire(member) {
     doQuestionnaire(member) {
       this.showMemberDetailModal = false
       this.showMemberDetailModal = false

+ 1 - 1
cfc-frontend/pages/shop/address-edit/address-edit.vue

@@ -77,7 +77,7 @@
           <scroll-view class="region-list" scroll-y>
           <scroll-view class="region-list" scroll-y>
             <view
             <view
               v-for="item in currentRegionItems"
               v-for="item in currentRegionItems"
-              :key="item.id || item.code"
+              :key="item.id"
               :class="['region-item', isRegionSelected(item) ? 'region-item-selected' : '']"
               :class="['region-item', isRegionSelected(item) ? 'region-item-selected' : '']"
               @click="selectRegionItem(item)"
               @click="selectRegionItem(item)"
             >
             >

+ 1 - 1
cfc-web/.env.development

@@ -1,2 +1,2 @@
-VUE_APP_BASE_API=
+VUE_APP_BASE_API=http://localhost:9082
 VUE_APP_SKIP_CAPTCHA=true
 VUE_APP_SKIP_CAPTCHA=true

+ 18 - 0
cfc-web/public/CHANGELOG-v$(node.undefined.md

@@ -0,0 +1,18 @@
+# v$(node.undefined 版本历史
+
+[« 返回最新版本](CHANGELOG.md)
+
+---
+## v$(node (2026-07-20)
+
+### 其他
+- 分配规划师
+- 分配规划师
+- 填写预约报告表单
+- 填写预约报告表单
+- 填写预约报告表单
+- 填写预约报告表单
+- 修复程序报错
+- 修复程序报错
+- 修复程序报错
+

+ 25 - 0
cfc-web/src/api/admin.js

@@ -1595,3 +1595,28 @@ export function getFamilyEarningsRecords(familyId, type) {
     data: { familyId: familyId, type: type || '' }
     data: { familyId: familyId, type: type || '' }
   })
   })
 }
 }
+
+// ===== 测评待分配规划师 =====
+export function getPendingAssessmentList(params) {
+  return request({
+    url: '/api/admin/assessment/pending-list',
+    method: 'post',
+    data: params || {}
+  })
+}
+
+export function getAvailableGuides() {
+  return request({
+    url: '/api/admin/assessment/available-guides',
+    method: 'post',
+    data: {}
+  })
+}
+
+export function assignGuide(appointmentId, guideId) {
+  return request({
+    url: '/api/admin/assessment/assign-guide',
+    method: 'post',
+    data: { appointmentId, guideId }
+  })
+}

+ 6 - 0
cfc-web/src/router/index.js

@@ -186,6 +186,12 @@ const routes = [
         component: () => import('@/views/admin/Assessment.vue'),
         component: () => import('@/views/admin/Assessment.vue'),
         meta: { title: '测评管理', perm: 'assessment:dan' }
         meta: { title: '测评管理', perm: 'assessment:dan' }
       },
       },
+      {
+        path: 'assessment-assign',
+        name: 'AssessmentAssign',
+        component: () => import('@/views/admin/AssessmentAssign.vue'),
+        meta: { title: '待分配规划师', perm: 'assessment:dan' }
+      },
       {
       {
         path: 'product-manage',
         path: 'product-manage',
         name: 'ProductManage',
         name: 'ProductManage',

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

@@ -39,8 +39,7 @@
         </el-form>
         </el-form>
 
 
         <!-- 孩子列表 -->
         <!-- 孩子列表 -->
-        <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 :data="tableData" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <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="nickname" label="昵称" width="150"></el-table-column>
         <el-table-column prop="age" label="年龄" width="80"></el-table-column>
         <el-table-column prop="age" label="年龄" width="80"></el-table-column>
@@ -81,7 +80,6 @@
           </template>
           </template>
         </el-table-column>
         </el-table-column>
         </el-table>
         </el-table>
-        </div>
 
 
         <!-- 分页 -->
         <!-- 分页 -->
       <el-pagination
       <el-pagination
@@ -151,6 +149,11 @@ import { getChildrenList, adjustChildPoints, updateChild } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'Children',
   name: 'Children',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,
@@ -239,6 +242,7 @@ export default {
     },
     },
     handleSizeChange(val) {
     handleSizeChange(val) {
       this.pagination.size = val
       this.pagination.size = val
+      this.pagination.current = 1
       this.loadChildren()
       this.loadChildren()
     },
     },
     handleCurrentChange(val) {
     handleCurrentChange(val) {

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

@@ -31,12 +31,12 @@
         </el-form>
         </el-form>
 
 
         <!-- 家庭列表 -->
         <!-- 家庭列表 -->
-        <div style="overflow:auto;max-height:calc(100vh - 300px);">
         <el-table
         <el-table
           :data="tableData"
           :data="tableData"
           border
           border
           v-loading="loading"
           v-loading="loading"
-          style="width: 100%;max-height:calc(100vh - 300px);"
+          style="width: 100%"
+          :max-height="tableHeight"
         >
         >
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <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="name" label="家庭名称" width="200"></el-table-column>
@@ -61,7 +61,6 @@
           </template>
           </template>
         </el-table-column>
         </el-table-column>
         </el-table>
         </el-table>
-        </div>
 
 
         <!-- 分页 -->
         <!-- 分页 -->
       <el-pagination
       <el-pagination
@@ -110,6 +109,7 @@
           :data="membersData.parents"
           :data="membersData.parents"
           border
           border
           style="width: 100%; margin-bottom: 20px"
           style="width: 100%; margin-bottom: 20px"
+          :max-height="300"
           v-if="membersData.parents && membersData.parents.length > 0"
           v-if="membersData.parents && membersData.parents.length > 0"
         >
         >
           <el-table-column prop="id" label="ID" width="80"></el-table-column>
           <el-table-column prop="id" label="ID" width="80"></el-table-column>
@@ -124,6 +124,7 @@
           :data="membersData.children"
           :data="membersData.children"
           border
           border
           style="width: 100%"
           style="width: 100%"
+          :max-height="300"
           v-if="membersData.children && membersData.children.length > 0"
           v-if="membersData.children && membersData.children.length > 0"
         >
         >
           <el-table-column prop="id" label="ID" width="80"></el-table-column>
           <el-table-column prop="id" label="ID" width="80"></el-table-column>
@@ -150,6 +151,11 @@ import { getFamilyList, getFamilyMembers, updateFamily, deleteFamily } from '@/a
 
 
 export default {
 export default {
   name: 'Families',
   name: 'Families',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,
@@ -229,6 +235,7 @@ export default {
     },
     },
     handleSizeChange(val) {
     handleSizeChange(val) {
       this.pagination.size = val
       this.pagination.size = val
+      this.pagination.current = 1
       this.loadFamilies()
       this.loadFamilies()
     },
     },
     handleCurrentChange(val) {
     handleCurrentChange(val) {

+ 11 - 8
cfc-web/src/views/GuideFamilyTask.vue

@@ -69,8 +69,7 @@
       </div>
       </div>
 
 
       <!-- 孩子列表 -->
       <!-- 孩子列表 -->
-      <div style="overflow:auto;max-height:calc(100vh - 300px);">
-      <el-table style="max-height:calc(100vh - 300px);" v-if="familyOverview && !searchForm.childId" :data="familyOverview.children" border>
+      <el-table :max-height="tableHeight" v-if="familyOverview && !searchForm.childId" :data="familyOverview.children" border>
         <el-table-column prop="childName" label="孩子姓名" width="120"></el-table-column>
         <el-table-column prop="childName" label="孩子姓名" width="120"></el-table-column>
         <el-table-column prop="totalPoints" label="总积分" width="100"></el-table-column>
         <el-table-column prop="totalPoints" label="总积分" width="100"></el-table-column>
         <el-table-column prop="streakDays" label="连续打卡" width="100">
         <el-table-column prop="streakDays" label="连续打卡" width="100">
@@ -88,11 +87,10 @@
             <el-button size="mini" @click="selectChild(row)">查看任务</el-button>
             <el-button size="mini" @click="selectChild(row)">查看任务</el-button>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
 
 
       <!-- 任务列表 -->
       <!-- 任务列表 -->
-      <div style="overflow:auto;max-height:calc(100vh - 300px);">
-      <el-table v-if="searchForm.childId" :data="tasks" border v-loading="taskLoading">
+      <el-table v-if="searchForm.childId" :data="tasks" border v-loading="taskLoading" :max-height="tableHeight">
         <template slot="empty">
         <template slot="empty">
           <div class="empty-table-state">
           <div class="empty-table-state">
             <i class="el-icon-tickets" style="font-size: 48px; color: #ccc; margin-bottom: 16px;"></i>
             <i class="el-icon-tickets" style="font-size: 48px; color: #ccc; margin-bottom: 16px;"></i>
@@ -133,10 +131,10 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-    </el-table></div>
+      </el-table>
 
 
-    <!-- 分页 -->
-    <el-pagination
+      <!-- 分页 -->
+      <el-pagination
         v-if="searchForm.childId && total > 0"
         v-if="searchForm.childId && total > 0"
         style="margin-top: 20px; text-align: right"
         style="margin-top: 20px; text-align: right"
         :current-page="pagination.page"
         :current-page="pagination.page"
@@ -201,6 +199,11 @@ import { fetchBoundFamilies, fetchFamilyOverview, fetchChildTasks, fetchPendingR
 
 
 export default {
 export default {
   name: 'GuideFamilyTask',
   name: 'GuideFamilyTask',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

+ 8 - 4
cfc-web/src/views/GuidePackages.vue

@@ -26,8 +26,7 @@
       </el-form>
       </el-form>
 
 
       <!-- 任务模板列表 -->
       <!-- 任务模板列表 -->
-      <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 :max-height="tableHeight" :data="tableData" border v-loading="loading">
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <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="name" label="任务模板名称" min-width="150"></el-table-column>
         <el-table-column prop="cycleDays" label="周期" width="80">
         <el-table-column prop="cycleDays" label="周期" width="80">
@@ -68,7 +67,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
     </el-card>
     </el-card>
 
 
     <!-- 编辑弹窗 -->
     <!-- 编辑弹窗 -->
@@ -123,7 +122,7 @@
       <div style="margin-bottom: 20px">
       <div style="margin-bottom: 20px">
         <el-button type="primary" size="small" @click="handleAddItem">添加任务项</el-button>
         <el-button type="primary" size="small" @click="handleAddItem">添加任务项</el-button>
       </div>
       </div>
-      <el-table :data="items" border>
+      <el-table :data="items" border :max-height="300">
         <el-table-column prop="taskName" label="任务名称" min-width="120"></el-table-column>
         <el-table-column prop="taskName" label="任务名称" min-width="120"></el-table-column>
         <el-table-column prop="points" label="积分" width="60"></el-table-column>
         <el-table-column prop="points" label="积分" width="60"></el-table-column>
         <el-table-column prop="frequency" label="频率" width="80"></el-table-column>
         <el-table-column prop="frequency" label="频率" width="80"></el-table-column>
@@ -194,6 +193,11 @@ import { getMyPackages, getGuidePackage, getGuidePackageItems, createPackage, up
 
 
 export default {
 export default {
   name: 'GuidePackages',
   name: 'GuidePackages',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

+ 1 - 4
cfc-web/src/views/Layout.vue

@@ -295,6 +295,7 @@ export default {
             { title: '测评管理', icon: 'el-icon-edit', perm: 'assessment:dan',
             { title: '测评管理', icon: 'el-icon-edit', perm: 'assessment:dan',
               children: [
               children: [
                 { path: '/assessment-admin', label: '测评管理', icon: 'el-icon-edit', perm: 'assessment:dan' },
                 { path: '/assessment-admin', label: '测评管理', icon: 'el-icon-edit', perm: 'assessment:dan' },
+                { path: '/assessment-assign', label: '待分配规划师', icon: 'el-icon-user', perm: 'assessment:dan' },
               ]},
               ]},
             // --- 虚拟团队 ---
             // --- 虚拟团队 ---
             { title: '虚拟团队', icon: 'el-icon-s-custom', perm: 'system:config',
             { title: '虚拟团队', icon: 'el-icon-s-custom', perm: 'system:config',
@@ -693,8 +694,6 @@ export default {
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
   min-height: 0;
   min-height: 0;
-  overflow-y: auto;
-  overflow-x: hidden;
 }
 }
 
 
 /* ========== 全局 .admin-page 样式 ========== */
 /* ========== 全局 .admin-page 样式 ========== */
@@ -718,7 +717,6 @@ export default {
   flex-direction: column;
   flex-direction: column;
   min-height: 0;
   min-height: 0;
   padding: 20px;
   padding: 20px;
-  overflow-y: auto;
 }
 }
 /* 当 admin-page > div > el-card(如 ArticleManage 的嵌套 div) */
 /* 当 admin-page > div > el-card(如 ArticleManage 的嵌套 div) */
 .admin-page > div:only-child {
 .admin-page > div:only-child {
@@ -739,6 +737,5 @@ export default {
   flex-direction: column;
   flex-direction: column;
   min-height: 0;
   min-height: 0;
   padding: 20px;
   padding: 20px;
-  overflow-y: auto;
 }
 }
 </style>
 </style>

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

@@ -35,8 +35,7 @@
 
 
     <!-- 日志列表 -->
     <!-- 日志列表 -->
     <el-card>
     <el-card>
-      <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 :max-height="tableHeight" :data="logs" v-loading="loading" stripe>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <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="userId" label="用户ID" width="100"></el-table-column>
         <el-table-column prop="nickname" label="用户名" width="120"></el-table-column>
         <el-table-column prop="nickname" label="用户名" width="120"></el-table-column>
@@ -68,7 +67,7 @@
             <el-button size="mini" @click="handleViewDetail(row)">详情</el-button>
             <el-button size="mini" @click="handleViewDetail(row)">详情</el-button>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
 
 
       <!-- 分页 -->
       <!-- 分页 -->
       <el-pagination
       <el-pagination
@@ -107,6 +106,11 @@ import { getOperationLogs } from '@/api/operationLog'
 
 
 export default {
 export default {
   name: 'OperationLogs',
   name: 'OperationLogs',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

+ 7 - 1
cfc-web/src/views/Points.vue

@@ -41,7 +41,7 @@
       </el-form>
       </el-form>
 
 
       <!-- 积分流水列表 -->
       <!-- 积分流水列表 -->
-      <el-table :data="tableData" border v-loading="loading" style="width: 100%">
+      <el-table :data="tableData" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="childId" label="孩子ID" width="100"></el-table-column>
         <el-table-column prop="childId" label="孩子ID" width="100"></el-table-column>
         <el-table-column prop="amount" label="积分变动" width="120">
         <el-table-column prop="amount" label="积分变动" width="120">
@@ -91,6 +91,11 @@ import { getPointsLogs } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'Points',
   name: 'Points',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,
@@ -143,6 +148,7 @@ export default {
     },
     },
     handleSizeChange(val) {
     handleSizeChange(val) {
       this.pagination.size = val
       this.pagination.size = val
+      this.pagination.current = 1
       this.loadPointsLogs()
       this.loadPointsLogs()
     },
     },
     handleCurrentChange(val) {
     handleCurrentChange(val) {

+ 12 - 7
cfc-web/src/views/Rewards.vue

@@ -52,8 +52,7 @@
 
 
           <!-- 家庭选择对话框 -->
           <!-- 家庭选择对话框 -->
           <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
           <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
-            <div style="overflow:auto;max-height:calc(100vh - 300px);">
-<el-table style="max-height:calc(100vh - 300px);cursor: pointer" :data="familyList" border v-loading="familyLoading" @row-click="selectFamily">
+            <el-table :max-height="tableHeight" style="cursor: pointer" :data="familyList" border v-loading="familyLoading" @row-click="selectFamily">
               <el-table-column prop="id" label="ID" width="80"></el-table-column>
               <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="name" label="家庭名称" min-width="150"></el-table-column>
               <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
               <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
@@ -62,7 +61,7 @@
                   {{ formatDate(scope.row.createdAt) }}
                   {{ formatDate(scope.row.createdAt) }}
                 </template>
                 </template>
               </el-table-column>
               </el-table-column>
-            </el-table></div>
+            </el-table>
             <el-pagination
             <el-pagination
               style="margin-top: 15px; text-align: right"
               style="margin-top: 15px; text-align: right"
               @current-change="loadFamilies"
               @current-change="loadFamilies"
@@ -73,9 +72,9 @@
             ></el-pagination>
             ></el-pagination>
           </el-dialog>
           </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="title" label="奖励名称" min-width="200"></el-table-column>
+<el-table :data="tableData" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
+             <el-table-column prop="id" label="ID" width="80"></el-table-column>
+             <el-table-column prop="title" label="奖励名称" min-width="200"></el-table-column>
             <el-table-column prop="pointsRequired" label="所需积分" width="120">
             <el-table-column prop="pointsRequired" label="所需积分" width="120">
               <template slot-scope="scope">
               <template slot-scope="scope">
                 <el-tag type="warning">{{ scope.row.pointsRequired }}</el-tag>
                 <el-tag type="warning">{{ scope.row.pointsRequired }}</el-tag>
@@ -134,7 +133,7 @@
           <el-button type="primary" size="small" style="margin-bottom: 15px" @click="showCreateTemplate">
           <el-button type="primary" size="small" style="margin-bottom: 15px" @click="showCreateTemplate">
             新建模板
             新建模板
           </el-button>
           </el-button>
-          <el-table :data="templates" border v-loading="loadingTemplates" style="width: 100%">
+          <el-table :data="templates" border v-loading="loadingTemplates" style="width: 100%" :max-height="tableHeight">
             <el-table-column prop="id" label="ID" width="80"></el-table-column>
             <el-table-column prop="id" label="ID" width="80"></el-table-column>
             <el-table-column prop="title" label="模板名称" min-width="200"></el-table-column>
             <el-table-column prop="title" label="模板名称" min-width="200"></el-table-column>
             <el-table-column prop="pointsRequired" label="所需积分" width="120">
             <el-table-column prop="pointsRequired" label="所需积分" width="120">
@@ -190,6 +189,11 @@ import { getRewardsList, getRewardTemplates, createRewardTemplate, deleteRewardT
 
 
 export default {
 export default {
   name: 'Rewards',
   name: 'Rewards',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       activeTab: 'list',
       activeTab: 'list',
@@ -321,6 +325,7 @@ export default {
     },
     },
     handleSizeChange(val) {
     handleSizeChange(val) {
       this.pagination.size = val
       this.pagination.size = val
+      this.pagination.current = 1
       this.loadRewards()
       this.loadRewards()
     },
     },
     handleCurrentChange(val) {
     handleCurrentChange(val) {

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

@@ -54,12 +54,12 @@
       </el-form>
       </el-form>
 
 
       <!-- 模板列表 -->
       <!-- 模板列表 -->
-      <div style="overflow:auto;max-height:calc(100vh - 300px);">
       <el-table
       <el-table
         :data="tableData"
         :data="tableData"
         border
         border
         v-loading="loading"
         v-loading="loading"
-        style="width: 100%;max-height:calc(100vh - 300px);"
+        style="width: 100%"
+        :max-height="tableHeight"
       >
       >
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="title" label="模板名称" min-width="200"></el-table-column>
         <el-table-column prop="title" label="模板名称" min-width="200"></el-table-column>
@@ -140,7 +140,7 @@
             </el-button>
             </el-button>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-        </el-table></div>
+      </el-table>
 
 
       <!-- 分页 -->
       <!-- 分页 -->
       <el-pagination
       <el-pagination
@@ -261,6 +261,11 @@ import { getTaskTemplateList, createTaskTemplate, updateTaskTemplate, deleteTask
 
 
 export default {
 export default {
   name: 'TaskTemplates',
   name: 'TaskTemplates',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,
@@ -355,6 +360,7 @@ export default {
     },
     },
     handleSizeChange(val) {
     handleSizeChange(val) {
       this.pagination.size = val
       this.pagination.size = val
+      this.pagination.current = 1
       this.loadTemplates()
       this.loadTemplates()
     },
     },
     handleCurrentChange(val) {
     handleCurrentChange(val) {

+ 8 - 2
cfc-web/src/views/Tasks.vue

@@ -57,7 +57,7 @@
 
 
       <!-- 家庭选择对话框 -->
       <!-- 家庭选择对话框 -->
       <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
       <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
-        <el-table :data="familyList" border v-loading="familyLoading" @row-click="selectFamily" style="cursor: pointer">
+        <el-table :data="familyList" border v-loading="familyLoading" @row-click="selectFamily" style="cursor: pointer" :max-height="300">
           <el-table-column prop="id" label="ID" width="80"></el-table-column>
           <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="name" label="家庭名称" min-width="150"></el-table-column>
           <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
           <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
@@ -94,7 +94,7 @@
       </el-row>
       </el-row>
 
 
       <!-- 任务列表 -->
       <!-- 任务列表 -->
-      <el-table :data="tableData" border v-loading="loading" style="width: 100%">
+      <el-table :data="tableData" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="title" label="任务名称" min-width="200"></el-table-column>
         <el-table-column prop="title" label="任务名称" min-width="200"></el-table-column>
         <el-table-column prop="points" label="积分" width="80">
         <el-table-column prop="points" label="积分" width="80">
@@ -150,6 +150,11 @@ import { getTasksList, getTaskStats, getFamilyList } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'Tasks',
   name: 'Tasks',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,
@@ -262,6 +267,7 @@ export default {
     },
     },
     handleSizeChange(val) {
     handleSizeChange(val) {
       this.pagination.size = val
       this.pagination.size = val
+      this.pagination.current = 1
       this.loadTasks()
       this.loadTasks()
     },
     },
     handleCurrentChange(val) {
     handleCurrentChange(val) {

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

@@ -20,8 +20,7 @@
       </el-form>
       </el-form>
 
 
       <!-- 咨询列表 -->
       <!-- 咨询列表 -->
-      <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 :max-height="tableHeight" :data="messages" border v-loading="loading">
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <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 prop="familyId" label="家庭ID" width="80"></el-table-column>
         <el-table-column label="家长" width="100">
         <el-table-column label="家长" width="100">
@@ -47,7 +46,7 @@
             </el-button>
             </el-button>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
 
 
       <!-- 分页 -->
       <!-- 分页 -->
       <el-pagination
       <el-pagination
@@ -113,6 +112,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     replyDialogTitle() {
     replyDialogTitle() {
       if (!this.currentMessage) return '回复咨询'
       if (!this.currentMessage) return '回复咨询'
       return this.currentMessage.status === 'pending' ? '回复咨询' : '查看回复'
       return this.currentMessage.status === 'pending' ? '回复咨询' : '查看回复'

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

@@ -50,11 +50,12 @@
       </el-form>
       </el-form>
 
 
       <!-- 用户列表 -->
       <!-- 用户列表 -->
-      <div style="overflow:auto;max-height:calc(100vh - 300px);">
-<el-table style="max-height:calc(100vh - 300px);width: 100%" 
+<el-table 
         :data="tableData" 
         :data="tableData" 
         border 
         border 
         v-loading="loading"
         v-loading="loading"
+        style="width: 100%"
+        :max-height="tableHeight"
       >
       >
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <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="nickname" label="昵称" width="150"></el-table-column>
@@ -93,7 +94,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
 
 
       <!-- 分页 -->
       <!-- 分页 -->
       <el-pagination
       <el-pagination
@@ -182,6 +183,11 @@ import { getRoleLabel } from '@/utils/permissions'
 
 
 export default {
 export default {
   name: 'Users',
   name: 'Users',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,
@@ -270,6 +276,7 @@ export default {
     },
     },
     handleSizeChange(val) {
     handleSizeChange(val) {
       this.pagination.size = val
       this.pagination.size = val
+      this.pagination.current = 1
       this.loadUsers()
       this.loadUsers()
     },
     },
     handleCurrentChange(val) {
     handleCurrentChange(val) {

+ 11 - 8
cfc-web/src/views/Wishes.vue

@@ -48,8 +48,7 @@
           <!-- 待定价列表 -->
           <!-- 待定价列表 -->
           <div v-if="draftWishes.length > 0" class="wish-section">
           <div v-if="draftWishes.length > 0" class="wish-section">
             <div class="section-title">📝 待定价</div>
             <div class="section-title">📝 待定价</div>
-            <div style="overflow:auto;max-height:calc(100vh - 300px);">
-<el-table style="max-height:calc(100vh - 300px);width: 100%" :data="draftWishes" border v-loading="loading">
+<el-table style="width: 100%" :max-height="tableHeight" :data="draftWishes" border v-loading="loading">
               <el-table-column prop="id" label="ID" width="80"></el-table-column>
               <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="childName" label="孩子" width="100"></el-table-column>
               <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
               <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
@@ -72,13 +71,13 @@
                   </el-dropdown>
                   </el-dropdown>
                 </template>
                 </template>
               </el-table-column>
               </el-table-column>
-            </el-table></div>
+            </el-table>
           </div>
           </div>
 
 
           <!-- 待审批兑换列表 -->
           <!-- 待审批兑换列表 -->
           <div v-if="pendingExchangeWishes.length > 0" class="wish-section">
           <div v-if="pendingExchangeWishes.length > 0" class="wish-section">
             <div class="section-title">⏳ 待审批兑换</div>
             <div class="section-title">⏳ 待审批兑换</div>
-            <el-table :data="pendingExchangeWishes" border v-loading="loading" style="width: 100%">
+            <el-table :data="pendingExchangeWishes" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
               <el-table-column prop="id" label="ID" width="80"></el-table-column>
               <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="childName" label="孩子" width="100"></el-table-column>
               <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
               <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
@@ -111,7 +110,7 @@
           <!-- 待兑现列表 -->
           <!-- 待兑现列表 -->
           <div v-if="approvedWishes.length > 0" class="wish-section">
           <div v-if="approvedWishes.length > 0" class="wish-section">
             <div class="section-title">📦 待兑现</div>
             <div class="section-title">📦 待兑现</div>
-            <el-table :data="approvedWishes" border v-loading="loading" style="width: 100%">
+            <el-table :data="approvedWishes" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
               <el-table-column prop="id" label="ID" width="80"></el-table-column>
               <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="childName" label="孩子" width="100"></el-table-column>
               <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
               <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
@@ -136,7 +135,7 @@
           <!-- 待收货列表 -->
           <!-- 待收货列表 -->
           <div v-if="exchangingWishes.length > 0" class="wish-section">
           <div v-if="exchangingWishes.length > 0" class="wish-section">
             <div class="section-title">🎁 待收货确认</div>
             <div class="section-title">🎁 待收货确认</div>
-            <el-table :data="exchangingWishes" border v-loading="loading" style="width: 100%">
+            <el-table :data="exchangingWishes" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
               <el-table-column prop="id" label="ID" width="80"></el-table-column>
               <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="childName" label="孩子" width="100"></el-table-column>
               <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
               <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
@@ -198,7 +197,7 @@
 
 
           <!-- 家庭选择对话框 -->
           <!-- 家庭选择对话框 -->
           <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
           <el-dialog title="选择家庭" :visible.sync="familyDialogVisible" width="600px">
-            <el-table :data="familyList" border v-loading="familyLoading" @row-click="selectFamily" style="cursor: pointer">
+            <el-table :data="familyList" border v-loading="familyLoading" @row-click="selectFamily" style="cursor: pointer" :max-height="300">
               <el-table-column prop="id" label="ID" width="80"></el-table-column>
               <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="name" label="家庭名称" min-width="150"></el-table-column>
               <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
               <el-table-column prop="inviteCode" label="邀请码" width="120"></el-table-column>
@@ -213,7 +212,7 @@
             ></el-pagination>
             ></el-pagination>
           </el-dialog>
           </el-dialog>
 
 
-          <el-table :data="tableData" border v-loading="loading" style="width: 100%">
+          <el-table :data="tableData" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
             <el-table-column prop="id" label="ID" width="80"></el-table-column>
             <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="childName" label="孩子" width="100"></el-table-column>
             <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
             <el-table-column prop="title" label="心愿名称" min-width="200"></el-table-column>
@@ -323,6 +322,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     draftWishes() {
     draftWishes() {
       return this.pendingWishes.filter(w => w.status === 'draft')
       return this.pendingWishes.filter(w => w.status === 'draft')
     },
     },
@@ -436,6 +438,7 @@ export default {
     },
     },
     handleSizeChange(val) {
     handleSizeChange(val) {
       this.pagination.size = val
       this.pagination.size = val
+      this.pagination.current = 1
       this.loadWishes()
       this.loadWishes()
     },
     },
     handleCurrentChange(val) {
     handleCurrentChange(val) {

+ 8 - 4
cfc-web/src/views/admin/Activities.vue

@@ -57,8 +57,7 @@
         <el-button type="primary" size="mini" @click="handleSearch">查询</el-button>
         <el-button type="primary" size="mini" @click="handleSearch">查询</el-button>
         <el-button size="mini" @click="resetSearch">重置</el-button>
         <el-button size="mini" @click="resetSearch">重置</el-button>
       </div>
       </div>
-      <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-        <el-table :data="activities" v-loading="loading" border stripe style="min-width:900px;">
+        <el-table :data="activities" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column label="封面" width="80">
         <el-table-column label="封面" width="80">
           <template slot-scope="{ row }">
           <template slot-scope="{ row }">
@@ -109,7 +108,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-        </el-table></div>
+        </el-table>
       <el-pagination
       <el-pagination
         v-if="total > 0"
         v-if="total > 0"
         @size-change="handleSizeChange"
         @size-change="handleSizeChange"
@@ -130,7 +129,7 @@
       width="800px"
       width="800px"
       @closed="regDialogVisible = false"
       @closed="regDialogVisible = false"
     >
     >
-      <el-table :data="registrations" v-loading="regLoading" border stripe>
+      <el-table :data="registrations" v-loading="regLoading" border stripe :max-height="300">
         <el-table-column prop="id" label="ID" width="60" />
         <el-table-column prop="id" label="ID" width="60" />
         <el-table-column prop="userId" label="用户ID" width="70" />
         <el-table-column prop="userId" label="用户ID" width="70" />
         <el-table-column prop="childId" label="孩子ID" width="70" />
         <el-table-column prop="childId" label="孩子ID" width="70" />
@@ -182,6 +181,11 @@ const DIMENSION_MAP = {
 
 
 export default {
 export default {
   name: 'Activities',
   name: 'Activities',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

+ 5 - 3
cfc-web/src/views/admin/ActivityRegistrationReview.vue

@@ -17,8 +17,7 @@
     </div>
     </div>
 
 
     <div class="table-scroll-wrap-sm">
     <div class="table-scroll-wrap-sm">
-      <div style="overflow:auto;max-height:calc(100vh - 300px);">
-      <el-table style="max-height:calc(100vh - 300px);" :data="filteredList" v-loading="loading" border stripe>
+      <el-table :max-height="tableHeight" :data="filteredList" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="userId" label="用户ID" width="70" />
       <el-table-column prop="userId" label="用户ID" width="70" />
       <el-table-column prop="childId" label="孩子ID" width="70" />
       <el-table-column prop="childId" label="孩子ID" width="70" />
@@ -41,7 +40,7 @@
           <span v-else style="color: #999;">已处理</span>
           <span v-else style="color: #999;">已处理</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-      </el-table></div>
+      </el-table>
     </div>
     </div>
 
 
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
@@ -74,6 +73,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredList() {
     filteredList() {
       if (!this.keyword) return this.list
       if (!this.keyword) return this.list
       var kw = this.keyword.toLowerCase()
       var kw = this.keyword.toLowerCase()

+ 7 - 3
cfc-web/src/views/admin/ActivityReview.vue

@@ -23,8 +23,7 @@
           <el-button size="mini" @click="resetSearch">重置</el-button>
           <el-button size="mini" @click="resetSearch">重置</el-button>
         </div>
         </div>
       </div>
       </div>
-      <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-        <el-table :data="pendingActivities" v-loading="loading" border stripe style="min-width:900px;">
+        <el-table :data="pendingActivities" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="80" />
       <el-table-column prop="id" label="ID" width="80" />
       <el-table-column prop="title" label="活动标题" min-width="200" show-overflow-tooltip />
       <el-table-column prop="title" label="活动标题" min-width="200" show-overflow-tooltip />
       <el-table-column prop="applicant" label="申请人" width="120" />
       <el-table-column prop="applicant" label="申请人" width="120" />
@@ -54,7 +53,7 @@
             <span v-else class="no-op">—</span>
             <span v-else class="no-op">—</span>
           </template>
           </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
     <el-pagination
     <el-pagination
         v-if="total > 0"
         v-if="total > 0"
         @current-change="handlePageChange"
         @current-change="handlePageChange"
@@ -73,6 +72,11 @@ import { getActivityList, reviewActivity } from '@/api/activity'
 
 
 export default {
 export default {
   name: 'ActivityReview',
   name: 'ActivityReview',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

+ 4 - 1
cfc-web/src/views/admin/ArticleCategory.vue

@@ -9,7 +9,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap-sm">
       <div class="table-scroll-wrap-sm">
-      <el-table :data="filteredData" v-loading="loading" border stripe>
+      <el-table :data="filteredData" v-loading="loading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column label="图标" width="80">
         <el-table-column label="图标" width="80">
           <template slot-scope="{ row }">
           <template slot-scope="{ row }">
@@ -115,6 +115,9 @@ export default {
     this.loadData()
     this.loadData()
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredData() {
     filteredData() {
       if (!this.keyword) return this.categories
       if (!this.keyword) return this.categories
       const kw = this.keyword.toLowerCase()
       const kw = this.keyword.toLowerCase()

+ 7 - 2
cfc-web/src/views/admin/ArticleManage.vue

@@ -56,7 +56,7 @@
       </div>
       </div>
 
 
       <div class="table-scroll-wrap-lg">
       <div class="table-scroll-wrap-lg">
-        <el-table :data="list" v-loading="loading" border stripe style="max-height:calc(100vh - 300px);" :max-height="600">
+        <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
           <el-table-column prop="id" label="ID" width="70" />
           <el-table-column prop="id" label="ID" width="70" />
         <el-table-column label="标题" min-width="220">
         <el-table-column label="标题" min-width="220">
           <template slot-scope="{ row }">
           <template slot-scope="{ row }">
@@ -217,7 +217,7 @@
         />
         />
       </div>
       </div>
     </el-card>
     </el-card>
-  </div>
+    </div>
 
 
   <!-- 驳回弹窗 -->
   <!-- 驳回弹窗 -->
   <el-dialog title="驳回原因" :visible.sync="rejectDialogVisible" width="400px">
   <el-dialog title="驳回原因" :visible.sync="rejectDialogVisible" width="400px">
@@ -253,6 +253,11 @@ import { getTagList } from '@/api/dimension.js'
 
 
 export default {
 export default {
   name: 'ArticleManage',
   name: 'ArticleManage',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

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

@@ -28,8 +28,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap-sm">
       <div class="table-scroll-wrap-sm">
-      <div style="overflow:auto;max-height:calc(100vh - 300px);">
-      <el-table style="max-height:calc(100vh - 300px);" :data="filteredData" border stripe>
+      <el-table :max-height="tableHeight" :data="filteredData" border stripe>
         <el-table-column prop="id" label="ID" width="60" />
         <el-table-column prop="id" label="ID" width="60" />
         <el-table-column prop="title" label="标题" />
         <el-table-column prop="title" label="标题" />
         <el-table-column prop="content" label="内容" show-overflow-tooltip />
         <el-table-column prop="content" label="内容" show-overflow-tooltip />
@@ -56,7 +55,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
       </div>
       </div>
     </el-card>
     </el-card>
 
 
@@ -104,6 +103,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredData() {
     filteredData() {
       if (!this.keyword) return this.materials
       if (!this.keyword) return this.materials
       const kw = this.keyword.toLowerCase()
       const kw = this.keyword.toLowerCase()

+ 185 - 0
cfc-web/src/views/admin/AssessmentAssign.vue

@@ -0,0 +1,185 @@
+<template>
+  <div class="assessment-assign admin-page">
+    <el-card>
+      <div slot="header" class="admin-page-header">
+        <span class="admin-page-title">测评待分配规划师</span>
+        <el-button type="primary" size="small" icon="el-icon-refresh" @click="loadList">刷新</el-button>
+      </div>
+
+        <el-table :max-height="tableHeight" :data="list" v-loading="loading" border stripe empty-text="暂无可分配记录">
+          <el-table-column prop="id" label="ID" width="70" />
+          <el-table-column label="用户" width="120">
+            <template slot-scope="{ row }">{{ row.userName }}</template>
+          </el-table-column>
+          <el-table-column label="孩子" width="120">
+            <template slot-scope="{ row }">{{ row.childName }}</template>
+          </el-table-column>
+          <el-table-column label="预约日期" width="120">
+            <template slot-scope="{ row }">{{ row.appointmentDate || '-' }}</template>
+          </el-table-column>
+          <el-table-column label="预约时间" width="90">
+            <template slot-scope="{ row }">{{ row.appointmentTime || '-' }}</template>
+          </el-table-column>
+          <el-table-column label="类型" width="80">
+            <template slot-scope="{ row }">
+              <el-tag size="mini">{{ row.appointmentType === 'initial' ? '初测' : row.appointmentType === 'retest' ? '复测' : row.appointmentType || '-' }}</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="备注" min-width="160" show-overflow-tooltip>
+            <template slot-scope="{ row }">{{ row.notes || '-' }}</template>
+          </el-table-column>
+          <el-table-column label="创建时间" width="160">
+            <template slot-scope="{ row }">{{ row.createdAt }}</template>
+          </el-table-column>
+          <el-table-column label="操作" width="220" fixed="right">
+            <template slot-scope="{ row }">
+              <el-button size="mini" type="primary" @click="openAssignDialog(row)">分配规划师</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="page"
+        :page-sizes="[10, 20, 50]"
+        :page-size="size"
+        :total="total"
+        layout="total, sizes, prev, pager, next, jumper"
+        class="pagination-wrap"
+      />
+    </el-card>
+
+    <el-dialog title="分配规划师" :visible.sync="assignDialogVisible" width="480px">
+      <div v-loading="guidesLoading">
+        <el-form label-width="100px">
+          <el-form-item label="预约ID">
+            <el-input :value="currentAppointmentId" disabled />
+          </el-form-item>
+          <el-form-item label="用户">
+            <el-input :value="currentUserName" disabled />
+          </el-form-item>
+          <el-form-item label="孩子">
+            <el-input :value="currentChildName" disabled />
+          </el-form-item>
+          <el-form-item label="选择规划师">
+            <el-select v-model="selectedGuideId" placeholder="请选择规划师" style="width:100%" filterable>
+              <el-option
+                v-for="g in guides"
+                :key="g.id"
+                :label="g.nickname + (g.realName ? ' (' + g.realName + ')' : '') + (g.teacherNo ? ' - ' + g.teacherNo : '')"
+                :value="g.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer">
+        <el-button @click="assignDialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="confirmAssign" :loading="assigning">确认分配</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getPendingAssessmentList, getAvailableGuides, assignGuide } from '@/api/admin'
+
+export default {
+  name: 'AssessmentAssign',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      list: [],
+      page: 1,
+      size: 10,
+      total: 0,
+      assignDialogVisible: false,
+      guidesLoading: false,
+      assigning: false,
+      guides: [],
+      currentAppointmentId: null,
+      currentUserName: '',
+      currentChildName: '',
+      selectedGuideId: null
+    }
+  },
+  mounted() {
+    this.loadList()
+  },
+  methods: {
+    async loadList() {
+      this.loading = true
+      try {
+        const res = await getPendingAssessmentList({ page: this.page, size: this.size })
+        this.list = res.data.records || []
+        this.total = res.data.total || 0
+      } catch (e) {
+        this.$message.error(e.message || '加载失败')
+      } finally {
+        this.loading = false
+      }
+    },
+    handleSizeChange(val) {
+      this.size = val
+      this.page = 1
+      this.loadList()
+    },
+    handleCurrentChange(val) {
+      this.page = val
+      this.loadList()
+    },
+    async openAssignDialog(row) {
+      this.currentAppointmentId = row.id
+      this.currentUserName = row.userName
+      this.currentChildName = row.childName
+      this.selectedGuideId = null
+      this.assignDialogVisible = true
+
+      this.guidesLoading = true
+      try {
+        const res = await getAvailableGuides()
+        this.guides = res.data || []
+      } catch (e) {
+        this.$message.error(e.message || '加载规划师列表失败')
+      } finally {
+        this.guidesLoading = false
+      }
+    },
+    async confirmAssign() {
+      if (!this.selectedGuideId) {
+        this.$message.warning('请选择规划师')
+        return
+      }
+      this.assigning = true
+      try {
+        await assignGuide(this.currentAppointmentId, this.selectedGuideId)
+        this.$message.success('分配成功')
+        this.assignDialogVisible = false
+        this.loadList()
+      } catch (e) {
+        this.$message.error(e.message || '分配失败')
+      } finally {
+        this.assigning = false
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.assessment-assign .admin-page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.pagination-wrap {
+  margin-top: 20px;
+  text-align: right;
+}
+</style>

+ 6 - 1
cfc-web/src/views/admin/AssessmentPlanRules.vue

@@ -5,7 +5,7 @@
       <el-button type="primary" @click="showDialog(null)">新增规则</el-button>
       <el-button type="primary" @click="showDialog(null)">新增规则</el-button>
     </div>
     </div>
 
 
-    <el-table :data="rules" border stripe style="width: 100%">
+    <el-table :data="rules" border stripe style="width: 100%" :max-height="tableHeight">
       <el-table-column prop="dimension" label="维度" width="120" />
       <el-table-column prop="dimension" label="维度" width="120" />
       <el-table-column label="分数区间" width="140">
       <el-table-column label="分数区间" width="140">
         <template slot-scope="{ row }">{{ row.scoreMin }} - {{ row.scoreMax }}</template>
         <template slot-scope="{ row }">{{ row.scoreMin }} - {{ row.scoreMax }}</template>
@@ -65,6 +65,11 @@
 import { listPlanRules, savePlanRule, deletePlanRule } from '@/api/assessment'
 import { listPlanRules, savePlanRule, deletePlanRule } from '@/api/assessment'
 
 
 export default {
 export default {
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       rules: [],
       rules: [],

+ 7 - 2
cfc-web/src/views/admin/AssessmentProducts.vue

@@ -26,7 +26,7 @@
         </div>
         </div>
       </div>
       </div>
 
 
-      <el-table :data="list" v-loading="loading" border stripe>
+      <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column label="商品图片" width="80">
         <el-table-column label="商品图片" width="80">
           <template slot-scope="{ row }">
           <template slot-scope="{ row }">
@@ -102,6 +102,11 @@ import { getProductList, reviewProduct, shelveProduct } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'AssessmentProducts',
   name: 'AssessmentProducts',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],
@@ -181,7 +186,7 @@ export default {
       if (price === 0) return '免费'
       if (price === 0) return '免费'
       return '¥' + (price / 100).toFixed(2)
       return '¥' + (price / 100).toFixed(2)
     },
     },
-    handleSizeChange(val) { this.size = val; this.loadList() },
+    handleSizeChange(val) { this.size = val; this.page = 1; this.loadList() },
     handlePageChange(val) { this.page = val; this.loadList() }
     handlePageChange(val) { this.page = val; this.loadList() }
   }
   }
 }
 }

+ 4 - 1
cfc-web/src/views/admin/BaziConfigs.vue

@@ -9,7 +9,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap">
       <div class="table-scroll-wrap">
-      <el-table :data="filteredData" stripe
+      <el-table :data="filteredData" stripe :max-height="tableHeight"
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <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="stemOrBranch" label="天干/地支" width="100"></el-table-column>
         <el-table-column prop="type" label="类型" width="80">
         <el-table-column prop="type" label="类型" width="80">
@@ -119,6 +119,9 @@ export default {
     this.loadData()
     this.loadData()
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredData() {
     filteredData() {
       if (!this.keyword) return this.configs
       if (!this.keyword) return this.configs
       const kw = this.keyword.toLowerCase()
       const kw = this.keyword.toLowerCase()

+ 4 - 1
cfc-web/src/views/admin/BloodTypeConfigs.vue

@@ -8,7 +8,7 @@
           <el-button type="primary" size="small" @click="handleCreate">+ 添加配置</el-button>
           <el-button type="primary" size="small" @click="handleCreate">+ 添加配置</el-button>
         </div>
         </div>
       </div>
       </div>
-      <div class="table-scroll-wrap"><el-table :data="filteredData" stripe>
+      <div class="table-scroll-wrap"><el-table :data="filteredData" stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="bloodType" label="血型" width="80"></el-table-column>
         <el-table-column prop="bloodType" label="血型" width="80"></el-table-column>
         <el-table-column prop="description" label="性格描述" min-width="200"></el-table-column>
         <el-table-column prop="description" label="性格描述" min-width="200"></el-table-column>
@@ -97,6 +97,9 @@ export default {
     this.loadData()
     this.loadData()
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredData() {
     filteredData() {
       if (!this.keyword) return this.configs
       if (!this.keyword) return this.configs
       const kw = this.keyword.toLowerCase()
       const kw = this.keyword.toLowerCase()

+ 13 - 4
cfc-web/src/views/admin/CouponManagement.vue

@@ -11,8 +11,7 @@
       </div>
       </div>
 
 
       <div class="table-scroll-wrap-sm">
       <div class="table-scroll-wrap-sm">
-        <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 :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="name" label="名称" min-width="140" show-overflow-tooltip />
         <el-table-column prop="name" label="名称" min-width="140" show-overflow-tooltip />
         <el-table-column label="类型" width="90">
         <el-table-column label="类型" width="90">
@@ -54,12 +53,12 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-        </el-table></div>
+        </el-table>
       </div>
       </div>
 
 
       <el-pagination
       <el-pagination
         @current-change="onPageChange"
         @current-change="onPageChange"
-        @size-change="onPageChange"
+        @size-change="onSizeChange"
         :current-page="page"
         :current-page="page"
         :page-size="size"
         :page-size="size"
         :total="total"
         :total="total"
@@ -143,6 +142,11 @@ import { getCouponList, createCoupon, updateCoupon, deleteCoupon, batchIssueCoup
 
 
 export default {
 export default {
   name: 'CouponManagement',
   name: 'CouponManagement',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],
@@ -202,6 +206,11 @@ export default {
       this.page = 1
       this.page = 1
       this.loadData()
       this.loadData()
     },
     },
+    onSizeChange(val) {
+      this.size = val
+      this.page = 1
+      this.loadData()
+    },
     onPageChange(p) {
     onPageChange(p) {
       if (p) this.page = p
       if (p) this.page = p
       this.loadData()
       this.loadData()

+ 10 - 2
cfc-web/src/views/admin/EcomSupplierManage.vue

@@ -9,7 +9,7 @@
     </div>
     </div>
 
 
     <div class="table-scroll-wrap">
     <div class="table-scroll-wrap">
-    <el-table :data="list" v-loading="loading" border stripe>
+    <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="name" label="供应商名称" min-width="160" />
       <el-table-column prop="name" label="供应商名称" min-width="160" />
       <el-table-column prop="contactName" label="联系人" width="120" />
       <el-table-column prop="contactName" label="联系人" width="120" />
@@ -29,7 +29,7 @@
     </el-table></div>
     </el-table></div>
 
 
     <el-pagination
     <el-pagination
-      @size-change="onPageChange"
+      @size-change="onSizeChange"
       @current-change="onPageChange"
       @current-change="onPageChange"
       :current-page="page"
       :current-page="page"
       :page-size="size"
       :page-size="size"
@@ -94,6 +94,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     dialogTitle() {
     dialogTitle() {
       return this.editId ? '编辑供应商' : '新增供应商'
       return this.editId ? '编辑供应商' : '新增供应商'
     }
     }
@@ -118,6 +121,11 @@ export default {
       this.page = 1
       this.page = 1
       this.loadList()
       this.loadList()
     },
     },
+    onSizeChange(val) {
+      this.size = val
+      this.page = 1
+      this.loadList()
+    },
     onPageChange(val) {
     onPageChange(val) {
       if (typeof val === 'number') {
       if (typeof val === 'number') {
         this.page = val
         this.page = val

+ 15 - 5
cfc-web/src/views/admin/EmotionAlertManage.vue

@@ -8,9 +8,8 @@
         <el-radio-button label="false">未处理</el-radio-button>
         <el-radio-button label="false">未处理</el-radio-button>
         <el-radio-button label="true">已处理</el-radio-button>
         <el-radio-button label="true">已处理</el-radio-button>
       </el-radio-group>
       </el-radio-group>
-    </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table style="max-height:calc(100vh - 300px);" :data="list" v-loading="loading" border stripe>
+      </div>
+    <el-table :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column prop="childId" label="孩子ID" width="90" />
       <el-table-column prop="childId" label="孩子ID" width="90" />
       <el-table-column label="告警类型" width="140">
       <el-table-column label="告警类型" width="140">
@@ -53,10 +52,10 @@
           <span v-else class="resolved-text">-</span>
           <span v-else class="resolved-text">-</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
-      @size-change="onPageChange"
+      @size-change="onSizeChange"
       @current-change="onPageChange"
       @current-change="onPageChange"
       :current-page="page"
       :current-page="page"
       :page-size="size"
       :page-size="size"
@@ -71,6 +70,12 @@
 import { getEmotionAlertList, resolveEmotionAlert } from '@/api/admin'
 import { getEmotionAlertList, resolveEmotionAlert } from '@/api/admin'
 
 
 export default {
 export default {
+  name: 'EmotionAlertManage',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],
@@ -113,6 +118,11 @@ export default {
       this.page = 1
       this.page = 1
       this.loadList()
       this.loadList()
     },
     },
+    onSizeChange(val) {
+      this.size = val
+      this.page = 1
+      this.loadList()
+    },
     onPageChange(val) {
     onPageChange(val) {
       this.page = val
       this.page = val
       this.loadList()
       this.loadList()

+ 14 - 5
cfc-web/src/views/admin/EnergyRuleManagement.vue

@@ -10,9 +10,8 @@
         </el-select>
         </el-select>
         <el-button type="primary" icon="el-icon-plus" @click="showDialog(null)">新增规则</el-button>
         <el-button type="primary" icon="el-icon-plus" @click="showDialog(null)">新增规则</el-button>
       </div>
       </div>
-    </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table style="max-height:calc(100vh - 300px);" :data="list" v-loading="loading" border stripe>
+      </div>
+    <el-table :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="ruleCode" label="规则编码" width="140" />
       <el-table-column prop="ruleCode" label="规则编码" width="140" />
       <el-table-column prop="ruleName" label="规则名称" min-width="160" show-overflow-tooltip />
       <el-table-column prop="ruleName" label="规则名称" min-width="160" show-overflow-tooltip />
@@ -43,10 +42,10 @@
           </el-dropdown>
           </el-dropdown>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
-      @size-change="onPageChange"
+      @size-change="onSizeChange"
       @current-change="onPageChange"
       @current-change="onPageChange"
       :current-page="page"
       :current-page="page"
       :page-size="size"
       :page-size="size"
@@ -103,6 +102,11 @@ import { getEnergyRuleList, createEnergyRule, updateEnergyRule, deleteEnergyRule
 
 
 export default {
 export default {
   name: 'EnergyRuleManagement',
   name: 'EnergyRuleManagement',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],
@@ -146,6 +150,11 @@ export default {
       } catch (e) { console.error(e) }
       } catch (e) { console.error(e) }
       this.loading = false
       this.loading = false
     },
     },
+    onSizeChange(val) {
+      this.size = val
+      this.page = 1
+      this.loadList()
+    },
     onPageChange(p) {
     onPageChange(p) {
       this.page = typeof p === 'number' ? p : 1
       this.page = typeof p === 'number' ? p : 1
       this.loadList()
       this.loadList()

+ 4 - 1
cfc-web/src/views/admin/EnergySandbox.vue

@@ -41,7 +41,7 @@
         <span>家庭成员数据</span>
         <span>家庭成员数据</span>
         <el-input v-model="memberKeyword" placeholder="搜索成员姓名..." prefix-icon="el-icon-search" size="small" clearable style="float: right; width: 200px;" />
         <el-input v-model="memberKeyword" placeholder="搜索成员姓名..." prefix-icon="el-icon-search" size="small" clearable style="float: right; width: 200px;" />
       </div>
       </div>
-      <el-table :data="filteredMembers" border style="width: 100%">
+      <el-table :data="filteredMembers" border style="width: 100%" :max-height="tableHeight">
         <el-table-column prop="memberType" label="成员类型" width="100"></el-table-column>
         <el-table-column prop="memberType" label="成员类型" width="100"></el-table-column>
         <el-table-column prop="name" label="姓名" width="120"></el-table-column>
         <el-table-column prop="name" label="姓名" width="120"></el-table-column>
         <el-table-column prop="bodyScore" label="身" width="80" align="center">
         <el-table-column prop="bodyScore" label="身" width="80" align="center">
@@ -111,6 +111,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredMembers() {
     filteredMembers() {
       const members = this.sandboxData.members || []
       const members = this.sandboxData.members || []
       if (!this.memberKeyword) return members
       if (!this.memberKeyword) return members

+ 7 - 2
cfc-web/src/views/admin/FamilyEarnings.vue

@@ -9,7 +9,7 @@
     </div>
     </div>
 
 
     <div class="table-scroll-wrap">
     <div class="table-scroll-wrap">
-      <el-table :data="list" v-loading="loading" border stripe @row-click="showDetail">
+      <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight" @row-click="showDetail">
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="familyId" label="家庭ID" width="100" />
         <el-table-column prop="familyId" label="家庭ID" width="100" />
         <el-table-column label="累计推荐收入" width="140">
         <el-table-column label="累计推荐收入" width="140">
@@ -61,7 +61,7 @@
         </el-descriptions>
         </el-descriptions>
 
 
         <h4 style="margin:20px 0 10px">成员贡献</h4>
         <h4 style="margin:20px 0 10px">成员贡献</h4>
-        <el-table :data="detail.members || []" border stripe size="small" v-if="detail && detail.members && detail.members.length > 0">
+        <el-table :data="detail.members || []" border stripe size="small" :max-height="300" v-if="detail && detail.members && detail.members.length > 0">
           <el-table-column label="用户ID" prop="userId" width="80" />
           <el-table-column label="用户ID" prop="userId" width="80" />
           <el-table-column label="昵称" prop="nickname" min-width="120" />
           <el-table-column label="昵称" prop="nickname" min-width="120" />
           <el-table-column label="已分配" width="120">
           <el-table-column label="已分配" width="120">
@@ -96,6 +96,11 @@
 import { getFamilyEarningsList, getFamilyEarningsDetail } from '@/api/admin'
 import { getFamilyEarningsList, getFamilyEarningsDetail } from '@/api/admin'
 
 
 export default {
 export default {
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 6 - 1
cfc-web/src/views/admin/FamilyEarningsWithdraw.vue

@@ -15,7 +15,7 @@
     </div>
     </div>
 
 
     <div class="table-scroll-wrap">
     <div class="table-scroll-wrap">
-      <el-table :data="list" v-loading="loading" border stripe>
+      <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="familyId" label="家庭ID" width="90" />
         <el-table-column prop="familyId" label="家庭ID" width="90" />
         <el-table-column label="类型" width="100">
         <el-table-column label="类型" width="100">
@@ -56,6 +56,11 @@
 import { getFamilyEarningsRecords } from '@/api/admin'
 import { getFamilyEarningsRecords } from '@/api/admin'
 
 
 export default {
 export default {
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 7 - 3
cfc-web/src/views/admin/Foods.vue

@@ -28,8 +28,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap-lg">
       <div class="table-scroll-wrap-lg">
-        <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 :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="name" label="名称" />
         <el-table-column prop="name" label="名称" />
         <el-table-column prop="category" label="分类" width="100" />
         <el-table-column prop="category" label="分类" width="100" />
@@ -61,7 +60,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-        </el-table></div>
+        </el-table>
       </div>
       </div>
     </el-card>
     </el-card>
 
 
@@ -136,6 +135,11 @@ import { getFoodDetail, saveFoodMonths } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'Foods',
   name: 'Foods',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

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

@@ -20,8 +20,7 @@
           <el-button type="primary" size="mini" @click="openCreate">创建任务</el-button>
           <el-button type="primary" size="mini" @click="openCreate">创建任务</el-button>
         </div>
         </div>
       </div>
       </div>
-      <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 :max-height="tableHeight" :data="tasks" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="80" />
         <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="name" label="任务名称" min-width="150" show-overflow-tooltip />
         <el-table-column prop="dimensionCode" label="关联维度" width="100">
         <el-table-column prop="dimensionCode" label="关联维度" width="100">
@@ -68,7 +67,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
       <el-pagination
       <el-pagination
         v-if="total > 0"
         v-if="total > 0"
         @size-change="handleSizeChange"
         @size-change="handleSizeChange"
@@ -174,6 +173,11 @@ const DIMENSION_CONFIG = {
 export default {
 export default {
   name: 'GrowthTaskManagement',
   name: 'GrowthTaskManagement',
   components: { DimensionWeightPicker },
   components: { DimensionWeightPicker },
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

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

@@ -8,8 +8,7 @@
           <el-button type="primary" size="small" @click="handleCreate">+ 新增标签</el-button>
           <el-button type="primary" size="small" @click="handleCreate">+ 新增标签</el-button>
         </div>
         </div>
       </div>
       </div>
-      <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 :max-height="tableHeight" :data="filteredTags" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="tagName" label="标签名称" min-width="200" />
         <el-table-column prop="tagName" label="标签名称" min-width="200" />
         <el-table-column label="类型" width="140">
         <el-table-column label="类型" width="140">
@@ -33,7 +32,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
     </el-card>
     </el-card>
 
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑标签' : '新增标签'" width="450px" :close-on-click-modal="false">
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑标签' : '新增标签'" width="450px" :close-on-click-modal="false">
@@ -89,6 +88,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredTags() {
     filteredTags() {
       if (!this.keyword) return this.tags
       if (!this.keyword) return this.tags
       const kw = this.keyword.toLowerCase()
       const kw = this.keyword.toLowerCase()

+ 8 - 6
cfc-web/src/views/admin/MembershipCenter.vue

@@ -33,8 +33,7 @@
       <div slot="header">
       <div slot="header">
         <span>会员等级配置</span>
         <span>会员等级配置</span>
       </div>
       </div>
-      <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 :max-height="tableHeight" :data="levels" v-loading="levelsLoading" border stripe>
         <el-table-column prop="levelCode" label="等级编码" width="120">
         <el-table-column prop="levelCode" label="等级编码" width="120">
           <template slot-scope="{ row }">
           <template slot-scope="{ row }">
             <el-tag :type="levelTagType(row.levelCode)" size="mini">{{ row.levelCode }}</el-tag>
             <el-tag :type="levelTagType(row.levelCode)" size="mini">{{ row.levelCode }}</el-tag>
@@ -76,7 +75,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
     </el-card>
     </el-card>
 
 
     <!-- 升级记录 -->
     <!-- 升级记录 -->
@@ -84,8 +83,7 @@
       <div slot="header">
       <div slot="header">
         <span>会员升级记录</span>
         <span>会员升级记录</span>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table :data="upgradeRecords" v-loading="recordsLoading" border stripe style="max-height:calc(100vh - 300px);">
+    <el-table :data="upgradeRecords" v-loading="recordsLoading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="userId" label="用户ID" width="80" />
         <el-table-column prop="userId" label="用户ID" width="80" />
         <el-table-column label="从" width="100">
         <el-table-column label="从" width="100">
@@ -111,7 +109,6 @@
           <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
           <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
         </el-table-column>
         </el-table-column>
     </el-table>
     </el-table>
-    </div>
     <el-pagination
     <el-pagination
         v-if="recordsTotal > 0"
         v-if="recordsTotal > 0"
         @size-change="handleRecordSizeChange"
         @size-change="handleRecordSizeChange"
@@ -152,6 +149,11 @@
 <script>
 <script>
 export default {
 export default {
   name: 'MembershipCenter',
   name: 'MembershipCenter',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       // overview
       // overview

+ 8 - 3
cfc-web/src/views/admin/OrderManage.vue

@@ -31,8 +31,7 @@
     </div>
     </div>
 
 
     <div class="table-scroll-wrap-lg">
     <div class="table-scroll-wrap-lg">
-      <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 :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="orderNo" label="订单号" width="180" />
       <el-table-column prop="orderNo" label="订单号" width="180" />
       <el-table-column label="商品" min-width="160">
       <el-table-column label="商品" min-width="160">
         <template slot-scope="{ row }">
         <template slot-scope="{ row }">
@@ -79,7 +78,7 @@
           </el-dropdown>
           </el-dropdown>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-      </el-table></div>
+      </el-table>
     </div>
     </div>
 
 
 <el-pagination
 <el-pagination
@@ -163,6 +162,12 @@
 import { getOrderList, shipOrder, closeOrder, approveRefund, rejectRefund } from '@/api/admin'
 import { getOrderList, shipOrder, closeOrder, approveRefund, rejectRefund } from '@/api/admin'
 
 
 export default {
 export default {
+  name: 'OrderManage',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 6 - 1
cfc-web/src/views/admin/PendingRefund.vue

@@ -28,7 +28,7 @@
     </div>
     </div>
 
 
     <div class="table-scroll-wrap">
     <div class="table-scroll-wrap">
-      <el-table :data="list" v-loading="loading" border stripe>
+      <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column label="类型" width="100">
         <el-table-column label="类型" width="100">
           <template slot-scope="{ row }">
           <template slot-scope="{ row }">
@@ -115,6 +115,11 @@ import { getPendingRefundList, getPendingRefundSummary, cancelPendingRefund } fr
 
 
 export default {
 export default {
   name: 'PendingRefund',
   name: 'PendingRefund',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 6 - 1
cfc-web/src/views/admin/PlanManagement.vue

@@ -16,7 +16,7 @@
       </div>
       </div>
     </div>
     </div>
 
 
-    <el-table :data="plans" border stripe style="width:100%">
+    <el-table :data="plans" border stripe style="width:100%" :max-height="tableHeight">
       <el-table-column prop="id" label="方案ID" width="80" />
       <el-table-column prop="id" label="方案ID" width="80" />
       <el-table-column prop="familyId" label="家庭ID" width="80" />
       <el-table-column prop="familyId" label="家庭ID" width="80" />
       <el-table-column prop="childId" label="孩子ID" width="80" />
       <el-table-column prop="childId" label="孩子ID" width="80" />
@@ -70,6 +70,11 @@
 import { listFamilyPlans, reviewPlan, activatePlan } from '@/api/assessment'
 import { listFamilyPlans, reviewPlan, activatePlan } from '@/api/assessment'
 
 
 export default {
 export default {
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       plans: [],
       plans: [],

+ 7 - 3
cfc-web/src/views/admin/PointsLog.vue

@@ -21,8 +21,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap-sm">
       <div class="table-scroll-wrap-sm">
-      <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 :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
         <el-table-column prop="createdAt" label="时间" width="160">
         <el-table-column prop="createdAt" label="时间" width="160">
           <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
           <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
         </el-table-column>
         </el-table-column>
@@ -66,7 +65,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
     </div>
     </div>
 
 
     <el-pagination
     <el-pagination
@@ -123,6 +122,11 @@ const TYPE_MAP = {
 
 
 export default {
 export default {
   name: 'PointsLog',
   name: 'PointsLog',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

+ 7 - 3
cfc-web/src/views/admin/ProductManage.vue

@@ -36,8 +36,7 @@
       </div>
       </div>
 
 
       <div class="table-scroll-wrap-sm">
       <div class="table-scroll-wrap-sm">
-        <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 :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column label="商品图片" width="80">
       <el-table-column label="商品图片" width="80">
         <template slot-scope="{ row }">
         <template slot-scope="{ row }">
@@ -100,7 +99,7 @@
           </el-dropdown>
           </el-dropdown>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-        </el-table></div>
+        </el-table>
     </div>
     </div>
 
 
     <el-pagination
     <el-pagination
@@ -149,6 +148,11 @@ import { getProductList, reviewProduct, shelveProduct } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'ProductManage',
   name: 'ProductManage',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 14 - 4
cfc-web/src/views/admin/ProductPpointManage.vue

@@ -8,8 +8,7 @@
         <el-button type="success" @click="openAddDialog">新增配置</el-button>
         <el-button type="success" @click="openAddDialog">新增配置</el-button>
       </div>
       </div>
     </div>
     </div>
-    <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 :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column label="商品图片" width="70">
       <el-table-column label="商品图片" width="70">
         <template slot-scope="{ row }">
         <template slot-scope="{ row }">
@@ -67,10 +66,10 @@
           </template>
           </template>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
-      @size-change="onPageChange"
+      @size-change="onSizeChange"
       @current-change="onPageChange"
       @current-change="onPageChange"
       :current-page="page"
       :current-page="page"
       :page-size="size"
       :page-size="size"
@@ -109,6 +108,12 @@
 import { getProductPpointList, saveProductPpoint, deleteProductPpoint, getProductList } from '@/api/admin'
 import { getProductPpointList, saveProductPpoint, deleteProductPpoint, getProductList } from '@/api/admin'
 
 
 export default {
 export default {
+  name: 'ProductPpointManage',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],
@@ -144,6 +149,11 @@ export default {
         this.loading = false
         this.loading = false
       }
       }
     },
     },
+    onSizeChange(val) {
+      this.size = val
+      this.page = 1
+      this.loadList()
+    },
     onPageChange(val) {
     onPageChange(val) {
       this.page = val
       this.page = val
       this.loadList()
       this.loadList()

+ 15 - 5
cfc-web/src/views/admin/ProductProfitRate.vue

@@ -12,9 +12,8 @@
         </el-select>
         </el-select>
         <el-button type="primary" @click="loadList">查询</el-button>
         <el-button type="primary" @click="loadList">查询</el-button>
       </div>
       </div>
-    </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table style="max-height:calc(100vh - 300px);" :data="list" v-loading="loading" border stripe>
+      </div>
+    <el-table :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column prop="id" label="ID" width="70" />
       <el-table-column label="商品图片" width="70">
       <el-table-column label="商品图片" width="70">
         <template slot-scope="{ row }">
         <template slot-scope="{ row }">
@@ -67,10 +66,10 @@
           </template>
           </template>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
-      @size-change="onPageChange"
+      @size-change="onSizeChange"
       @current-change="onPageChange"
       @current-change="onPageChange"
       :current-page="page"
       :current-page="page"
       :page-size="size"
       :page-size="size"
@@ -85,6 +84,12 @@
 import { getProductList, updateProductProfitRate } from '@/api/admin'
 import { getProductList, updateProductProfitRate } from '@/api/admin'
 
 
 export default {
 export default {
+  name: 'ProductProfitRate',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],
@@ -114,6 +119,11 @@ export default {
         this.loading = false
         this.loading = false
       }
       }
     },
     },
+    onSizeChange(val) {
+      this.size = val
+      this.page = 1
+      this.loadList()
+    },
     onPageChange(val) {
     onPageChange(val) {
       this.page = val
       this.page = val
       this.loadList()
       this.loadList()

+ 5 - 6
cfc-web/src/views/admin/PromotionManagement.vue

@@ -6,8 +6,7 @@
           <div style="margin-bottom: 16px">
           <div style="margin-bottom: 16px">
             <el-input v-model="milestoneKeyword" placeholder="搜索里程碑..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleMilestoneSearch" @clear="handleMilestoneSearch" />
             <el-input v-model="milestoneKeyword" placeholder="搜索里程碑..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleMilestoneSearch" @clear="handleMilestoneSearch" />
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table :data="filteredMilestones" v-loading="milestoneLoading" border stripe style="max-height:calc(100vh - 300px);">
+    <el-table :data="filteredMilestones" v-loading="milestoneLoading" border stripe :max-height="tableHeight">
             <el-table-column prop="milestone" label="里程碑" min-width="180" show-overflow-tooltip />
             <el-table-column prop="milestone" label="里程碑" min-width="180" show-overflow-tooltip />
             <el-table-column prop="rewardPoints" label="奖励积分" width="120" />
             <el-table-column prop="rewardPoints" label="奖励积分" width="120" />
             <el-table-column prop="rewardEnergy" label="奖励能量" width="120" />
             <el-table-column prop="rewardEnergy" label="奖励能量" width="120" />
@@ -19,7 +18,6 @@
               </template>
               </template>
             </el-table-column>
             </el-table-column>
     </el-table>
     </el-table>
-    </div>
     </el-tab-pane>
     </el-tab-pane>
         <el-tab-pane label="排行榜" name="leaderboard">
         <el-tab-pane label="排行榜" name="leaderboard">
           <div style="margin-bottom: 16px; display: flex; gap: 16px; align-items: center; flex-wrap: wrap">
           <div style="margin-bottom: 16px; display: flex; gap: 16px; align-items: center; flex-wrap: wrap">
@@ -41,8 +39,7 @@
             <el-button type="primary" @click="handleSearch">搜索</el-button>
             <el-button type="primary" @click="handleSearch">搜索</el-button>
             <el-button @click="resetLeaderboard">重置</el-button>
             <el-button @click="resetLeaderboard">重置</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table :data="leaderboardList" v-loading="leaderboardLoading" border stripe style="max-height:calc(100vh - 300px);">
+    <el-table :data="leaderboardList" v-loading="leaderboardLoading" border stripe :max-height="tableHeight">
             <el-table-column label="排名" width="80" type="index" :index="leaderboardIndex" />
             <el-table-column label="排名" width="80" type="index" :index="leaderboardIndex" />
             <el-table-column label="头像" width="80">
             <el-table-column label="头像" width="80">
               <template slot-scope="{ row }">
               <template slot-scope="{ row }">
@@ -52,7 +49,6 @@
             <el-table-column prop="nickname" label="昵称" min-width="140" show-overflow-tooltip />
             <el-table-column prop="nickname" label="昵称" min-width="140" show-overflow-tooltip />
             <el-table-column prop="referralCount" label="邀请数" width="100" />
             <el-table-column prop="referralCount" label="邀请数" width="100" />
     </el-table>
     </el-table>
-    </div>
     <el-pagination
     <el-pagination
             v-if="leaderboardTotal > leaderboardSize"
             v-if="leaderboardTotal > leaderboardSize"
             @current-change="onLeaderboardPageChange"
             @current-change="onLeaderboardPageChange"
@@ -118,6 +114,9 @@ export default {
     this.loadMilestones()
     this.loadMilestones()
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredMilestones() {
     filteredMilestones() {
       if (!this.milestoneKeyword) return this.milestoneList
       if (!this.milestoneKeyword) return this.milestoneList
       var kw = this.milestoneKeyword.toLowerCase()
       var kw = this.milestoneKeyword.toLowerCase()

+ 6 - 1
cfc-web/src/views/admin/Recipes.vue

@@ -22,7 +22,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap-sm">
       <div class="table-scroll-wrap-sm">
-      <el-table :data="list" v-loading="loading" border stripe>
+      <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="name" label="名称" />
         <el-table-column prop="name" label="名称" />
         <el-table-column prop="mealType" label="类型" width="80" />
         <el-table-column prop="mealType" label="类型" width="80" />
@@ -98,6 +98,11 @@
 <script>
 <script>
 export default {
 export default {
   name: 'Recipes',
   name: 'Recipes',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

+ 4 - 1
cfc-web/src/views/admin/RelationshipTypes.vue

@@ -9,7 +9,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap">
       <div class="table-scroll-wrap">
-      <el-table :data="filteredData" stripe>
+      <el-table :data="filteredData" stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <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="typeKey" label="编码" width="120"></el-table-column>
         <el-table-column prop="typeName" label="显示名称" width="120"></el-table-column>
         <el-table-column prop="typeName" label="显示名称" width="120"></el-table-column>
@@ -134,6 +134,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredData() {
     filteredData() {
       if (!this.keyword) return this.types
       if (!this.keyword) return this.types
       const kw = this.keyword.toLowerCase()
       const kw = this.keyword.toLowerCase()

+ 6 - 1
cfc-web/src/views/admin/SeasonalFoods.vue

@@ -17,7 +17,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap">
       <div class="table-scroll-wrap">
-      <el-table :data="list" v-loading="loading" border stripe>
+      <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="foodId" label="食材ID" width="80" />
         <el-table-column prop="foodId" label="食材ID" width="80" />
         <el-table-column label="月份" width="80">
         <el-table-column label="月份" width="80">
@@ -74,6 +74,11 @@
 <script>
 <script>
 export default {
 export default {
   name: 'SeasonalFoods',
   name: 'SeasonalFoods',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     const now = new Date()
     const now = new Date()
     return {
     return {

+ 8 - 3
cfc-web/src/views/admin/SubscriptionManagement.vue

@@ -20,8 +20,7 @@
     </div>
     </div>
 
 
     <div class="table-scroll-wrap">
     <div class="table-scroll-wrap">
-      <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 :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column label="家庭信息" min-width="180" show-overflow-tooltip>
         <el-table-column label="家庭信息" min-width="180" show-overflow-tooltip>
           <template slot-scope="{ row }">
           <template slot-scope="{ row }">
@@ -76,7 +75,7 @@
             <el-button v-if="row.status === 'cancelled'" size="mini" type="success" @click="handleActivate(row)">重新激活</el-button>
             <el-button v-if="row.status === 'cancelled'" size="mini" type="success" @click="handleActivate(row)">重新激活</el-button>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
     </div>
     </div>
 
 
     <el-pagination
     <el-pagination
@@ -174,6 +173,12 @@
 import { getSubscriptionList, activateSubscription, cancelSubscriptionAdmin } from '@/api/admin'
 import { getSubscriptionList, activateSubscription, cancelSubscriptionAdmin } from '@/api/admin'
 
 
 export default {
 export default {
+  name: 'SubscriptionManagement',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 6 - 3
cfc-web/src/views/admin/SupplierProductManage.vue

@@ -25,8 +25,7 @@
     </div>
     </div>
 
 
     <div class="table-scroll-wrap-sm">
     <div class="table-scroll-wrap-sm">
-      <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 :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
           <el-table-column prop="id" label="ID" width="70" />
           <el-table-column prop="id" label="ID" width="70" />
           <el-table-column label="商品图片" width="80">
           <el-table-column label="商品图片" width="80">
             <template slot-scope="{ row }">
             <template slot-scope="{ row }">
@@ -83,7 +82,6 @@
             </template>
             </template>
           </el-table-column>
           </el-table-column>
         </el-table>
         </el-table>
-      </div>
     </div>
     </div>
 
 
     <el-pagination
     <el-pagination
@@ -105,6 +103,11 @@ import { getSupplierProductList, shelveSupplierProduct } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'SupplierProductManage',
   name: 'SupplierProductManage',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

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

@@ -7,8 +7,7 @@
         <el-button type="primary" size="small" @click="addConfig" icon="el-icon-plus">新增配置</el-button>
         <el-button type="primary" size="small" @click="addConfig" icon="el-icon-plus">新增配置</el-button>
       </div>
       </div>
     </div>
     </div>
-    <div class="table-scroll-wrap" style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table :data="list" v-loading="loading" border stripe style="max-height:calc(100vh - 300px);">
+    <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
       <el-table-column prop="configKey" label="配置键" min-width="200" show-overflow-tooltip />
       <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="configValue" label="配置值" min-width="250" show-overflow-tooltip />
       <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
       <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
@@ -31,10 +30,9 @@
         </template>
         </template>
       </el-table-column>
       </el-table-column>
     </el-table>
     </el-table>
-    </div>
 
 
     <el-pagination
     <el-pagination
-      @size-change="onPageChange"
+      @size-change="onSizeChange"
       @current-change="onPageChange"
       @current-change="onPageChange"
       :current-page="page"
       :current-page="page"
       :page-size="size"
       :page-size="size"
@@ -77,6 +75,12 @@
 import { getSysConfigList, createSysConfig, updateSysConfig, deleteSysConfig } from '@/api/admin'
 import { getSysConfigList, createSysConfig, updateSysConfig, deleteSysConfig } from '@/api/admin'
 
 
 export default {
 export default {
+  name: 'SysConfig',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],
@@ -121,6 +125,11 @@ export default {
       this.page = 1
       this.page = 1
       this.loadList()
       this.loadList()
     },
     },
+    onSizeChange(val) {
+      this.size = val
+      this.page = 1
+      this.loadList()
+    },
     onPageChange(val) {
     onPageChange(val) {
       this.page = val
       this.page = val
       this.loadList()
       this.loadList()

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

@@ -20,8 +20,7 @@
       <div slot="header">
       <div slot="header">
         <span>成员列表</span>
         <span>成员列表</span>
       </div>
       </div>
-      <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 :max-height="tableHeight" :data="members" stripe v-loading="membersLoading">
         <el-table-column prop="id" label="关系ID" width="80"></el-table-column>
         <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="userId" label="用户ID" width="100"></el-table-column>
         <el-table-column label="用户昵称" width="140">
         <el-table-column label="用户昵称" width="140">
@@ -51,7 +50,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
     </el-card>
     </el-card>
 
 
     <el-dialog :visible.sync="addDialogVisible" title="添加成员" width="500px" :close-on-click-modal="false">
     <el-dialog :visible.sync="addDialogVisible" title="添加成员" width="500px" :close-on-click-modal="false">
@@ -148,6 +147,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     teamName() {
     teamName() {
       return this.teamInfo.name || '加载中...'
       return this.teamInfo.name || '加载中...'
     },
     },

+ 5 - 2
cfc-web/src/views/admin/VirtualTeamList.vue

@@ -20,7 +20,7 @@
         <el-button size="small" type="primary" @click="loadData">查询</el-button>
         <el-button size="small" type="primary" @click="loadData">查询</el-button>
     </div>
     </div>
 
 
-    <div style="overflow:auto;max-height:calc(100vh - 300px);"><el-table style="max-height:calc(100vh - 300px);" :data="pagedData" stripe v-loading="loading">
+    <el-table :max-height="tableHeight" :data="pagedData" stripe v-loading="loading">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="name" label="团队名称" width="160"></el-table-column>
         <el-table-column prop="name" label="团队名称" width="160"></el-table-column>
         <el-table-column prop="description" label="描述" show-overflow-tooltip></el-table-column>
         <el-table-column prop="description" label="描述" show-overflow-tooltip></el-table-column>
@@ -56,7 +56,7 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
         v-if="filteredData.length > pageSize"
         v-if="filteredData.length > pageSize"
@@ -129,6 +129,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredData() {
     filteredData() {
       if (!this.searchKeyword) return this.teams
       if (!this.searchKeyword) return this.teams
       var kw = this.searchKeyword.toLowerCase()
       var kw = this.searchKeyword.toLowerCase()

+ 4 - 1
cfc-web/src/views/admin/ZodiacConfigs.vue

@@ -9,7 +9,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap">
       <div class="table-scroll-wrap">
-      <el-table :data="filteredData" stripe>
+      <el-table :data="filteredData" stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <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="zodiacCode" label="代码" width="120"></el-table-column>
         <el-table-column prop="zodiacName" label="名称"></el-table-column>
         <el-table-column prop="zodiacName" label="名称"></el-table-column>
@@ -116,6 +116,9 @@ export default {
     this.loadData()
     this.loadData()
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredData() {
     filteredData() {
       if (!this.keyword) return this.configs
       if (!this.keyword) return this.configs
       const kw = this.keyword.toLowerCase()
       const kw = this.keyword.toLowerCase()

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

@@ -5,8 +5,7 @@
       <el-button type="primary" size="mini" icon="el-icon-plus" @click="showDialog(null)">添加SKU</el-button>
       <el-button type="primary" size="mini" icon="el-icon-plus" @click="showDialog(null)">添加SKU</el-button>
     </div>
     </div>
 
 
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table :data="skus" border stripe size="small" style="max-height:calc(100vh - 300px);">
+    <el-table :data="skus" border stripe size="small" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column label="规格" min-width="120">
       <el-table-column label="规格" min-width="120">
         <template slot-scope="{ row }">
         <template slot-scope="{ row }">
@@ -44,7 +43,6 @@
         </template>
         </template>
       </el-table-column>
       </el-table-column>
     </el-table>
     </el-table>
-  </div>
 
 
     <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px" @close="resetForm">
     <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px" @close="resetForm">
       <el-form ref="skuForm" :model="skuForm" :rules="skuRules" label-width="80px">
       <el-form ref="skuForm" :model="skuForm" :rules="skuRules" label-width="80px">
@@ -121,6 +119,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     dialogTitle() {
     dialogTitle() {
       return this.editingId ? '编辑SKU' : '添加SKU'
       return this.editingId ? '编辑SKU' : '添加SKU'
     },
     },

+ 7 - 4
cfc-web/src/views/admin/data-source-config.vue

@@ -9,8 +9,7 @@
         </div>
         </div>
       </div>
       </div>
       <div class="table-scroll-wrap-sm">
       <div class="table-scroll-wrap-sm">
-      <div style="overflow:auto;max-height:calc(100vh - 300px);">
-      <el-table style="max-height:calc(100vh - 300px);" :data="records" stripe v-loading="loading">
+      <el-table :max-height="tableHeight" :data="records" stripe v-loading="loading">
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <el-table-column prop="memberId" label="成员ID" width="80"></el-table-column>
         <el-table-column prop="memberId" label="成员ID" width="80"></el-table-column>
         <el-table-column prop="sourceType" label="类型" width="100">
         <el-table-column prop="sourceType" label="类型" width="100">
@@ -44,12 +43,11 @@
             </el-dropdown>
             </el-dropdown>
           </template>
           </template>
         </el-table-column>
         </el-table-column>
-      </el-table></div>
+      </el-table>
       </div>
       </div>
       <el-pagination
       <el-pagination
         v-if="total > 0"
         v-if="total > 0"
         class="pagination-wrap"
         class="pagination-wrap"
-        :total="total"
         style="margin-top:16px;text-align:right"
         style="margin-top:16px;text-align:right"
         :page.sync="page"
         :page.sync="page"
         :limit.sync="size"
         :limit.sync="size"
@@ -106,6 +104,11 @@
 <script>
 <script>
 export default {
 export default {
   name: 'DataSourceConfig',
   name: 'DataSourceConfig',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

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

@@ -6,8 +6,7 @@
         <el-input v-model="keyword" placeholder="搜索维度/来源..." prefix-icon="el-icon-search" style="width:200px;float:right;margin-right:8px" clearable @keyup.enter.native="loadData" @clear="loadData" />
         <el-input v-model="keyword" placeholder="搜索维度/来源..." prefix-icon="el-icon-search" style="width:200px;float:right;margin-right:8px" clearable @keyup.enter.native="loadData" @clear="loadData" />
         <el-button style="float: right;margin-right:8px" type="primary" size="small" @click="handleCreate">+ 添加常模</el-button>
         <el-button style="float: right;margin-right:8px" type="primary" size="small" @click="handleCreate">+ 添加常模</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-    <el-table :data="filteredNorms" stripe v-loading="loading" style="max-height:calc(100vh - 300px);">
+    <el-table :data="filteredNorms" stripe v-loading="loading" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <el-table-column prop="id" label="ID" width="60"></el-table-column>
         <el-table-column prop="dimension" label="维度" width="100">
         <el-table-column prop="dimension" label="维度" width="100">
           <template slot-scope="scope">
           <template slot-scope="scope">
@@ -53,7 +52,6 @@
         </template>
         </template>
       </el-table-column>
       </el-table-column>
     </el-table>
     </el-table>
-    </div>
   </el-card>
   </el-card>
 
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑常模' : '添加常模'" width="600px">
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑常模' : '添加常模'" width="600px">
@@ -146,6 +144,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     filteredNorms() {
     filteredNorms() {
       if (!this.keyword) return this.norms
       if (!this.keyword) return this.norms
       var kw = this.keyword.toLowerCase()
       var kw = this.keyword.toLowerCase()

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

@@ -7,8 +7,7 @@
         <el-button style="float: right; margin-left: 10px" type="primary" size="small" @click="handleCreate">+ 新增维度</el-button>
         <el-button style="float: right; margin-left: 10px" type="primary" size="small" @click="handleCreate">+ 新增维度</el-button>
 </div>
 </div>
 
 
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-      <el-table :data="filteredData" stripe v-loading="loading" style="max-height:calc(100vh - 300px);">
+      <el-table :data="filteredData" stripe v-loading="loading" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="dimensionCode" label="代码" width="120" />
         <el-table-column prop="dimensionCode" label="代码" width="120" />
         <el-table-column prop="dimensionName" label="名称" width="160" />
         <el-table-column prop="dimensionName" label="名称" width="160" />
@@ -35,7 +34,6 @@
           </template>
           </template>
         </el-table-column>
         </el-table-column>
     </el-table>
     </el-table>
-    </div>
   </el-card>
   </el-card>
 
 
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑维度' : '新增维度'" width="500px">
     <el-dialog :visible.sync="dialogVisible" :title="isEdit ? '编辑维度' : '新增维度'" width="500px">
@@ -112,6 +110,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     ...mapState('dimension', ['dimensionTree']),
     ...mapState('dimension', ['dimensionTree']),
     filteredData() {
     filteredData() {
       if (!this.keyword) return this.dimensions
       if (!this.keyword) return this.dimensions

+ 7 - 2
cfc-web/src/views/admin/energy-config/WuxingConfig.vue

@@ -11,7 +11,7 @@
         <el-input v-model="sourceKeyword" placeholder="搜索来源类型/名称..." prefix-icon="el-icon-search" style="width: 250px; float: right; margin-bottom: 15px;" clearable @keyup.enter.native="loadSourceConfigs" @clear="loadSourceConfigs" />
         <el-input v-model="sourceKeyword" placeholder="搜索来源类型/名称..." prefix-icon="el-icon-search" style="width: 250px; float: right; margin-bottom: 15px;" clearable @keyup.enter.native="loadSourceConfigs" @clear="loadSourceConfigs" />
         <div style="clear: both;"></div>
         <div style="clear: both;"></div>
 
 
-        <el-table :data="filteredSourceConfigs" stripe v-loading="sourceLoading" style="margin-top: 10px;">
+        <el-table :data="filteredSourceConfigs" stripe v-loading="sourceLoading" style="margin-top: 10px;" :max-height="tableHeight">
           <el-table-column prop="sourceType" label="来源类型" width="120" show-overflow-tooltip></el-table-column>
           <el-table-column prop="sourceType" label="来源类型" width="120" show-overflow-tooltip></el-table-column>
           <el-table-column prop="sourceName" label="来源名称" width="150" show-overflow-tooltip></el-table-column>
           <el-table-column prop="sourceName" label="来源名称" width="150" show-overflow-tooltip></el-table-column>
           <el-table-column label="维度比例" min-width="300">
           <el-table-column label="维度比例" min-width="300">
@@ -37,7 +37,7 @@
       <!-- Section 2: Daily Limits Overview (read-only for V1) -->
       <!-- Section 2: Daily Limits Overview (read-only for V1) -->
       <div>
       <div>
         <h3 style="margin-bottom: 15px; color: #606266;">每日能量限制(只读)</h3>
         <h3 style="margin-bottom: 15px; color: #606266;">每日能量限制(只读)</h3>
-        <el-table :data="dailyLimits" stripe border>
+        <el-table :data="dailyLimits" stripe border :max-height="tableHeight">
           <el-table-column prop="dimensionCode" label="维度" width="120">
           <el-table-column prop="dimensionCode" label="维度" width="120">
             <template slot-scope="scope">
             <template slot-scope="scope">
               <el-tag :type="getDimensionType(scope.row.dimensionCode)">{{ getDimensionLabel(scope.row.dimensionCode) }}</el-tag>
               <el-tag :type="getDimensionType(scope.row.dimensionCode)">{{ getDimensionLabel(scope.row.dimensionCode) }}</el-tag>
@@ -117,6 +117,11 @@
 <script>
 <script>
 export default {
 export default {
   name: 'WuxingEnergyConfig',
   name: 'WuxingEnergyConfig',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       sourceLoading: false,
       sourceLoading: false,

+ 6 - 1
cfc-web/src/views/admin/health-knowledge.vue

@@ -21,7 +21,7 @@
         </el-form-item>
         </el-form-item>
       </el-form>
       </el-form>
 
 
-      <el-table :data="list" border stripe v-loading="loading" empty-text="暂无数据" style="width:100%">
+      <el-table :data="list" border stripe v-loading="loading" empty-text="暂无数据" style="width:100%" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="60" />
         <el-table-column prop="id" label="ID" width="60" />
         <el-table-column prop="itemName" label="指标名称" min-width="140" />
         <el-table-column prop="itemName" label="指标名称" min-width="140" />
         <el-table-column prop="category" label="分类" width="140" />
         <el-table-column prop="category" label="分类" width="140" />
@@ -67,6 +67,11 @@
 
 
 <script>
 <script>
 export default {
 export default {
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       loading: false,
       loading: false,

+ 7 - 3
cfc-web/src/views/admin/indicators/index.vue

@@ -16,8 +16,7 @@
     </div>
     </div>
 
 
     <!-- 表格 -->
     <!-- 表格 -->
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-      <el-table :data="list" border stripe v-loading="loading" style="max-height:calc(100vh - 300px);">
+      <el-table :data="list" border stripe v-loading="loading" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="domain" label="领域" width="100" />
       <el-table-column prop="domain" label="领域" width="100" />
       <el-table-column prop="category" label="分类" width="100" />
       <el-table-column prop="category" label="分类" width="100" />
@@ -44,7 +43,6 @@
         </template>
         </template>
       </el-table-column>
       </el-table-column>
     </el-table>
     </el-table>
-    </div>
 
 
     <!-- 编辑弹窗 -->
     <!-- 编辑弹窗 -->
     <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px">
     <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px">
@@ -95,6 +93,12 @@
 
 
 <script>
 <script>
 export default {
 export default {
+  name: 'IndicatorsIndex',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 7 - 3
cfc-web/src/views/admin/review/ActivityAudit.vue

@@ -10,8 +10,7 @@
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="title" label="活动名称" min-width="200" show-overflow-tooltip />
       <el-table-column prop="title" label="活动名称" min-width="200" show-overflow-tooltip />
       <el-table-column label="审核状态" width="100">
       <el-table-column label="审核状态" width="100">
@@ -29,7 +28,7 @@
           <span v-else class="no-op">—</span>
           <span v-else class="no-op">—</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
@@ -46,6 +45,11 @@ import { getActivityList, auditActivity } from '@/api/activity'
 
 
 export default {
 export default {
   name: 'ActivityAudit',
   name: 'ActivityAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [], loading: false, keyword: '', statusFilter: 'pending',
       list: [], loading: false, keyword: '', statusFilter: 'pending',

+ 7 - 3
cfc-web/src/views/admin/review/ActivityRegistrationAudit.vue

@@ -9,8 +9,7 @@
       </el-select>
       </el-select>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column label="用户" width="120">
       <el-table-column label="用户" width="120">
         <template slot-scope="{ row }">{{ row.nickname || row.userName || '-' }}</template>
         <template slot-scope="{ row }">{{ row.nickname || row.userName || '-' }}</template>
@@ -32,7 +31,7 @@
           <span v-else class="no-op">—</span>
           <span v-else class="no-op">—</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -42,6 +41,11 @@ import { approveRegistration, rejectRegistration } from '@/api/activity'
 
 
 export default {
 export default {
   name: 'ActivityRegistrationAudit',
   name: 'ActivityRegistrationAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [], loading: false, statusFilter: 'pending'
       list: [], loading: false, statusFilter: 'pending'

+ 7 - 3
cfc-web/src/views/admin/review/ArticleAudit.vue

@@ -12,8 +12,7 @@
       <el-button v-if="selectedRows.length > 0 && statusFilter === 'pending'" size="small" type="success" @click="handleBatchApprove">批量通过({{ selectedRows.length }})</el-button>
       <el-button v-if="selectedRows.length > 0 && statusFilter === 'pending'" size="small" type="success" @click="handleBatchApprove">批量通过({{ selectedRows.length }})</el-button>
       <el-button v-if="selectedRows.length > 0 && statusFilter === 'pending'" size="small" type="danger" @click="showBatchRejectDialog">批量驳回({{ selectedRows.length }})</el-button>
       <el-button v-if="selectedRows.length > 0 && statusFilter === 'pending'" size="small" type="danger" @click="showBatchRejectDialog">批量驳回({{ selectedRows.length }})</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" @selection-change="onSelectionChange">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight" @selection-change="onSelectionChange">
       <el-table-column type="selection" width="40" v-if="statusFilter === 'pending'" />
       <el-table-column type="selection" width="40" v-if="statusFilter === 'pending'" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="title" label="标题" min-width="200" show-overflow-tooltip />
       <el-table-column prop="title" label="标题" min-width="200" show-overflow-tooltip />
@@ -39,7 +38,7 @@
           <el-button v-else size="mini" type="primary" @click="showDetail(row)">查看</el-button>
           <el-button v-else size="mini" type="primary" @click="showDetail(row)">查看</el-button>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
       v-if="total > 0"
       v-if="total > 0"
@@ -103,6 +102,11 @@ import { adminArticleList, adminArticleAudit } from '@/api/article'
 
 
 export default {
 export default {
   name: 'ArticleAudit',
   name: 'ArticleAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 7 - 3
cfc-web/src/views/admin/review/ButlerAudit.vue

@@ -9,8 +9,7 @@
       </el-select>
       </el-select>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="档案ID" width="80" />
       <el-table-column prop="id" label="档案ID" width="80" />
       <el-table-column prop="userId" label="用户ID" width="80" />
       <el-table-column prop="userId" label="用户ID" width="80" />
       <el-table-column prop="tier" label="等级" width="80" />
       <el-table-column prop="tier" label="等级" width="80" />
@@ -29,7 +28,7 @@
           <span v-else class="no-op">—</span>
           <span v-else class="no-op">—</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
@@ -46,6 +45,11 @@ import { getButlerList, reviewButler } from '@/api/butler'
 
 
 export default {
 export default {
   name: 'ButlerAudit',
   name: 'ButlerAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [], loading: false, statusFilter: 'pending',
       list: [], loading: false, statusFilter: 'pending',

+ 7 - 3
cfc-web/src/views/admin/review/GuideAudit.vue

@@ -10,8 +10,7 @@
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="nickname" label="昵称" width="120" />
       <el-table-column prop="nickname" label="昵称" width="120" />
       <el-table-column prop="realName" label="真实姓名" width="120" />
       <el-table-column prop="realName" label="真实姓名" width="120" />
@@ -30,7 +29,7 @@
           <span v-else class="no-op">—</span>
           <span v-else class="no-op">—</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
       v-if="total > 0"
       v-if="total > 0"
@@ -57,6 +56,11 @@ import { getGuideApplications, approveGuide, rejectGuide } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'GuideAudit',
   name: 'GuideAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [], loading: false, keyword: '', statusFilter: 'pending',
       list: [], loading: false, keyword: '', statusFilter: 'pending',

+ 7 - 3
cfc-web/src/views/admin/review/HierarchyAudit.vue

@@ -9,8 +9,7 @@
       </el-select>
       </el-select>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="applicantName" label="申请人" width="120" />
       <el-table-column prop="applicantName" label="申请人" width="120" />
       <el-table-column prop="currentSuperior" label="当前上级" width="120" />
       <el-table-column prop="currentSuperior" label="当前上级" width="120" />
@@ -30,7 +29,7 @@
           <span v-else class="no-op">—</span>
           <span v-else class="no-op">—</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
@@ -48,6 +47,11 @@ import { reviewSupplyHierarchyChange } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'HierarchyAudit',
   name: 'HierarchyAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [], loading: false, statusFilter: 'pending',
       list: [], loading: false, statusFilter: 'pending',

+ 7 - 3
cfc-web/src/views/admin/review/NutritionistAudit.vue

@@ -10,8 +10,7 @@
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="nickname" label="昵称" width="120" />
       <el-table-column prop="nickname" label="昵称" width="120" />
       <el-table-column prop="realName" label="真实姓名" width="120" />
       <el-table-column prop="realName" label="真实姓名" width="120" />
@@ -30,7 +29,7 @@
           <span v-else class="no-op">—</span>
           <span v-else class="no-op">—</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
@@ -47,6 +46,11 @@ import { getNutritionistApplications, approveNutritionist, rejectNutritionist }
 
 
 export default {
 export default {
   name: 'NutritionistAudit',
   name: 'NutritionistAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [], loading: false, keyword: '', statusFilter: 'pending',
       list: [], loading: false, keyword: '', statusFilter: 'pending',

+ 7 - 3
cfc-web/src/views/admin/review/PackageAudit.vue

@@ -11,8 +11,7 @@
       <el-button v-if="selectedRows.length > 0 && statusFilter === 'pending'" size="small" type="success" @click="handleBatchApprove">批量通过({{ selectedRows.length }})</el-button>
       <el-button v-if="selectedRows.length > 0 && statusFilter === 'pending'" size="small" type="success" @click="handleBatchApprove">批量通过({{ selectedRows.length }})</el-button>
       <el-button v-if="selectedRows.length > 0 && statusFilter === 'pending'" size="small" type="danger" @click="showBatchRejectDialog">批量驳回({{ selectedRows.length }})</el-button>
       <el-button v-if="selectedRows.length > 0 && statusFilter === 'pending'" size="small" type="danger" @click="showBatchRejectDialog">批量驳回({{ selectedRows.length }})</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" @selection-change="onSelectionChange">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight" @selection-change="onSelectionChange">
       <el-table-column type="selection" width="40" v-if="statusFilter === 'pending'" />
       <el-table-column type="selection" width="40" v-if="statusFilter === 'pending'" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="name" label="任务模板名称" min-width="180" show-overflow-tooltip />
       <el-table-column prop="name" label="任务模板名称" min-width="180" show-overflow-tooltip />
@@ -44,7 +43,7 @@
           <el-button v-else size="mini" type="primary" @click="showDetail(row)">查看</el-button>
           <el-button v-else size="mini" type="primary" @click="showDetail(row)">查看</el-button>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
       v-if="total > 0"
       v-if="total > 0"
@@ -106,6 +105,11 @@ import { getPackageList, reviewPackage } from '@/api/package'
 
 
 export default {
 export default {
   name: 'PackageAudit',
   name: 'PackageAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 7 - 3
cfc-web/src/views/admin/review/ProductAudit.vue

@@ -9,8 +9,7 @@
       </el-select>
       </el-select>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="name" label="商品名称" min-width="180" show-overflow-tooltip />
       <el-table-column prop="name" label="商品名称" min-width="180" show-overflow-tooltip />
       <el-table-column label="审核状态" width="100">
       <el-table-column label="审核状态" width="100">
@@ -28,7 +27,7 @@
           <span v-else class="no-op">—</span>
           <span v-else class="no-op">—</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
@@ -45,6 +44,11 @@ import { getProductList, reviewProduct } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'ProductAudit',
   name: 'ProductAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [], loading: false, statusFilter: 'pending',
       list: [], loading: false, statusFilter: 'pending',

+ 7 - 3
cfc-web/src/views/admin/review/VendorAudit.vue

@@ -10,8 +10,7 @@
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="nickname" label="昵称" width="120" />
       <el-table-column prop="nickname" label="昵称" width="120" />
       <el-table-column prop="realName" label="姓名" width="120" />
       <el-table-column prop="realName" label="姓名" width="120" />
@@ -33,7 +32,7 @@
           <span v-else class="no-op">—</span>
           <span v-else class="no-op">—</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
     <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
       <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
@@ -50,6 +49,11 @@ import { getVendorList, reviewVendor } from '@/api/vendor'
 
 
 export default {
 export default {
   name: 'VendorAudit',
   name: 'VendorAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [], loading: false, keyword: '', statusFilter: 'pending',
       list: [], loading: false, keyword: '', statusFilter: 'pending',

+ 7 - 3
cfc-web/src/views/admin/review/WithdrawAudit.vue

@@ -10,8 +10,7 @@
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
       <el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
     </div>
     </div>
-    <div style="overflow:auto;max-height:calc(100vh - 300px);min-width:0;box-sizing:border-box;">
-    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
+    <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;" :max-height="tableHeight">
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column prop="id" label="ID" width="60" />
       <el-table-column label="用户" width="120">
       <el-table-column label="用户" width="120">
         <template slot-scope="{ row }">{{ row.nickname || row.userName || '-' }}</template>
         <template slot-scope="{ row }">{{ row.nickname || row.userName || '-' }}</template>
@@ -37,7 +36,7 @@
           <span v-else style="color:#999">-</span>
           <span v-else style="color:#999">-</span>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-    </el-table></div>
+    </el-table>
 
 
     <el-pagination
     <el-pagination
       v-if="total > 0"
       v-if="total > 0"
@@ -56,6 +55,11 @@ import { getWithdrawalList, auditWithdrawal } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'WithdrawAudit',
   name: 'WithdrawAudit',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       list: [],
       list: [],

+ 6 - 1
cfc-web/src/views/admin/supply-hierarchy/ChangeRequest.vue

@@ -22,7 +22,7 @@
                 </el-form>
                 </el-form>
             </div>
             </div>
             
             
-            <el-table :data="requests" stripe>
+            <el-table :data="requests" stripe :max-height="tableHeight">
                 <el-table-column prop="id" label="ID" width="60"></el-table-column>
                 <el-table-column prop="id" label="ID" width="60"></el-table-column>
                 <el-table-column prop="systemId" label="体系ID" width="80"></el-table-column>
                 <el-table-column prop="systemId" label="体系ID" width="80"></el-table-column>
                 <el-table-column label="申请人" width="120">
                 <el-table-column label="申请人" width="120">
@@ -71,6 +71,11 @@ import { listAllSupplySystems, getSupplyHierarchyChangeRequests, reviewSupplyHie
 
 
 export default {
 export default {
     name: 'SupplyHierarchyChangeRequest',
     name: 'SupplyHierarchyChangeRequest',
+    computed: {
+      tableHeight() {
+        return window.innerHeight - 300
+      }
+    },
     data() {
     data() {
         return {
         return {
             supplySystems: [],
             supplySystems: [],

+ 6 - 3
cfc-web/src/views/admin/supply-manage/List.vue

@@ -24,8 +24,7 @@
         </el-form-item>
         </el-form-item>
     </el-form>
     </el-form>
 
 
-    <div style="overflow:auto;max-height:calc(100vh - 300px);">
-      <el-table :data="suppliers" stripe v-loading="loading" style="max-height:calc(100vh - 300px);">
+      <el-table :data="suppliers" stripe v-loading="loading" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="70"></el-table-column>
         <el-table-column prop="id" label="ID" width="70"></el-table-column>
         <el-table-column prop="nickname" label="昵称" width="130"></el-table-column>
         <el-table-column prop="nickname" label="昵称" width="130"></el-table-column>
         <el-table-column prop="realName" label="真实姓名" width="120"></el-table-column>
         <el-table-column prop="realName" label="真实姓名" width="120"></el-table-column>
@@ -53,7 +52,6 @@
           </template>
           </template>
         </el-table-column>
         </el-table-column>
     </el-table>
     </el-table>
-    </div>
 
 
     <el-pagination
     <el-pagination
         v-if="total > 0"
         v-if="total > 0"
@@ -74,6 +72,11 @@ import { getSupplyManageList, deleteSupplyManage } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'SupplyManageList',
   name: 'SupplyManageList',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       suppliers: [],
       suppliers: [],

+ 10 - 5
cfc-web/src/views/admin/supply-system/Detail.vue

@@ -9,7 +9,7 @@
       <el-tabs v-model="activeTab">
       <el-tabs v-model="activeTab">
         <!-- Tab 1: 商品 -->
         <!-- Tab 1: 商品 -->
         <el-tab-pane label="商品" name="products">
         <el-tab-pane label="商品" name="products">
-          <el-table :data="products" stripe>
+          <el-table :data="products" stripe :max-height="tableHeight">
             <el-table-column prop="id" label="ID" width="60"></el-table-column>
             <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="name" label="商品名称" min-width="150"></el-table-column>
             <el-table-column prop="price" label="售价(元)" width="100">
             <el-table-column prop="price" label="售价(元)" width="100">
@@ -34,7 +34,7 @@
           <div style="margin-bottom: 15px;">
           <div style="margin-bottom: 15px;">
             <el-button type="primary" size="small" @click="showAddMemberDialog">+ 添加成员</el-button>
             <el-button type="primary" size="small" @click="showAddMemberDialog">+ 添加成员</el-button>
           </div>
           </div>
-          <el-table :data="members" stripe>
+          <el-table :data="members" stripe :max-height="tableHeight">
             <el-table-column prop="id" label="ID" width="60"></el-table-column>
             <el-table-column prop="id" label="ID" width="60"></el-table-column>
             <el-table-column prop="userId" label="用户ID" width="100"></el-table-column>
             <el-table-column prop="userId" label="用户ID" width="100"></el-table-column>
             <el-table-column prop="role" label="角色" width="100">
             <el-table-column prop="role" label="角色" width="100">
@@ -65,7 +65,7 @@
 
 
         <!-- Tab 3: 订单 -->
         <!-- Tab 3: 订单 -->
         <el-tab-pane label="订单" name="orders">
         <el-tab-pane label="订单" name="orders">
-          <el-table :data="orders" stripe>
+          <el-table :data="orders" stripe :max-height="tableHeight">
             <el-table-column prop="id" label="ID" width="60"></el-table-column>
             <el-table-column prop="id" label="ID" width="60"></el-table-column>
             <el-table-column prop="orderNo" label="订单号" width="180"></el-table-column>
             <el-table-column prop="orderNo" label="订单号" width="180"></el-table-column>
             <el-table-column prop="productName" label="商品" min-width="120"></el-table-column>
             <el-table-column prop="productName" label="商品" min-width="120"></el-table-column>
@@ -93,7 +93,7 @@
             <div style="margin-bottom: 15px;">
             <div style="margin-bottom: 15px;">
                 <el-button type="primary" size="small" @click="showCreateSettlementDialog">生成结算单</el-button>
                 <el-button type="primary" size="small" @click="showCreateSettlementDialog">生成结算单</el-button>
             </div>
             </div>
-            <el-table :data="settlements" stripe>
+            <el-table :data="settlements" stripe :max-height="tableHeight">
                 <el-table-column prop="id" label="ID" width="60"></el-table-column>
                 <el-table-column prop="id" label="ID" width="60"></el-table-column>
                 <el-table-column label="结算周期" width="200">
                 <el-table-column label="结算周期" width="200">
                     <template slot-scope="scope">{{ scope.row.periodStart | parseTime('{y}-{m}-{d}') }} ~ {{ scope.row.periodEnd | parseTime('{y}-{m}-{d}') }}</template>
                     <template slot-scope="scope">{{ scope.row.periodStart | parseTime('{y}-{m}-{d}') }} ~ {{ scope.row.periodEnd | parseTime('{y}-{m}-{d}') }}</template>
@@ -150,7 +150,7 @@
 
 
     <!-- 结算明细对话框 -->
     <!-- 结算明细对话框 -->
     <el-dialog title="结算明细" :visible.sync="settlementDetailVisible" width="700px">
     <el-dialog title="结算明细" :visible.sync="settlementDetailVisible" width="700px">
-      <el-table :data="settlementItems">
+      <el-table :data="settlementItems" :max-height="300">
         <el-table-column prop="orderNo" label="订单号" width="160"></el-table-column>
         <el-table-column prop="orderNo" label="订单号" width="160"></el-table-column>
         <el-table-column prop="productName" label="商品" min-width="120"></el-table-column>
         <el-table-column prop="productName" label="商品" min-width="120"></el-table-column>
         <el-table-column prop="amount" label="订单金额(分)" width="120"></el-table-column>
         <el-table-column prop="amount" label="订单金额(分)" width="120"></el-table-column>
@@ -210,6 +210,11 @@ import { getSupplySystemDetail, getSupplySystemMembers, addSupplySystemMember,
 
 
 export default {
 export default {
   name: 'SupplySystemDetail',
   name: 'SupplySystemDetail',
+    computed: {
+      tableHeight() {
+        return window.innerHeight - 300
+      }
+    },
     data() {
     data() {
         return {
         return {
             activeTab: 'members',
             activeTab: 'members',

+ 6 - 1
cfc-web/src/views/admin/supply-system/List.vue

@@ -23,7 +23,7 @@
         </el-form-item>
         </el-form-item>
       </el-form>
       </el-form>
 
 
-      <el-table :data="systems" stripe v-loading="loading">
+      <el-table :data="systems" stripe v-loading="loading" :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <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="name" label="体系名称" min-width="150"></el-table-column>
         <el-table-column prop="settlementPeriodDays" label="账期(天)" width="100"></el-table-column>
         <el-table-column prop="settlementPeriodDays" label="账期(天)" width="100"></el-table-column>
@@ -70,6 +70,11 @@ import { getSupplySystemList, toggleSupplySystemStatus } from '@/api/admin'
 
 
 export default {
 export default {
   name: 'SupplySystemList',
   name: 'SupplySystemList',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return {
     return {
       systems: [],
       systems: [],

+ 7 - 4
cfc-web/src/views/health/HealthReportAudit.vue

@@ -4,7 +4,7 @@
       <h2 class="admin-page-title">报告草稿审核</h2>
       <h2 class="admin-page-title">报告草稿审核</h2>
     </div>
     </div>
 
 
-    <el-table :data="list" v-loading="loading" border stripe>
+    <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
       <el-table-column prop="id" label="草稿ID" width="80" />
       <el-table-column prop="id" label="草稿ID" width="80" />
       <el-table-column label="上传用户" width="120">
       <el-table-column label="上传用户" width="120">
         <template slot-scope="{ row }">{{ row.userId }}</template>
         <template slot-scope="{ row }">{{ row.userId }}</template>
@@ -68,7 +68,7 @@
 
 
           <el-tabs v-model="activeTab">
           <el-tabs v-model="activeTab">
             <el-tab-pane label="指标" name="indicators">
             <el-tab-pane label="指标" name="indicators">
-              <el-table :data="parsedPayload.indicators || []" border size="small" max-height="300">
+              <el-table :data="parsedPayload.indicators || []" border size="small" :max-height="tableHeight">
                 <el-table-column prop="category" label="类别" width="100" />
                 <el-table-column prop="category" label="类别" width="100" />
                 <el-table-column prop="indicatorName" label="指标名称" width="160" />
                 <el-table-column prop="indicatorName" label="指标名称" width="160" />
                 <el-table-column prop="indicatorValue" label="检测值" width="100" />
                 <el-table-column prop="indicatorValue" label="检测值" width="100" />
@@ -84,7 +84,7 @@
               </el-table>
               </el-table>
             </el-tab-pane>
             </el-tab-pane>
             <el-tab-pane label="菌群" name="gutFlora">
             <el-tab-pane label="菌群" name="gutFlora">
-              <el-table :data="parsedPayload.gutFlora || []" border size="small" max-height="300">
+              <el-table :data="parsedPayload.gutFlora || []" border size="small" :max-height="tableHeight">
                 <el-table-column prop="bacteriaName" label="菌种" width="160" />
                 <el-table-column prop="bacteriaName" label="菌种" width="160" />
                 <el-table-column prop="bacteriaValue" label="检测值" width="100" />
                 <el-table-column prop="bacteriaValue" label="检测值" width="100" />
                 <el-table-column prop="normalRange" label="正常范围" width="140" />
                 <el-table-column prop="normalRange" label="正常范围" width="140" />
@@ -93,7 +93,7 @@
               </el-table>
               </el-table>
             </el-tab-pane>
             </el-tab-pane>
             <el-tab-pane label="疾病风险" name="diseaseRisks">
             <el-tab-pane label="疾病风险" name="diseaseRisks">
-              <el-table :data="parsedPayload.diseaseRisks || []" border size="small" max-height="300">
+              <el-table :data="parsedPayload.diseaseRisks || []" border size="small" :max-height="tableHeight">
                 <el-table-column prop="diseaseName" label="疾病" width="200" />
                 <el-table-column prop="diseaseName" label="疾病" width="200" />
                 <el-table-column prop="riskValue" label="风险值" width="100" />
                 <el-table-column prop="riskValue" label="风险值" width="100" />
                 <el-table-column prop="riskLevel" label="风险等级" width="100" />
                 <el-table-column prop="riskLevel" label="风险等级" width="100" />
@@ -125,6 +125,9 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    },
     parsedPayload() {
     parsedPayload() {
       if (!this.detail || !this.detail.payloadJson) return null
       if (!this.detail || !this.detail.payloadJson) return null
       try {
       try {

+ 6 - 1
cfc-web/src/views/nutritionist/HealthCheckins.vue

@@ -2,7 +2,7 @@
   <div class="health-checkins">
   <div class="health-checkins">
     <el-card>
     <el-card>
       <div slot="header"><span>健康打卡</span></div>
       <div slot="header"><span>健康打卡</span></div>
-      <el-table :data="checkins" v-loading="loading" border stripe>
+      <el-table :data="checkins" v-loading="loading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="childName" label="孩子" width="120" />
         <el-table-column prop="childName" label="孩子" width="120" />
         <el-table-column prop="checkinType" label="打卡类型" width="120" />
         <el-table-column prop="checkinType" label="打卡类型" width="120" />
@@ -16,6 +16,11 @@
 <script>
 <script>
 export default {
 export default {
   name: 'HealthCheckins',
   name: 'HealthCheckins',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() { return { loading: false, checkins: [] } },
   data() { return { loading: false, checkins: [] } },
   created() { this.loadCheckins() },
   created() { this.loadCheckins() },
   methods: {
   methods: {

+ 6 - 1
cfc-web/src/views/nutritionist/HealthIndicators.vue

@@ -2,7 +2,7 @@
   <div class="health-indicators">
   <div class="health-indicators">
     <el-card>
     <el-card>
       <div slot="header"><span>健康指标</span></div>
       <div slot="header"><span>健康指标</span></div>
-      <el-table :data="indicators" v-loading="loading" border stripe :cell-style="cellStyle">
+      <el-table :data="indicators" v-loading="loading" border stripe :max-height="tableHeight" :cell-style="cellStyle">
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column prop="childName" label="孩子" width="120" />
         <el-table-column prop="childName" label="孩子" width="120" />
         <el-table-column prop="indicatorName" label="指标名称" width="120">
         <el-table-column prop="indicatorName" label="指标名称" width="120">
@@ -40,6 +40,11 @@
 <script>
 <script>
 export default {
 export default {
   name: 'HealthIndicators',
   name: 'HealthIndicators',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() { return { loading: false, indicators: [] } },
   data() { return { loading: false, indicators: [] } },
   created() { this.loadIndicators() },
   created() { this.loadIndicators() },
   methods: {
   methods: {

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

@@ -4,7 +4,7 @@
       <div slot="header">
       <div slot="header">
         <span>健康报告</span>
         <span>健康报告</span>
       </div>
       </div>
-      <el-table :data="reports" v-loading="loading" border stripe>
+      <el-table :data="reports" v-loading="loading" border stripe :max-height="tableHeight">
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column prop="childName" label="孩子" width="100" />
         <el-table-column prop="childName" label="孩子" width="100" />
         <el-table-column prop="reportType" label="报告类型" width="100" />
         <el-table-column prop="reportType" label="报告类型" width="100" />
@@ -49,6 +49,11 @@
 <script>
 <script>
 export default {
 export default {
   name: 'HealthReports',
   name: 'HealthReports',
+  computed: {
+    tableHeight() {
+      return window.innerHeight - 300
+    }
+  },
   data() {
   data() {
     return { loading: false, reports: [], page: 1, size: 20, total: 0 }
     return { loading: false, reports: [], page: 1, size: 20, total: 0 }
   },
   },

Некоторые файлы не были показаны из-за большого количества измененных файлов