Forráskód Böngészése

refactor(web): 复用组件铺开第一批(StatusTag 43 处 + PageHeader 41 处)

StatusTag:
- 迁移单行纯文本状态标签 43 处(17 个文件)
- 保留原有 v-if/v-else 分支与 type 映射,零逻辑变更
- 未动含插值的 118 处:其中混有非状态用途(如数值展示 totalPoints),
  自动替换会误伤语义,留待逐页判断

PageHeader:
- 迁移 admin-page-header 41 处(40 个文件),保留 slot="header" 等属性与内部操作区
- 用 div 配对计数定位闭合标签,兼容含嵌套 div.admin-page-actions 的结构
- 7 处无 admin-page-title 的非标准结构保守跳过
- 修复:迁移脚本误改了 PageHeader.vue 自身注释中的示例代码,已从已提交版本恢复

验证: npm run build EXIT=0(65034ms,428 个文件)
liaoxg 1 hete
szülő
commit
f653297b72
55 módosított fájl, 212 hozzáadás és 175 törlés
  1. 1 1
      cfc-web/.last_build_commit
  2. 1 1
      cfc-web/package.json
  3. 7 1
      cfc-web/public/CHANGELOG.md
  4. 1 1
      cfc-web/src/views/Dashboard.vue
  5. 4 4
      cfc-web/src/views/TaskTemplates.vue
  6. 1 1
      cfc-web/src/views/Wishes.vue
  7. 4 3
      cfc-web/src/views/admin/Activities.vue
  8. 4 3
      cfc-web/src/views/admin/ActivityEdit.vue
  9. 7 6
      cfc-web/src/views/admin/ActivityReview.vue
  10. 4 3
      cfc-web/src/views/admin/ArticleCategory.vue
  11. 4 3
      cfc-web/src/views/admin/ArticleEdit.vue
  12. 18 17
      cfc-web/src/views/admin/ArticleManage.vue
  13. 5 6
      cfc-web/src/views/admin/Assessment.vue
  14. 4 3
      cfc-web/src/views/admin/AssessmentAssign.vue
  15. 5 4
      cfc-web/src/views/admin/AssessmentOrders.vue
  16. 4 3
      cfc-web/src/views/admin/AssessmentProducts.vue
  17. 4 3
      cfc-web/src/views/admin/BaziConfigs.vue
  18. 4 3
      cfc-web/src/views/admin/BloodTypeConfigs.vue
  19. 4 3
      cfc-web/src/views/admin/CouponGrantLog.vue
  20. 4 3
      cfc-web/src/views/admin/CouponManagement.vue
  21. 4 3
      cfc-web/src/views/admin/DanExecution.vue
  22. 4 3
      cfc-web/src/views/admin/DanSettlement.vue
  23. 4 3
      cfc-web/src/views/admin/DiscountRuleManagement.vue
  24. 1 1
      cfc-web/src/views/admin/FamilyEarnings.vue
  25. 5 6
      cfc-web/src/views/admin/Foods.vue
  26. 4 3
      cfc-web/src/views/admin/HealthCheckinManage.vue
  27. 2 2
      cfc-web/src/views/admin/HealthReportReassign.vue
  28. 4 3
      cfc-web/src/views/admin/HomeBannerManage.vue
  29. 3 3
      cfc-web/src/views/admin/IndicatorCorrelations.vue
  30. 1 1
      cfc-web/src/views/admin/IndicatorMappings.vue
  31. 4 3
      cfc-web/src/views/admin/InventoryInboundCreate.vue
  32. 4 3
      cfc-web/src/views/admin/InventoryManage.vue
  33. 5 6
      cfc-web/src/views/admin/MbtiProfiles.vue
  34. 4 3
      cfc-web/src/views/admin/MenuManage.vue
  35. 4 3
      cfc-web/src/views/admin/NoticeManage.vue
  36. 6 7
      cfc-web/src/views/admin/NutritionProducts.vue
  37. 4 3
      cfc-web/src/views/admin/PointsLog.vue
  38. 4 3
      cfc-web/src/views/admin/ProblemDomainManage.vue
  39. 4 3
      cfc-web/src/views/admin/ProductEdit.vue
  40. 4 3
      cfc-web/src/views/admin/ProfileManagement.vue
  41. 1 1
      cfc-web/src/views/admin/ProxyReportUpload.vue
  42. 4 3
      cfc-web/src/views/admin/PurchaseManagement.vue
  43. 4 3
      cfc-web/src/views/admin/Recipes.vue
  44. 4 3
      cfc-web/src/views/admin/RecommendationRules.vue
  45. 2 2
      cfc-web/src/views/admin/ReportCollectorTrainer.vue
  46. 3 3
      cfc-web/src/views/admin/ReportParseStatus.vue
  47. 3 3
      cfc-web/src/views/admin/ReportTypeManagement.vue
  48. 4 3
      cfc-web/src/views/admin/SeasonalFoods.vue
  49. 4 3
      cfc-web/src/views/admin/SupplierProductManage.vue
  50. 4 3
      cfc-web/src/views/admin/SurveyTemplates.vue
  51. 4 3
      cfc-web/src/views/admin/ZodiacConfigs.vue
  52. 4 3
      cfc-web/src/views/admin/data-source-config.vue
  53. 4 3
      cfc-web/src/views/admin/knowledge/index.vue
  54. 1 1
      cfc-web/src/views/nutritionist/HealthReports.vue
  55. 1 1
      cfc-web/src/views/teacher/ProxyReport.vue

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-8a07de7b49e1da3f322c25ffba90927f614baab0
+4e5a28511a232ff37fdcdc7423eb4f89b38c8468

+ 1 - 1
cfc-web/package.json

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

+ 7 - 1
cfc-web/public/CHANGELOG.md

@@ -1,6 +1,6 @@
 # 更新日志
 
-> 当前版本: v1.0.1614
+> 当前版本: v$(node
 
 ## 历史版本
 
@@ -8,6 +8,12 @@
 
 ---
 
+# v1.0 版本历史
+
+[« 返回最新版本](CHANGELOG.md)
+
+---
+
 ## v1.0.1614 (2026-10-14)
 
 ### 新功能

+ 1 - 1
cfc-web/src/views/Dashboard.vue

@@ -170,7 +170,7 @@
 <el-card class="content-card system-health-card" shadow="never">
 <div slot="header" class="card-header">
   <span class="card-title"> 系统状态</span>
-  <el-tag size="mini" type="success">正常运行</el-tag>
+  <StatusTag size="mini" type="success" text="正常运行" />
 </div>
 <div class="health-grid">
   <div class="health-item">

+ 4 - 4
cfc-web/src/views/TaskTemplates.vue

@@ -120,8 +120,8 @@
         </el-table-column>
         <el-table-column prop="taskType" label="性质" width="80">
           <template slot-scope="scope">
-            <el-tag v-if="scope.row.taskType === 'recurring'" type="warning" size="small">循环</el-tag>
-            <el-tag v-else type="info" size="small">一次性</el-tag>
+            <StatusTag v-if="scope.row.taskType === 'recurring'" type="warning" size="small" text="循环" />
+            <StatusTag v-else type="info" size="small" text="一次性" />
           </template>
           <template slot="header">
             <span class="sort-header" @click.stop="onSortClick('taskType', $event)">性质<span v-if="sortIndex('taskType') !== null" class="sort-index" :class="sortClass('taskType') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('taskType') }}</span>{{ sortIcon('taskType') }}</span>
@@ -129,8 +129,8 @@
         </el-table-column>
         <el-table-column prop="needReview" label="需审核" width="80">
           <template slot-scope="scope">
-            <el-tag v-if="scope.row.needReview === 1" type="warning" size="small">是</el-tag>
-            <el-tag v-else type="info" size="small">否</el-tag>
+            <StatusTag v-if="scope.row.needReview === 1" type="warning" size="small" text="是" />
+            <StatusTag v-else type="info" size="small" text="否" />
           </template>
           <template slot="header">
             <span class="sort-header" @click.stop="onSortClick('needReview', $event)">需审核<span v-if="sortIndex('needReview') !== null" class="sort-index" :class="sortClass('needReview') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('needReview') }}</span>{{ sortIcon('needReview') }}</span>

+ 1 - 1
cfc-web/src/views/Wishes.vue

@@ -153,7 +153,7 @@
               </el-table-column>
               <el-table-column label="状态" width="100">
                 <template slot-scope="scope">
-                  <el-tag type="info">等待确认</el-tag>
+                  <StatusTag type="info" text="等待确认" />
                 </template>
               </el-table-column>
             </el-table>

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

@@ -1,10 +1,11 @@
 <template>
   <div class="activities admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">活动管理</span>
+      <PageHeader slot="header" title="活动管理">
+        
         <el-button type="success" size="mini" icon="el-icon-plus" @click="$router.push('/activity-edit')">创建活动</el-button>
-      </div>
+      
+</PageHeader>
 
       <div class="filter-bar" style="margin-bottom:12px;gap:12px;">
         <el-input

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

@@ -1,8 +1,8 @@
 <template>
   <div class="activity-edit admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">{{ readonly && activityStatus !== 'rejected' ? '活动详情' : (isEdit ? '编辑活动' : '创建活动') }}</span>
+      <PageHeader slot="header" :title="readonly && activityStatus !== 'rejected' ? '活动详情' : (isEdit ? '编辑活动' : '创建活动')">
+        
         <div class="admin-page-actions">
           <el-button @click="$router.push('/activities')">返回列表</el-button>
           <template v-if="!readonly && activityStatus !== 'rejected'">
@@ -16,7 +16,8 @@
             <el-button type="primary" size="mini" @click="editFromReadonly">编辑</el-button>
           </template>
         </div>
-      </div>
+      
+</PageHeader>
 
       <!-- 状态横幅 -->
       <el-alert

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

@@ -1,8 +1,8 @@
 <template>
   <div class="activity-review admin-page">
     <el-card>
-      <div class="admin-page-header">
-        <span class="admin-page-title">活动审核</span>
+      <PageHeader  title="活动审核">
+        
         <div class="admin-page-actions" style="gap:12px;">
           <el-input v-model="filter.keyword" placeholder="搜索活动..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px;margin-right:8px;" />
           <el-select v-model="filter.status" placeholder="活动状态" clearable @change="handleSearch" style="width:130px;">
@@ -22,7 +22,8 @@
           <el-button type="primary" size="mini" @click="handleSearch">查询</el-button>
           <el-button size="mini" @click="resetSearch">重置</el-button>
         </div>
-      </div>
+      
+</PageHeader>
                 <div class="adm-table-wrap">
 <el-table :data="pendingActivities" v-loading="loading" border stripe style="min-width:900px;" height="100%">
       <el-table-column prop="id" label="ID" width="80">
@@ -47,9 +48,9 @@
       </el-table-column>
       <el-table-column label="状态" width="100">
         <template slot-scope="{ row }">
-          <el-tag v-if="row.status === 'draft'" type="warning">待审核</el-tag>
-          <el-tag v-else-if="row.status === 'published'" type="success">已发布</el-tag>
-          <el-tag v-else-if="row.status === 'rejected'" type="danger">已驳回</el-tag>
+          <StatusTag v-if="row.status === 'draft'" type="warning" text="待审核" />
+          <StatusTag v-else-if="row.status === 'published'" type="success" text="已发布" />
+          <StatusTag v-else-if="row.status === 'rejected'" type="danger" text="已驳回" />
           <el-tag v-else type="info">{{ row.status }}</el-tag>
         </template>
       </el-table-column>

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

@@ -1,13 +1,14 @@
 <template>
   <div class="article-category admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">文章分类管理</span>
+      <PageHeader slot="header" title="文章分类管理">
+        
         <div class="admin-page-actions">
           <el-input v-model="keyword" placeholder="搜索分类..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-button type="primary" size="small" @click="handleCreate">+ 新增分类</el-button>
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap">
       <el-table :data="filteredData" v-loading="loading" border stripe height="100%">
         <el-table-column prop="id" label="ID" width="70">

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

@@ -1,8 +1,8 @@
 <template>
   <div class="article-edit admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">{{ readonly && articleStatus !== 'rejected' ? '文章详情' : (isEdit ? '编辑文章' : '新建文章') }}</span>
+      <PageHeader slot="header" :title="readonly && articleStatus !== 'rejected' ? '文章详情' : (isEdit ? '编辑文章' : '新建文章')">
+        
         <div class="admin-page-actions">
           <el-button @click="$router.push('/article-manage')">返回列表</el-button>
           <template v-if="!readonly">
@@ -17,7 +17,8 @@
             <el-button type="default" @click="handleCopyAsNew" :loading="saving">复制并新建</el-button>
           </template>
         </div>
-      </div>
+      
+</PageHeader>
 
       <!-- 状态横幅 -->
       <el-alert

+ 18 - 17
cfc-web/src/views/admin/ArticleManage.vue

@@ -2,10 +2,11 @@
   <div class="admin-page">
     <div class="article-manage">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">文章管理</span>
+      <PageHeader slot="header" title="文章管理">
+        
         <el-button type="primary" size="small" @click="$router.push('/article-edit')">+ 新建文章</el-button>
-      </div>
+      
+</PageHeader>
 
       <!-- 状态标签栏 -->
       <div class="status-tabs">
@@ -76,9 +77,9 @@
             <span class="sort-header" @click.stop="onSortClick('visibility', $event)">可见性<span v-if="sortIndex('visibility') !== null" class="sort-index" :class="sortClass('visibility') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('visibility') }}</span>{{ sortIcon('visibility') }}</span>
           </template>
           <template slot-scope="{ row }">
-            <el-tag v-if="row.visibility === 'public'" size="small" type="success">公开</el-tag>
-            <el-tag v-else-if="row.visibility === 'login'" size="small" type="primary">登录</el-tag>
-            <el-tag v-else size="small" type="info">私密</el-tag>
+            <StatusTag v-if="row.visibility === 'public'" size="small" type="success" text="公开" />
+            <StatusTag v-else-if="row.visibility === 'login'" size="small" type="primary" text="登录" />
+            <StatusTag v-else size="small" type="info" text="私密" />
           </template>
         </el-table-column>
         <el-table-column label="内容类型" width="90">
@@ -86,10 +87,10 @@
             <span class="sort-header" @click.stop="onSortClick('contentType', $event)">内容类型<span v-if="sortIndex('contentType') !== null" class="sort-index" :class="sortClass('contentType') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('contentType') }}</span>{{ sortIcon('contentType') }}</span>
           </template>
           <template slot-scope="{ row }">
-            <el-tag v-if="row.contentType === 'article'" size="small" type="primary">文章</el-tag>
-            <el-tag v-else-if="row.contentType === 'knowledge'" size="small" type="success">知识点</el-tag>
-            <el-tag v-else-if="row.contentType === 'course'" size="small" type="warning">课程</el-tag>
-            <el-tag v-else-if="row.contentType === 'tip'" size="small" type="info">贴士</el-tag>
+            <StatusTag v-if="row.contentType === 'article'" size="small" type="primary" text="文章" />
+            <StatusTag v-else-if="row.contentType === 'knowledge'" size="small" type="success" text="知识点" />
+            <StatusTag v-else-if="row.contentType === 'course'" size="small" type="warning" text="课程" />
+            <StatusTag v-else-if="row.contentType === 'tip'" size="small" type="info" text="贴士" />
             <span v-else>-</span>
           </template>
         </el-table-column>
@@ -121,10 +122,10 @@
             <span class="sort-header" @click.stop="onSortClick('status', $event)">状态<span v-if="sortIndex('status') !== null" class="sort-index" :class="sortClass('status') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('status') }}</span>{{ sortIcon('status') }}</span>
           </template>
           <template slot-scope="{ row }">
-            <el-tag v-if="row.status === 'draft' && row.auditStatus === 'pending'" size="small" type="warning">待审核</el-tag>
-            <el-tag v-else-if="row.status === 'draft'" size="small" type="info">草稿箱</el-tag>
-            <el-tag v-else-if="row.status === 'rejected'" size="small" type="danger">已驳回</el-tag>
-            <el-tag v-else-if="row.status === 'published'" size="small" type="success">发布中</el-tag>
+            <StatusTag v-if="row.status === 'draft' && row.auditStatus === 'pending'" size="small" type="warning" text="待审核" />
+            <StatusTag v-else-if="row.status === 'draft'" size="small" type="info" text="草稿箱" />
+            <StatusTag v-else-if="row.status === 'rejected'" size="small" type="danger" text="已驳回" />
+            <StatusTag v-else-if="row.status === 'published'" size="small" type="success" text="发布中" />
             <el-tag v-else-if="row.status === 'withdrawn'" size="small">已撤回</el-tag>
             <el-tag v-else size="small" type="info">{{ row.status }}</el-tag>
           </template>
@@ -134,9 +135,9 @@
             <span class="sort-header" @click.stop="onSortClick('auditStatus', $event)">审核状态<span v-if="sortIndex('auditStatus') !== null" class="sort-index" :class="sortClass('auditStatus') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('auditStatus') }}</span>{{ sortIcon('auditStatus') }}</span>
           </template>
           <template slot-scope="{ row }">
-            <el-tag v-if="row.auditStatus === 'approved'" size="small" type="success">已通过</el-tag>
-            <el-tag v-else-if="row.auditStatus === 'pending'" size="small" type="warning">待审核</el-tag>
-            <el-tag v-else-if="row.auditStatus === 'rejected'" size="small" type="danger" :title="row.auditReason || ''">已驳回</el-tag>
+            <StatusTag v-if="row.auditStatus === 'approved'" size="small" type="success" text="已通过" />
+            <StatusTag v-else-if="row.auditStatus === 'pending'" size="small" type="warning" text="待审核" />
+            <StatusTag v-else-if="row.auditStatus === 'rejected'" size="small" type="danger" :title="row.auditReason || ''" text="已驳回" />
             <span v-else>-</span>
           </template>
         </el-table-column>

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

@@ -1,9 +1,7 @@
 <template>
   <div class="assessment-admin admin-page">
     <el-card class="config-card">
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">💰 积分配置</span>
-      </div>
+      <PageHeader slot="header" title="💰 积分配置"></PageHeader>
       <el-form :model="pointsConfig" label-width="120px">
         <el-form-item label="完成获得积分">
           <el-input-number v-model="pointsConfig.pointsValue" :min="1" :max="1000" />
@@ -20,13 +18,14 @@
     </el-card>
 
     <el-card class="materials-card">
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">📚 测评资料</span>
+      <PageHeader slot="header" title="📚 测评资料">
+        
         <el-input v-model="keyword" placeholder="搜索测评资料..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         <div class="admin-page-actions">
           <el-button type="primary" size="small" @click="showCreateDialog">添加资料</el-button>
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap">
       <el-table height="100%" :data="filteredData" border stripe>
         <el-table-column prop="id" label="ID" width="60" />

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

@@ -1,10 +1,11 @@
 <template>
   <div class="assessment-assign admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">测评待分配规划师</span>
+      <PageHeader slot="header" title="测评待分配规划师">
+        
         <el-button type="primary" size="small" icon="el-icon-refresh" @click="loadList">刷新</el-button>
-      </div>
+      
+</PageHeader>
 
                 <div class="adm-table-wrap">
 <el-table height="100%" :data="list" v-loading="loading" border stripe empty-text="暂无可分配记录">

+ 5 - 4
cfc-web/src/views/admin/AssessmentOrders.vue

@@ -1,8 +1,8 @@
 <template>
   <div class="assessment-orders admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">测评预约管理</span>
+      <PageHeader slot="header" title="测评预约管理">
+        
         <div class="filter-bar">
           <el-input
             v-model="keyword"
@@ -23,7 +23,8 @@
           </el-select>
           <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table height="100%" :data="list" v-loading="loading" border stripe empty-text="暂无测评预约">
@@ -39,7 +40,7 @@
         <el-table-column label="当前规划师" width="120">
           <template slot-scope="{ row }">
             <span v-if="row.guideName">{{ row.guideName }}</span>
-            <el-tag v-else size="mini" type="info">未分配</el-tag>
+            <StatusTag v-else size="mini" type="info" text="未分配" />
           </template>
         </el-table-column>
         <el-table-column label="预约日期" width="120">

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

@@ -1,8 +1,8 @@
 <template>
   <div class="assessment-products admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">测评商品管理</span>
+      <PageHeader slot="header" title="测评商品管理">
+        
         <div class="admin-page-actions">
           <el-input
             v-model="filters.keyword"
@@ -24,7 +24,8 @@
           <el-button type="primary" size="mini" @click="loadList">查询</el-button>
           <el-button type="success" size="mini" icon="el-icon-plus" @click="$router.push('/product-edit')">新增测评商品</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table :data="list" v-loading="loading" border stripe height="100%">

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

@@ -1,13 +1,14 @@
 <template>
   <div class="bazi-configs admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">八字配置管理</span>
+      <PageHeader slot="header" title="八字配置管理">
+        
         <div class="flex items-center gap-sm">
           <el-input v-model="keyword" placeholder="搜索八字..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-button type="primary" size="small" @click="handleCreate">+ 添加配置</el-button>
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap">
       <el-table :data="filteredData" stripe height="100%"
         <el-table-column prop="id" label="ID" width="80">

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

@@ -1,13 +1,14 @@
 <template>
   <div class="blood-type-configs admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">血型配置管理</span>
+      <PageHeader slot="header" title="血型配置管理">
+        
         <div class="flex items-center gap-sm">
           <el-input v-model="keyword" placeholder="搜索血型..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-button type="primary" size="small" @click="handleCreate">+ 添加配置</el-button>
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap"><el-table :data="filteredData" stripe height="100%">
         <el-table-column prop="id" label="ID" width="80">
           <template slot="header">

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

@@ -1,14 +1,15 @@
 <template>
   <div class="coupon-grant-log admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">发券记录</span>
+      <PageHeader slot="header" title="发券记录">
+        
         <div class="admin-page-actions">
           <el-input v-model="familyId" placeholder="家庭ID" clearable style="width: 140px" @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-input v-model="couponId" placeholder="优惠券ID" clearable style="width: 140px" @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-button type="primary" size="small" icon="el-icon-search" @click="handleSearch">查询</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
       <div class="adm-table-wrap">
         <el-table height="100%" :data="list" v-loading="loading" border stripe>

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

@@ -1,8 +1,8 @@
 <template>
   <div class="coupon-management admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">优惠券管理</span>
+      <PageHeader slot="header" title="优惠券管理">
+        
         <div class="admin-page-actions">
           <el-input v-model="keyword" placeholder="搜索优惠券..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-tag
@@ -18,7 +18,8 @@
           <el-button type="primary" size="small" @click="handleCreate">新建优惠券</el-button>
           <el-button type="success" size="small" @click="handleBatchIssue">批量发放</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
       <div class="adm-table-wrap">
         <el-table height="100%" :data="list" v-loading="loading" border stripe>

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

@@ -1,8 +1,8 @@
 <template>
   <div class="dan-execution admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">DAN测评服务执行管理</span>
+      <PageHeader slot="header" title="DAN测评服务执行管理">
+        
         <div class="filter-bar">
           <el-select v-model="statusFilter" placeholder="执行状态" clearable @change="handleSearch" style="width: 140px; margin-right: 10px;">
             <el-option label="全部状态" value="" />
@@ -12,7 +12,8 @@
           </el-select>
           <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table :data="list" v-loading="loading" border stripe empty-text="暂无执行记录" height="100%">

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

@@ -48,8 +48,8 @@
 
     <!-- 结算列表 -->
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">结算记录管理</span>
+      <PageHeader slot="header" title="结算记录管理">
+        
         <div class="filter-bar">
           <el-select v-model="statusFilter" placeholder="结算状态" clearable @change="handleSearch" style="width: 140px; margin-right: 10px;">
             <el-option label="全部状态" value="" />
@@ -64,7 +64,8 @@
           </el-select>
           <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table :data="list" v-loading="loading" border stripe empty-text="暂无结算记录" height="100%">

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

@@ -1,12 +1,13 @@
 <template>
   <div class="discount-rule-management admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">限时折扣管理</span>
+      <PageHeader slot="header" title="限时折扣管理">
+        
         <div class="admin-page-actions">
           <el-button type="primary" size="small" @click="handleCreate">新建规则</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
       <div class="adm-table-wrap">
         <el-table height="100%" :data="list" v-loading="loading" border stripe>

+ 1 - 1
cfc-web/src/views/admin/FamilyEarnings.vue

@@ -88,7 +88,7 @@
           </el-table-column>
           <el-table-column label="管理员" width="80">
             <template slot-scope="{ row }">
-              <el-tag v-if="row.isAdmin" type="warning" size="mini">是</el-tag>
+              <StatusTag v-if="row.isAdmin" type="warning" size="mini" text="是" />
               <span v-else>否</span>
             </template>
           </el-table-column>

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

@@ -1,11 +1,9 @@
 <template>
   <div class="foods admin-page">
     <el-card shadow="never">
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">
-          <i class="el-icon-apple" style="color: #67c23a; margin-right: 8px;"></i>
-          食材管理
-        </span>
+      <PageHeader slot="header" title="<i class=&quot;el-icon-apple&quot; style=&quot;color: #67c23a; margin-right: 8px;&quot;></i>
+          食材管理">
+        
         <div class="header-actions">
           <el-input
             v-model="keyword"
@@ -40,7 +38,8 @@
               </el-tag>
           <el-button type="primary" size="mini" icon="el-icon-plus" @click="openCreate">新建食材</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table

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

@@ -1,8 +1,8 @@
 <template>
   <div class="health-checkins admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">健康打卡管理</span>
+      <PageHeader slot="header" title="健康打卡管理">
+        
         <div class="filter-bar">
           <el-input
             v-model="keyword"
@@ -23,7 +23,8 @@
           </el-select>
           <el-button type="primary" icon="el-icon-refresh" @click="loadList">刷新</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table :data="list" v-loading="loading" border stripe empty-text="暂无打卡记录" height="100%">

+ 2 - 2
cfc-web/src/views/admin/HealthReportReassign.vue

@@ -27,8 +27,8 @@
       </el-table-column>
       <el-table-column label="归属状态" width="120">
         <template slot-scope="{ row }">
-          <el-tag v-if="row.subjectId" type="success" size="small">已归属</el-tag>
-          <el-tag v-else type="warning" size="small">未归属</el-tag>
+          <StatusTag v-if="row.subjectId" type="success" size="small" text="已归属" />
+          <StatusTag v-else type="warning" size="small" text="未归属" />
         </template>
       </el-table-column>
       <el-table-column label="当前归属" width="120">

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

@@ -1,10 +1,11 @@
 <template>
   <div class="home-banner-manage admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">首页广告栏</span>
+      <PageHeader slot="header" title="首页广告栏">
+        
         <el-button type="primary" size="mini" icon="el-icon-plus" @click="openDialog()">新增广告位</el-button>
-      </div>
+      
+</PageHeader>
 
       <div class="filter-bar" style="margin-bottom:12px;">
         <el-select v-model="filterStatus" placeholder="启用状态" @change="loadList" clearable style="width:120px;" clearable>

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

@@ -16,8 +16,8 @@
         </el-table-column>
         <el-table-column label="方向" width="80">
           <template slot-scope="{ row }">
-            <el-tag v-if="row.direction === 'positive'" type="success" size="mini">正向</el-tag>
-            <el-tag v-else-if="row.direction === 'negative'" type="danger" size="mini">负向</el-tag>
+            <StatusTag v-if="row.direction === 'positive'" type="success" size="mini" text="正向" />
+            <StatusTag v-else-if="row.direction === 'negative'" type="danger" size="mini" text="负向" />
             <span v-else>-</span>
           </template>
         </el-table-column>
@@ -41,7 +41,7 @@
         </el-table-column>
         <el-table-column label="人工锁定" width="90">
           <template slot-scope="{ row }">
-            <el-tag v-if="row.manualLocked" type="warning" size="mini">锁定</el-tag>
+            <StatusTag v-if="row.manualLocked" type="warning" size="mini" text="锁定" />
             <span v-else>-</span>
           </template>
         </el-table-column>

+ 1 - 1
cfc-web/src/views/admin/IndicatorMappings.vue

@@ -24,7 +24,7 @@
         </el-table-column>
         <el-table-column label="匹配方式" width="110">
           <template slot-scope="{ row }">
-            <el-tag v-if="row.matchType === 'ai_fallback'" type="warning" size="mini">AI 建议</el-tag>
+            <StatusTag v-if="row.matchType === 'ai_fallback'" type="warning" size="mini" text="AI 建议" />
             <span v-else>{{ row.matchType || '-' }}</span>
           </template>
         </el-table-column>

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

@@ -1,10 +1,11 @@
 <template>
   <div class="inbound-create admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">创建入库单</span>
+      <PageHeader slot="header" title="创建入库单">
+        
         <el-button @click="$router.push('/inventory')">返回</el-button>
-      </div>
+      
+</PageHeader>
       <div class="inbound-create-form-wrap">
       <el-form label-width="100px">
         <el-form-item label="入库日期">

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

@@ -1,10 +1,11 @@
 <template>
   <div class="inventory-manage admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">库存管理</span>
+      <PageHeader slot="header" title="库存管理">
+        
         <el-button type="success" size="mini" icon="el-icon-plus" @click="$router.push('/inventory/inbound-create')">创建入库单</el-button>
-      </div>
+      
+</PageHeader>
 
       <el-tabs v-model="activeTab">
         <!-- 库存流水 -->

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

@@ -1,16 +1,15 @@
 <template>
   <div class="mbti-profiles admin-page">
     <el-card shadow="never">
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">
-          <i class="el-icon-user" style="color: #1677FF; margin-right: 8px;"></i>
-          MBTI 人格画像库(16型)
-        </span>
+      <PageHeader slot="header" title="<i class=&quot;el-icon-user&quot; style=&quot;color: #1677FF; margin-right: 8px;&quot;></i>
+          MBTI 人格画像库(16型)">
+        
         <div class="header-actions">
           <el-button type="warning" size="mini" @click="initSeed">初始化种子数据</el-button>
           <el-button type="primary" size="mini" icon="el-icon-plus" @click="openAdd">新增画像</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table :data="list" border stripe v-loading="loading" size="mini" style="width:100%" height="100%">

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

@@ -1,8 +1,8 @@
 <template>
   <div class="menu-manage admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">菜单管理</span>
+      <PageHeader slot="header" title="菜单管理">
+        
         <div class="header-actions">
           <div class="search-box">
             <el-input
@@ -17,7 +17,8 @@
           <el-button type="primary" size="small" @click="openRoleAuth">角色授权</el-button>
           <el-button type="primary" size="small" @click="handleCreate(0)">新增顶级菜单</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
       <div class="adm-table-wrap">
         <el-table

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

@@ -1,10 +1,11 @@
 <template>
   <div class="admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">公告管理</span>
+      <PageHeader slot="header" title="公告管理">
+        
         <el-button type="primary" size="small" @click="openCreate">+ 新建公告</el-button>
-      </div>
+      
+</PageHeader>
 
       <div class="adm-table-wrap">
         <el-table :data="list" v-loading="loading" border stripe height="100%">

+ 6 - 7
cfc-web/src/views/admin/NutritionProducts.vue

@@ -1,11 +1,9 @@
 <template>
   <div class="nutrition-products admin-page">
     <el-card shadow="never">
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">
-          <i class="el-icon-first-aid-kit" style="color: #67c23a; margin-right: 8px;"></i>
-          营养产品管理
-        </span>
+      <PageHeader slot="header" title="<i class=&quot;el-icon-first-aid-kit&quot; style=&quot;color: #67c23a; margin-right: 8px;&quot;></i>
+          营养产品管理">
+        
         <div class="header-actions">
           <el-input
             v-model="keyword"
@@ -40,7 +38,8 @@
             <el-option v-for="opt in brandOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
           </el-select>
         </div>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table
@@ -122,7 +121,7 @@
         </el-table-column>
         <el-table-column label="关联商品" width="90" align="center">
           <template slot-scope="{ row }">
-            <el-tag v-if="row.localProductId" type="success" size="mini">已关联</el-tag>
+            <StatusTag v-if="row.localProductId" type="success" size="mini" text="已关联" />
             <span v-else class="no-data">-</span>
           </template>
         </el-table-column>

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

@@ -1,8 +1,8 @@
 <template>
   <div class="points-log admin-page">
 <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">积分记录</span>
+      <PageHeader slot="header" title="积分记录">
+        
         <div class="admin-page-actions">
           <el-select v-model="filter.type" placeholder="类型筛选" size="mini" clearable @change="loadData">
             <el-option label="全部" value="" />
@@ -19,7 +19,8 @@
           </el-select>
           <el-input v-model="filter.childKeyword" placeholder="搜索孩子 ID..." prefix-icon="el-icon-search" size="mini" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap">
       <el-table height="100%" :data="list" v-loading="loading" border stripe>
         <el-table-column prop="createdAt" label="时间" width="160">

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

@@ -1,10 +1,11 @@
 <template>
   <div class="problem-domain-manage admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">问题域管理(改版v1)</span>
+      <PageHeader slot="header" title="问题域管理(改版v1)">
+        
         <el-button type="primary" size="mini" icon="el-icon-plus" @click="openCreate">新增问题域</el-button>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table :data="list" v-loading="loading" border stripe height="100%">

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

@@ -1,13 +1,14 @@
 <template>
   <div class="product-edit admin-page">
     <el-card v-loading="pageLoading">
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">{{ isEdit ? '编辑商品' : '新增商品' }}</span>
+      <PageHeader slot="header" :title="isEdit ? '编辑商品' : '新增商品'">
+        
         <div class="admin-page-actions">
           <el-button type="primary" size="small" :loading="saving" @click="handleSave()">{{ isEdit ? '保存修改' : '创建商品' }}</el-button>
           <el-button size="small" @click="$router.back()">取消</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
       <div class="product-edit-form-wrap">
       <el-form ref="form" :model="form" :rules="rules" label-width="100px">

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

@@ -1,10 +1,11 @@
 <template>
   <div class="profile-mgmt admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">用户画像管理</span>
+      <PageHeader slot="header" title="用户画像管理">
+        
         <el-button type="primary" size="mini" @click="handleRefresh" :loading="loading">刷新列表</el-button>
-      </div>
+      
+</PageHeader>
 
       <div class="filter-bar" style="margin-bottom:12px;display:flex;gap:12px;align-items:center;">
         <el-input v-model="searchForm.memberId" placeholder="家庭成员ID" clearable style="width:160px;" @keyup.enter.native="loadList" />

+ 1 - 1
cfc-web/src/views/admin/ProxyReportUpload.vue

@@ -56,7 +56,7 @@
     <el-card v-if="analysisResult" style="margin-top:20px">
       <div slot="header" class="card-header">
         <span class="card-title">🤖 AI解读结果</span>
-        <el-tag type="success" size="small">已完成</el-tag>
+        <StatusTag type="success" size="small" text="已完成" />
       </div>
       <div v-html="analysisResult" class="analysis-content"></div>
     </el-card>

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

@@ -1,10 +1,11 @@
 <template>
   <div class="purchase-mgmt admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">健康启航计划管理</span>
+      <PageHeader slot="header" title="健康启航计划管理">
+        
         <el-button type="primary" size="mini" @click="loadList" :loading="loading">刷新</el-button>
-      </div>
+      
+</PageHeader>
 
       <!-- 统计卡片 -->
       <el-row :gutter="16" style="margin-bottom: 16px;">

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

@@ -1,8 +1,8 @@
 <template>
   <div class="recipes admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">食谱管理</span>
+      <PageHeader slot="header" title="食谱管理">
+        
         <div class="admin-page-actions">
           <el-select
             v-model="mealTypeFilter"
@@ -30,7 +30,8 @@
               </el-tag>
           <el-button type="primary" size="mini" @click="openCreate">新建食谱</el-button>
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap">
       <el-table :data="list" v-loading="loading" border stripe height="100%">
         <el-table-column prop="id" label="ID" width="80" />

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

@@ -1,12 +1,13 @@
 <template>
   <div class="recommendation-rules-management admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">商品推荐规则管理</span>
+      <PageHeader slot="header" title="商品推荐规则管理">
+        
         <div class="admin-page-actions">
           <el-button type="primary" size="small" @click="handleCreate">新建规则</el-button>
         </div>
-      </div>
+      
+</PageHeader>
 
       <div class="adm-table-wrap">
         <el-table :data="list" v-loading="loading" border stripe height="100%">

+ 2 - 2
cfc-web/src/views/admin/ReportCollectorTrainer.vue

@@ -66,8 +66,8 @@
             </el-table-column>
             <el-table-column label="标注" width="100">
               <template slot-scope="{ row }">
-                <el-tag v-if="row.annotation" size="small" type="success">已标注</el-tag>
-                <el-tag v-else size="small" type="info">未标注</el-tag>
+                <StatusTag v-if="row.annotation" size="small" type="success" text="已标注" />
+                <StatusTag v-else size="small" type="info" text="未标注" />
               </template>
             </el-table-column>
         </el-card>

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

@@ -30,9 +30,9 @@
         <el-table-column prop="originalFilename" label="文件名" min-width="200" show-overflow-tooltip />
         <el-table-column label="解析状态" width="100">
           <template slot-scope="{ row }">
-            <el-tag v-if="row.parseStatus === 'collecting'" type="info" size="small">采集中</el-tag>
-            <el-tag v-else-if="row.parseStatus === 'completed'" type="success" size="small">成功</el-tag>
-            <el-tag v-else-if="row.parseStatus === 'failed'" type="danger" size="small">失败</el-tag>
+            <StatusTag v-if="row.parseStatus === 'collecting'" type="info" size="small" text="采集中" />
+            <StatusTag v-else-if="row.parseStatus === 'completed'" type="success" size="small" text="成功" />
+            <StatusTag v-else-if="row.parseStatus === 'failed'" type="danger" size="small" text="失败" />
             <el-tag v-else size="small">未触发</el-tag>
           </template>
         </el-table-column>

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

@@ -55,9 +55,9 @@
         </el-table-column>
         <el-table-column label="脚本状态" width="110">
           <template slot-scope="{ row }">
-            <el-tag v-if="row.scriptStatus === 'generating'" type="warning" size="small">生成中</el-tag>
-            <el-tag v-else-if="row.scriptStatus === 'ready'" type="success" size="small">测试通过</el-tag>
-            <el-tag v-else-if="row.scriptStatus === 'failed'" type="danger" size="small">生成失败</el-tag>
+            <StatusTag v-if="row.scriptStatus === 'generating'" type="warning" size="small" text="生成中" />
+            <StatusTag v-else-if="row.scriptStatus === 'ready'" type="success" size="small" text="测试通过" />
+            <StatusTag v-else-if="row.scriptStatus === 'failed'" type="danger" size="small" text="生成失败" />
             <span v-else style="color:#bbb;">—</span>
           </template>
         </el-table-column>

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

@@ -1,8 +1,8 @@
 <template>
   <div class="seasonal-foods admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">应季食材配置</span>
+      <PageHeader slot="header" title="应季食材配置">
+        
         <div class="flex items-center gap-sm">
           <el-select
             v-model="monthFilter"
@@ -15,7 +15,8 @@
           <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-button type="primary" size="mini" @click="openCreate">新增应季映射</el-button>
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap">
       <el-table :data="list" v-loading="loading" border stripe height="100%">
         <el-table-column prop="id" label="ID" width="80">

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

@@ -1,8 +1,8 @@
 <template>
 <div class="supplier-product-manage admin-page">
   <el-card>
-    <div slot="header" class="admin-page-header">
-      <span class="admin-page-title">商品管理</span>
+    <PageHeader slot="header" title="商品管理">
+      
       <div class="admin-page-actions">
         <el-input
           v-model="filters.keyword"
@@ -22,7 +22,8 @@
         <el-button type="primary" size="mini" @click="loadList">查询</el-button>
         <el-button type="success" size="mini" icon="el-icon-plus" @click="handleAdd">新增商品</el-button>
       </div>
-    </div>
+    
+</PageHeader>
 
     <div class="adm-table-wrap">
         <el-table height="100%" :data="list" v-loading="loading" border stripe>

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

@@ -1,11 +1,12 @@
 <template>
   <div class="survey-templates admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">调研模板管理</span>
+      <PageHeader slot="header" title="调研模板管理">
+        
         <el-button type="primary" size="mini" icon="el-icon-plus" @click="openCreate">新增模板</el-button>
         <el-button type="success" size="mini" icon="el-icon-magic-stick" @click="openAiGenerate">AI生成调研</el-button>
-      </div>
+      
+</PageHeader>
 
             <div class="adm-table-wrap">
 <el-table :data="templates" v-loading="loading" border stripe height="100%">

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

@@ -1,13 +1,14 @@
 <template>
   <div class="zodiac-configs admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">星座配置管理</span>
+      <PageHeader slot="header" title="星座配置管理">
+        
         <div class="flex items-center gap-sm">
           <el-input v-model="keyword" placeholder="搜索星座..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
           <el-button type="primary" size="small" @click="handleCreate">+ 添加配置</el-button>
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap">
       <el-table :data="filteredData" stripe height="100%">
         <el-table-column prop="id" label="ID" width="80">

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

@@ -1,13 +1,14 @@
 <template>
   <div class="data-source-config admin-page">
     <el-card>
-      <div slot="header" class="admin-page-header">
-        <span class="admin-page-title">健康数据源配置</span>
+      <PageHeader slot="header" title="健康数据源配置">
+        
         <el-input v-model="keyword" placeholder="搜索数据源..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
         <div class="admin-page-actions">
           <el-button type="primary" size="small" @click="handleCreate">+ 添加数据源</el-button>
         </div>
-      </div>
+      
+</PageHeader>
       <div class="adm-table-wrap">
       <el-table height="100%" :data="records" stripe v-loading="loading">
         <el-table-column prop="id" label="ID" width="60">

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

@@ -36,8 +36,8 @@
         <!-- 右侧知识库列表 -->
         <el-col :span="19">
           <el-card>
-            <div slot="header" class="admin-page-header">
-              <span class="admin-page-title">知识库管理</span>
+            <PageHeader slot="header" title="知识库管理">
+              
               <div class="admin-page-actions">
                 <el-select v-model="filterStatus" placeholder="状态" size="mini" clearable @change="handleSearch">
                   <el-option label="全部" value="" />
@@ -49,7 +49,8 @@
                 <el-button size="mini" @click="resetSearch">重置</el-button>
                 <el-button size="mini" type="primary" @click="handleCreate">+ 新增知识</el-button>
               </div>
-            </div>
+            
+</PageHeader>
 
             <knowledge-table
               :list="knowledgeList"

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

@@ -66,7 +66,7 @@
             <el-tag v-if="row.deficiencyCount > 0" type="danger" size="small">
               {{ row.deficiencyCount }}项缺乏
             </el-tag>
-            <el-tag v-else type="success" size="small">无缺乏</el-tag>
+            <StatusTag v-else type="success" size="small" text="无缺乏" />
             <el-button size="mini" type="text" @click="triggerAnalysis(row)" style="margin-left: 4px">
               {{ row.deficiencyCount > 0 ? '重新分析' : '分析' }}
             </el-button>

+ 1 - 1
cfc-web/src/views/teacher/ProxyReport.vue

@@ -72,7 +72,7 @@
     <el-card v-if="analysisResult" style="margin-top:20px">
       <div slot="header" class="card-header">
         <span class="card-title">🤖 AI解读结果</span>
-        <el-tag type="success" size="small">已完成</el-tag>
+        <StatusTag type="success" size="small" text="已完成" />
       </div>
       <div v-html="analysisResult" class="analysis-content"></div>
     </el-card>