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

feat(cfc-web): v1.0.11 - table overflow scroll fix + Layout sidebar scroll fix

- Wrap el-table in scrollable div with max-height:calc(100vh - Npx) across
  admin pages (Activities, ArticleManage, OrderManage, PointsLog, ProductManage,
  VendorReview, WithdrawAudit) and teacher pages (FamilyList, TeacherAssessment)
- Add overflow-y:auto to Layout sidebar and admin-page container
- Bump version to 1.0.11
Xiaogang Liao 2 месяцев назад
Родитель
Сommit
87b1790171

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-51b2a65b0d3979314d53701ec5d07a690091605d
+a958a3c68bc005a8c386f6b1cf848cc1300b7eb1

+ 48 - 0
cfc-web/CHANGELOG.md

@@ -1,6 +1,54 @@
 # 更新日志 (Changelog)
 
 此文件记录所有构建版本的变更。
+## v1.0.11 (2026-07-08)
+
+### 测试
+- 新增 DAN 测评服务商体系完整流程测试 + 需求验证报告
+- v13 最终版 - SupplySystemServiceTest(18/18), 修复 getAdminList 参数签名, 更新测试文档
+- v13 test records + issue tracking (ISSUE-010~012)
+
+### 其他
+- - 管理员创建三类服务商(测评/解读/规划)
+- - 家长购买测评 → AI 解读 → 人工处理 → 成长规划
+- - 验证需求完整性(80%)和合理性(92%)
+- - 识别 3 个 P0 问题:服务商类型扩展、人工解读功能、成长规划功能
+- - 提供实施建议和代码示例
+- 
+- - cfc-frontend: pages.json/ai.chat/mind.articles/user-edit/wealth 页面优化
+- - cfc-web: 新增 MembershipCenter.vue(295行)/PointsLog.vue(202行),全面更新各管理模块
+- - 67 files changed, 1946 insertions(+), 434 deletions(-)
+- 
+- - ProductOrderController/Service: support mixed payment (points + cash)
+- - PointsService: integrate points deduction for orders
+- - shop pages: refactor detail, index, order-list, order-detail
+- - DatabaseInitializer: resolve merge conflict (keep both migrations 38-40)
+- 
+- Closes ISSUE-007
+- 
+- - 添加supplier_admin角色到UserService.isValidRole()
+- - 添加supplier_admin到AdminAuthController登录角色检测
+- - 添加supplier_admin到数据库users.role ENUM
+- - 创建SupplyManageController供应商管理控制器(CRUD+角色管理+层级调整)
+- 前端:
+- - 添加supplier_admin到permissions.js权限映射
+- - 添加供应商管理菜单到Layout.vue
+- - 添加供应商管理路由到router/index.js
+- - 创建supply-manage/List.vue, Form.vue, Detail.vue
+- - 添加supply-manage API函数到admin.js
+- 
+
+### 新功能
+- 综合更新 - 后端服务修复、前端页面优化、管理端功能扩展
+- add pointsUsed/moneyAmount to ProductOrderDTO + checkout points UI + noMoneyPayment handling
+- product order hybrid payment + shop page refactor + DatabaseInitializer merge conflict resolution
+- 添加供应商管理员(supplier_admin)角色及供应商管理功能
+
+### Bug 修复
+- redesign ContactImport - support WeChat contacts import & fix picker modal issue
+- ISSUE-007 SupplySystemService.create() validate adminId
+
+
 ## v$(node (2026-07-07)
 
 ### Bug 修复

+ 1 - 1
cfc-web/package.json

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

+ 3 - 0
cfc-web/src/views/Layout.vue

@@ -657,6 +657,8 @@ export default {
   display: flex;
   flex-direction: column;
   min-height: 0;
+  overflow-y: auto;
+  overflow-x: hidden;
 }
 
 /* ========== 全局 .admin-page 样式 ========== */
@@ -680,6 +682,7 @@ export default {
   flex-direction: column;
   min-height: 0;
   padding: 20px;
+  overflow-y: auto;
 }
 /* 当 admin-page > div > el-card(如 ArticleManage 的嵌套 div) */
 .admin-page > div:only-child {

+ 3 - 1
cfc-web/src/views/admin/Activities.vue

@@ -21,7 +21,8 @@
           <el-button type="primary" size="mini" @click="$router.push('/activity-edit')">创建活动</el-button>
         </div>
       </div>
-      <el-table :data="activities" v-loading="loading" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 300px);">
+        <el-table :data="activities" v-loading="loading" border stripe style="max-height:calc(100vh - 300px);">
         <el-table-column prop="id" label="ID" width="80" />
         <el-table-column label="封面" width="80">
           <template slot-scope="{ row }">
@@ -73,6 +74,7 @@
           </template>
         </el-table-column>
       </el-table>
+      </div>
       <el-pagination
         v-if="total > 0"
         @size-change="handleSizeChange"

+ 3 - 1
cfc-web/src/views/admin/ArticleManage.vue

@@ -55,7 +55,8 @@
         <el-button type="primary" icon="el-icon-search" @click="loadList">搜索</el-button>
       </div>
 
-      <el-table :data="list" v-loading="loading" border stripe>
+      <div style="overflow:auto;max-height:calc(100vh - 340px);">
+        <el-table :data="list" v-loading="loading" border stripe style="max-height:calc(100vh - 340px);">
         <el-table-column prop="id" label="ID" width="70" />
         <el-table-column label="标题" min-width="220">
           <template slot-scope="{ row }">
@@ -207,6 +208,7 @@
           </template>
         </el-table-column>
       </el-table>
+      </div>
 
       <el-pagination
         @size-change="onPageChange"

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

@@ -18,7 +18,8 @@
       </div>
     </div>
 
-    <el-table :data="list" v-loading="loading" border stripe>
+    <div 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-column prop="orderNo" label="订单号" width="180" />
       <el-table-column label="商品" min-width="160">
         <template slot-scope="{ row }">
@@ -65,6 +66,7 @@
         </template>
       </el-table-column>
     </el-table>
+    </div>
 
     <el-pagination
       @size-change="onSizeChange"

+ 8 - 5
cfc-web/src/views/admin/PointsLog.vue

@@ -18,9 +18,10 @@
             <el-option label="系统积分" value="system" />
           </el-select>
           <el-input v-model="filter.childKeyword" placeholder="搜索孩子ID..." prefix-icon="el-icon-search" size="mini" style="width:180px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
-        </div>
-      </div>
-      <el-table :data="list" v-loading="loading" border stripe>
+    </div>
+    </div>
+    <div 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-column prop="createdAt" label="时间" width="160">
           <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
         </el-table-column>
@@ -64,8 +65,10 @@
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
-      <el-pagination
+    </el-table>
+    </div>
+
+    <el-pagination
         v-if="total > 0"
         @size-change="handleSizeChange"
         @current-change="handlePageChange"

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

@@ -31,7 +31,8 @@
       </div>
     </div>
 
-    <el-table :data="list" v-loading="loading" border stripe>
+    <div 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-column prop="id" label="ID" width="70" />
       <el-table-column label="商品图片" width="80">
         <template slot-scope="{ row }">
@@ -95,6 +96,7 @@
         </template>
       </el-table-column>
     </el-table>
+    </div>
 
     <el-pagination
       @size-change="handleSizeChange"

+ 3 - 2
cfc-web/src/views/admin/VendorReview.vue

@@ -11,7 +11,8 @@
       </el-select>
     </div>
 
-    <el-table :data="list" v-loading="loading" border stripe>
+    <div 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-column prop="id" label="用户ID" width="80" />
       <el-table-column prop="nickname" label="昵称" width="120" />
       <el-table-column prop="realName" label="真实姓名" width="120" />
@@ -44,7 +45,7 @@
             <span v-else class="no-op">—</span>
           </template>
         </el-table-column>
-    </el-table>
+    </el-table></div>
 
     <el-pagination
       @size-change="onPageChange"

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

@@ -13,7 +13,8 @@
       </div>
     </div>
 
-    <el-table :data="list" v-loading="loading" border stripe>
+    <div 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-column prop="id" label="ID" width="70" />
       <el-table-column label="用户" width="120">
         <template slot-scope="{ row }">
@@ -69,7 +70,7 @@
           </el-dropdown>
         </template>
       </el-table-column>
-    </el-table>
+    </el-table></div>
 
     <el-pagination
       @size-change="onPageChange"

+ 22 - 20
cfc-web/src/views/teacher/FamilyList.vue

@@ -5,26 +5,28 @@
         <span>我的家庭</span>
         <el-input v-model="keyword" placeholder="搜索家庭..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
       </div>
-      <el-table :data="filteredFamilies" v-loading="loading" border stripe>
-        <el-table-column prop="id" label="ID" width="80" />
-        <el-table-column prop="familyName" label="家庭名称" />
-        <el-table-column prop="memberCount" label="成员数" width="100" />
-        <el-table-column prop="createdAt" label="绑定时间" width="180" />
-        <el-table-column label="操作" width="200" fixed="right">
-          <template slot-scope="{ row }">
-            <el-button size="mini" type="primary" @click="handleEdit(row)">编辑</el-button>
-            <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
-              <el-button size="mini">
-                更多<i class="el-icon-arrow-down el-icon--right"></i>
-              </el-button>
-              <el-dropdown-menu slot="dropdown">
-                <el-dropdown-item command="view" icon="el-icon-view">查看详情</el-dropdown-item>
-                <el-dropdown-item command="delete" icon="el-icon-delete">删除</el-dropdown-item>
-              </el-dropdown-menu>
-            </el-dropdown>
-          </template>
-        </el-table-column>
-      </el-table>
+  <div style="overflow:auto;max-height:calc(100vh - 320px);">
+    <el-table :data="filteredFamilies" v-loading="loading" border stripe style="max-height:calc(100vh - 320px);">
+      <el-table-column prop="id" label="ID" width="80" />
+      <el-table-column prop="familyName" label="家庭名称" />
+      <el-table-column prop="memberCount" label="成员数" width="100" />
+      <el-table-column prop="createdAt" label="绑定时间" width="180" />
+      <el-table-column label="操作" width="200" fixed="right">
+        <template slot-scope="{ row }">
+          <el-button size="mini" type="primary" @click="handleEdit(row)">编辑</el-button>
+          <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
+            <el-button size="mini">
+              更多<i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item command="view" icon="el-icon-view">查看详情</el-dropdown-item>
+              <el-dropdown-item command="delete" icon="el-icon-delete">删除</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
     </el-card>
   </div>
 </template>

+ 47 - 45
cfc-web/src/views/teacher/TeacherAssessment.vue

@@ -6,51 +6,53 @@
         <el-input v-model="keyword" placeholder="搜索家庭ID..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
       </div>
 
-      <el-table :data="filteredConfigs" border stripe v-loading="loading">
-        <el-table-column prop="familyId" label="家庭ID" width="80" />
-        <el-table-column label="家庭名称" width="120">
-          <template slot-scope="scope">
-            家庭{{ scope.row.familyId }}
-          </template>
-        </el-table-column>
-        <el-table-column prop="materialTitle" label="测评资料" />
-        <el-table-column prop="remindMonths" label="提醒周期" width="100">
-          <template slot-scope="scope">
-            {{ scope.row.remindMonths }}个月
-          </template>
-        </el-table-column>
-        <el-table-column prop="lastRemindAt" label="上次提醒" width="140">
-          <template slot-scope="scope">
-            {{ formatDate(scope.row.lastRemindAt) }}
-          </template>
-        </el-table-column>
-        <el-table-column prop="nextRemindAt" label="下次提醒" width="140">
-          <template slot-scope="scope">
-            {{ formatDate(scope.row.nextRemindAt) }}
-          </template>
-        </el-table-column>
-        <el-table-column label="状态" width="80">
-          <template slot-scope="scope">
-            <el-tag :type="scope.row.isEnabled === 1 ? 'success' : 'info'" size="small">
-              {{ scope.row.isEnabled === 1 ? '启用' : '关闭' }}
-            </el-tag>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" width="200" fixed="right">
-          <template slot-scope="{ row }">
-            <el-button v-if="row.isEnabled !== 1" size="mini" type="primary" @click="enableFamily(row.familyId)">启用</el-button>
-            <el-button v-else size="mini" type="primary" @click="handleEdit(row)">修改周期</el-button>
-            <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
-              <el-button size="mini">
-                更多<i class="el-icon-arrow-down el-icon--right"></i>
-              </el-button>
-              <el-dropdown-menu slot="dropdown">
-                <el-dropdown-item command="disable" icon="el-icon-close">关闭</el-dropdown-item>
-              </el-dropdown-menu>
-            </el-dropdown>
-          </template>
-        </el-table-column>
-      </el-table>
+  <div style="overflow:auto;max-height:calc(100vh - 320px);">
+    <el-table :data="filteredConfigs" border stripe v-loading="loading" style="max-height:calc(100vh - 320px);">
+      <el-table-column prop="familyId" label="家庭ID" width="80" />
+      <el-table-column label="家庭名称" width="120">
+        <template slot-scope="scope">
+          家庭{{ scope.row.familyId }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="materialTitle" label="测评资料" />
+      <el-table-column prop="remindMonths" label="提醒周期" width="100">
+        <template slot-scope="scope">
+          {{ scope.row.remindMonths }}个月
+        </template>
+      </el-table-column>
+      <el-table-column prop="lastRemindAt" label="上次提醒" width="140">
+        <template slot-scope="scope">
+          {{ formatDate(scope.row.lastRemindAt) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="nextRemindAt" label="下次提醒" width="140">
+        <template slot-scope="scope">
+          {{ formatDate(scope.row.nextRemindAt) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="状态" width="80">
+        <template slot-scope="scope">
+          <el-tag :type="scope.row.isEnabled === 1 ? 'success' : 'info'" size="small">
+            {{ scope.row.isEnabled === 1 ? '启用' : '关闭' }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" width="200" fixed="right">
+        <template slot-scope="{ row }">
+          <el-button v-if="row.isEnabled !== 1" size="mini" type="primary" @click="enableFamily(row.familyId)">启用</el-button>
+          <el-button v-else size="mini" type="primary" @click="handleEdit(row)">修改周期</el-button>
+          <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
+            <el-button size="mini">
+              更多<i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item command="disable" icon="el-icon-close">关闭</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
     </el-card>
 
     <el-dialog title="启用家庭DAN测评" :visible.sync="enableDialogVisible" width="500px">