Selaa lähdekoodia

fix(miniapp): 修复图片双前缀 URL + teacher 方案管理页 + 编译错误清理

1. 图片 URL 双前缀修复(23 文件):getImageUrl 统一安全模式
   - 后端已返回完整 OSS URL(https://cfc.s3.cn-north-1.jdcloud-oss.com/...)时直接返回,
     不再拼接 config.API_BASE_URL(https://cfc.etotem.com.cn)
   - 统一 null/'null'/'undefined' 守卫 + http(s) 直通 + 前导斜杠规范化
   - 涉及:activity×2, ai/chat, article-center×2, body-detail/dimension-detail,
     discover/index, growth/upload, guide×3, index-home, meal/recipe-detail,
     mind-detail/articles, promotion/material, shop×5, vendor/products,
     components/RecommendedFeed

2. teacher 方案管理:新增 pages/teacher/plan-create.vue、plan-list.vue 并注册到 pages.json
   - 修复 pages/teacher 分包 plan-detail/plan-list 重复注册(app.json 报错)
   - families.vue: 修复重复 class 属性 + 方案入口卡片

3. docs 参考资料更新(测评样例/知识库 JSON/MD)

未提交:docs/参考资料/知识库/*.vbak-* 备份文件(忽略)
liaoxg 1 viikko sitten
vanhempi
sitoutus
ca76d8a624
33 muutettua tiedostoa jossa 1857 lisäystä ja 418 poistoa
  1. 5 1
      cfc-frontend/components/RecommendedFeed.vue
  2. 12 0
      cfc-frontend/pages.json
  3. 5 3
      cfc-frontend/pages/activity/activity-detail/activity-detail.vue
  4. 5 3
      cfc-frontend/pages/activity/index.vue
  5. 5 1
      cfc-frontend/pages/ai/chat.vue
  6. 5 1
      cfc-frontend/pages/article-center/index.vue
  7. 5 1
      cfc-frontend/pages/article-center/my-posts.vue
  8. 5 1
      cfc-frontend/pages/body-detail/dimension-detail.vue
  9. 5 1
      cfc-frontend/pages/discover/index.vue
  10. 12 3
      cfc-frontend/pages/growth/upload.vue
  11. 12 3
      cfc-frontend/pages/guide/activities/detail.vue
  12. 12 3
      cfc-frontend/pages/guide/activities/index.vue
  13. 12 3
      cfc-frontend/pages/guide/packages/share.vue
  14. 12 3
      cfc-frontend/pages/index-home/index.vue
  15. 12 3
      cfc-frontend/pages/meal/recipe-detail.vue
  16. 12 3
      cfc-frontend/pages/mind-detail/articles.vue
  17. 12 3
      cfc-frontend/pages/promotion/material.vue
  18. 12 3
      cfc-frontend/pages/shop/cart/cart.vue
  19. 12 3
      cfc-frontend/pages/shop/checkout/checkout.vue
  20. 12 3
      cfc-frontend/pages/shop/index/index.vue
  21. 12 3
      cfc-frontend/pages/shop/order-detail/order-detail.vue
  22. 12 3
      cfc-frontend/pages/shop/order-list/order-list.vue
  23. 29 17
      cfc-frontend/pages/teacher/families.vue
  24. 166 0
      cfc-frontend/pages/teacher/plan-create.vue
  25. 231 0
      cfc-frontend/pages/teacher/plan-list.vue
  26. 5 1
      cfc-frontend/pages/vendor/products/products.vue
  27. 12 38
      docs/参考资料/530010234-侯.json
  28. 36 62
      docs/参考资料/547982403.json
  29. 29 59
      docs/参考资料/556168709-mi.json
  30. 13 80
      docs/参考资料/儿童示例.json
  31. 355 27
      docs/参考资料/朱评估报告.json
  32. 642 58
      docs/参考资料/知识库/菌群营养知识库.json
  33. 131 25
      docs/参考资料/知识库/菌群营养知识库.md

+ 5 - 1
cfc-frontend/components/RecommendedFeed.vue

@@ -128,7 +128,11 @@ export default {
       return map[status] || ''
     },
     getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     }
   }
 }

+ 12 - 0
cfc-frontend/pages.json

@@ -113,6 +113,18 @@
             "navigationBarTitleText": "方案详情"
           }
         },
+        {
+          "path": "plan-list",
+          "style": {
+            "navigationBarTitleText": "我的方案"
+          }
+        },
+        {
+          "path": "plan-create",
+          "style": {
+            "navigationBarTitleText": "新建方案"
+          }
+        },
         {
           "path": "team",
           "style": {

+ 5 - 3
cfc-frontend/pages/activity/activity-detail/activity-detail.vue

@@ -358,9 +358,11 @@ export default {
   methods: {
     // ===== 工具方法 =====
     getImageUrl: function(path) {
-      if (!path) return ''
-      if (path.indexOf('http://') === 0 || path.indexOf('https://') === 0) return path
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     },
     checkMemberStatus: function() {
       var that = this

+ 5 - 3
cfc-frontend/pages/activity/index.vue

@@ -376,9 +376,11 @@ export default {
   },
   methods: {
     getImageUrl: function(path) {
-      if (!path) return ''
-      if (path.indexOf('http://') === 0 || path.indexOf('https://') === 0) return path
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     },
     onTabChange: function(key) {
       this.currentTab = key

+ 5 - 1
cfc-frontend/pages/ai/chat.vue

@@ -498,7 +498,11 @@ export default {
       return (d.getMonth() + 1) + '/' + d.getDate()
     },
     getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     }
   }
 }

+ 5 - 1
cfc-frontend/pages/article-center/index.vue

@@ -317,7 +317,11 @@ onLoad(options) {
       uni.navigateBack()
     },
     getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     }
   }
 }

+ 5 - 1
cfc-frontend/pages/article-center/my-posts.vue

@@ -120,7 +120,11 @@ export default {
       return 'status-draft'
     },
     getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     }
   }
 }

+ 5 - 1
cfc-frontend/pages/body-detail/dimension-detail.vue

@@ -329,7 +329,11 @@ export default {
       }
     },
     getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     }
   }
 }

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

@@ -229,7 +229,11 @@ export default {
       uni.navigateTo({ url: '/pages/article-center/article-detail?id=' + id })
     },
     getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     },
     goKnowledgeCenter() {
       uni.navigateTo({ url: '/pages/article-center/index' })

+ 12 - 3
cfc-frontend/pages/growth/upload.vue

@@ -273,9 +273,18 @@ export default {
     formatPrice: function(cents) {
       if (cents === null || cents === undefined) return '¥0'
       return '¥' + (cents / 100).toFixed(2)
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/guide/activities/detail.vue

@@ -318,9 +318,18 @@ export default {
       var h = ('0' + d.getHours()).slice(-2)
       var mi = ('0' + d.getMinutes()).slice(-2)
       return y + '-' + m + '-' + day + ' ' + h + ':' + mi
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/guide/activities/index.vue

@@ -207,9 +207,18 @@ export default {
       var h = ('0' + d.getHours()).slice(-2)
       var mi = ('0' + d.getMinutes()).slice(-2)
       return y + '-' + m + '-' + day + ' ' + h + ':' + mi
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/guide/packages/share.vue

@@ -154,9 +154,18 @@ export default {
     },
     closePoster() {
       this.$refs.posterPopup.close()
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/index-home/index.vue

@@ -1968,9 +1968,18 @@ title: '添加家庭成员',
         self.referralCode = extractReferralCode(res)
       }).catch(function() {})
       self.referralCodeLoaded = true
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     },
     /** 转发给朋友/群(不指定 imageUrl,微信自动截取当前页面截图作缩略图;static/share-cover.png 不存在会导致卡片空白) */
     onShareAppMessage: function() {

+ 12 - 3
cfc-frontend/pages/meal/recipe-detail.vue

@@ -147,9 +147,18 @@ export default {
       } catch (e) {
         this.stepList = str.split(/[;;\n]/).filter(function(s) { return s.trim() })
       }
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/mind-detail/articles.vue

@@ -254,9 +254,18 @@ onShow: function() {
         .replace(/"/gi, '"')
         .replace(/\s+/g, ' ')
         .trim()
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/promotion/material.vue

@@ -220,9 +220,18 @@ export default {
           uni.showToast({ title: '下载失败', icon: 'none' })
         }
         })
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/shop/cart/cart.vue

@@ -422,9 +422,18 @@ export default {
     formatPriceWithSymbol(price) {
       if (price === null || price === undefined) return '0.00'
       return (Number(price) / 100).toFixed(2)
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/shop/checkout/checkout.vue

@@ -1115,9 +1115,18 @@ showOnlineSlotPicker: function() {
     selectServicePerson: function(person) {
       this.selectedServicePerson = person
       this.showServicePersonModal = false
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/shop/index/index.vue

@@ -315,9 +315,18 @@ export default {
     formatPriceWithSymbol(price) {
       if (price === null || price === undefined) return ''
       return '¥' + (Number(price) / 100).toFixed(2)
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 12 - 3
cfc-frontend/pages/shop/order-detail/order-detail.vue

@@ -290,9 +290,18 @@ export default {
     formatPriceWithSymbol(price) {
       if (!price && price !== 0) return '-'
       return '¥' + (price / 100).toFixed(2)
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     },
     // 履约状态标签
     fulfillStatusLabel: function(status) {

+ 12 - 3
cfc-frontend/pages/shop/order-list/order-list.vue

@@ -356,9 +356,18 @@ export default {
     },
     onImgError(e, item) {
       item.coverImage = ''
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+    },getImageUrl: function(path) {
+
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+
+      var s = String(path).trim()
+
+      if (!s || s === 'null' || s === '/null') return ''
+
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
+
     }
   }
 }

+ 29 - 17
cfc-frontend/pages/teacher/families.vue

@@ -5,6 +5,11 @@
       <text class="family-meta">查看待审核方案与任务</text>
     </view>
 
+    <view class="family-card entry" @click="goPlanList">
+      <text class="family-name">我的方案</text>
+      <text class="family-meta">查看和管理已制定的训练方案</text>
+    </view>
+
     <view class="filter-bar">
       <view class="filter-item" :class="{ active: filterType === 'all' }" @click="changeFilter('all')">全部</view>
       <view class="filter-item" :class="{ active: filterType === 'active' }" @click="changeFilter('active')">活跃</view>
@@ -12,23 +17,27 @@
     </view>
 
     <view class="family-list">
-      <view class="family-card" v-for="family in families" :key="family.id" @click="viewFamily(family)">
-        <view class="family-header">
-          <text class="family-name">{{ family.familyName || '家庭' + family.familyId }}</text>
-          <text class="family-status">{{ family.status === 'active' ? '服务中' : '已暂停' }}</text>
-        </view>
-        <view class="family-info">
-          <text class="info-item">👶 {{ family.childrenCount || 0 }}位成员</text>
-          <text class="info-item">📍 {{ family.address || '未设置地址' }}</text>
-        </view>
-        <view class="family-tasks">
-          <text class="task-info">今日任务: {{ family.todayTaskCount || 0 }}/{{ family.totalTaskCount || 0 }}</text>
-        </view>
-        <view class="family-actions">
-          <button class="btn-action" size="mini" @click.stop="viewDetail(family)">查看详情</button>
-          <!-- 聊天功能已隐藏(临时): <button class="btn-action primary" size="mini" @click.stop="sendMessage(family)">发消息</button> -->
-        </view>
-      </view>
+<view class="family-card" v-for="family in families" :key="family.id" @click="viewFamily(family)">
+         <view class="family-header">
+           <text class="family-name">{{ family.familyName || '家庭' + family.familyId }}</text>
+           <text class="family-status">{{ family.status === 'active' ? '服务中' : '已暂停' }}</text>
+         </view>
+         <view class="family-info">
+           <text class="info-item">👶 {{ family.childrenCount || 0 }}位成员</text>
+           <text class="info-item">📍 {{ family.address || '未设置地址' }}</text>
+         </view>
+         <view class="family-tasks">
+           <text class="task-info">今日任务: {{ family.todayTaskCount || 0 }}/{{ family.totalTaskCount || 0 }}</text>
+         </view>
+         <view class="family-actions">
+           <button class="btn-action" size="mini" @click.stop="viewDetail(family)">查看详情</button>
+            <view class="family-card plan-card-entry" v-if="family.id !== null" @click="viewPlanList">
+             <view class="family-header">
+               <text class="family-name">方案管理</text>
+             </view>
+           </view>
+         </view>
+       </view>
       <view class="empty-tip" v-if="families.length === 0">
         <text>暂无服务家庭</text>
       </view>
@@ -78,6 +87,9 @@ export default {
     },
     goWorkbench() {
       uni.navigateTo({ url: '/pages/teacher/review-workbench' })
+    },
+    goPlanList() {
+      uni.navigateTo({ url: '/pages/teacher/plan-list' })
     }
   }
 }

+ 166 - 0
cfc-frontend/pages/teacher/plan-create.vue

@@ -0,0 +1,166 @@
+<template>
+  <view class="page">
+    <view class="card">
+      <view class="form-group">
+        <text class="label">方案标题 <text class="required">*</text></text>
+        <input
+          class="input"
+          v-model="title"
+          placeholder="请输入方案标题"
+        />
+      </view>
+
+      <view class="form-group">
+        <text class="label">方案描述</text>
+        <textarea
+          class="textarea"
+          v-model="description"
+          placeholder="请输入方案描述(可选)"
+          :maxlength="-1"
+        />
+      </view>
+    </view>
+
+    <view class="actions">
+      <button class="btn-primary" :disabled="submitting" @click="submitPlan">
+        {{ submitting ? '提交中...' : '保存方案' }}
+      </button>
+      <button class="btn-cancel" @click="goBack">取消</button>
+    </view>
+  </view>
+</template>
+
+<script>
+import { createTrainingPlan } from '@/utils/api.js'
+
+export default {
+  data() {
+    return {
+      title: '',
+      description: '',
+      submitting: false
+    }
+  },
+  methods: {
+    submitPlan() {
+      if (!this.title || !this.title.trim()) {
+        uni.showToast({ title: '请输入方案标题', icon: 'none' })
+        return
+      }
+
+      this.submitting = true
+
+      // 创建方案(memberId 留空,由后端关联当前用户)
+      createTrainingPlan(null, this.title.trim(), this.description.trim() || '')
+        .then(res => {
+          this.submitting = false
+          if (res && res.code === 200) {
+            uni.showToast({ title: '创建成功', icon: 'success' })
+            // 延迟跳转,让用户看到成功提示
+            setTimeout(() => {
+              uni.navigateBack()
+            }, 1000)
+          } else {
+            uni.showToast({ title: (res && res.message) || '创建失败', icon: 'none' })
+          }
+        })
+        .catch(err => {
+          this.submitting = false
+          console.error('创建方案失败', err)
+          uni.showToast({ title: '创建失败', icon: 'none' })
+        })
+    },
+    goBack() {
+      uni.navigateBack()
+    }
+  }
+}
+</script>
+
+<style scoped>
+.page {
+  padding: 24rpx;
+  background: #F5FAFE;
+  min-height: 100vh;
+}
+
+.card {
+  background: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+}
+
+.form-group {
+  margin-bottom: 30rpx;
+}
+
+.form-group:last-child {
+  margin-bottom: 0;
+}
+
+.label {
+  font-size: 28rpx;
+  color: #1F2D3D;
+  display: block;
+  margin-bottom: 12rpx;
+  font-weight: 500;
+}
+
+.required {
+  color: #F44336;
+}
+
+.input {
+  width: 100%;
+  height: 80rpx;
+  background: #F7F9FC;
+  border-radius: 12rpx;
+  padding: 0 20rpx;
+  font-size: 28rpx;
+  color: #1F2D3D;
+  box-sizing: border-box;
+}
+
+.textarea {
+  width: 100%;
+  min-height: 200rpx;
+  background: #F7F9FC;
+  border-radius: 12rpx;
+  padding: 20rpx;
+  font-size: 28rpx;
+  color: #1F2D3D;
+  box-sizing: border-box;
+}
+
+.actions {
+  display: flex;
+  flex-direction: column;
+  gap: 16rpx;
+}
+
+.btn-primary {
+  width: 100%;
+  background: #4A9BD7;
+  color: #fff;
+  font-size: 30rpx;
+  font-weight: 600;
+  padding: 24rpx 0;
+  border-radius: 12rpx;
+  border: none;
+}
+
+.btn-primary:disabled {
+  background: #ccc;
+}
+
+.btn-cancel {
+  width: 100%;
+  background: #F2F4F7;
+  color: #5A6478;
+  font-size: 30rpx;
+  padding: 24rpx 0;
+  border-radius: 12rpx;
+  border: none;
+}
+</style>

+ 231 - 0
cfc-frontend/pages/teacher/plan-list.vue

@@ -0,0 +1,231 @@
+<template>
+  <view class="page">
+    <view class="header">
+      <text class="title">我的方案</text>
+      <text class="subtitle">查看和管理已制定的训练方案</text>
+    </view>
+
+    <view class="action-bar">
+      <button class="btn-primary" @click="goCreatePlan">+ 新建方案</button>
+    </view>
+
+    <!-- 加载状态 -->
+    <view class="loading" v-if="loading">
+      <text class="loading-text">加载中...</text>
+    </view>
+
+    <!-- 空状态 -->
+    <view class="empty" v-else-if="plans.length === 0">
+      <text class="empty-icon">📋</text>
+      <text class="empty-title">暂无方案</text>
+      <text class="empty-desc">点击上方按钮创建第一个训练方案</text>
+    </view>
+
+    <!-- 方案列表 -->
+    <view class="plan-list" v-else>
+      <view
+        class="plan-card"
+        v-for="plan in plans"
+        :key="plan.id"
+        @click="goDetail(plan.id)"
+      >
+        <view class="card-top">
+          <text class="plan-title">{{ plan.title || '未命名方案' }}</text>
+          <view class="plan-status" :class="'status-' + (plan.status || 0)">
+            <text>{{ statusText(plan.status) }}</text>
+          </view>
+        </view>
+        <text class="plan-desc" v-if="plan.description">{{ plan.description }}</text>
+        <view class="card-meta">
+          <text class="meta-item">成员:{{ plan.memberName || '--' }}</text>
+          <text class="meta-item">创建时间:{{ formatTime(plan.createdAt) }}</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import { getTrainingPlanList } from '@/utils/api.js'
+
+export default {
+  data() {
+    return {
+      loading: false,
+      plans: []
+    }
+  },
+  onLoad() {
+    this.loadPlans()
+  },
+  onShow() {
+    this.loadPlans()
+  },
+  methods: {
+    loadPlans() {
+      this.loading = true
+      var self = this
+      getTrainingPlanList().then(function(res) {
+        self.loading = false
+        if (res && res.code === 200) {
+          self.plans = res.data || []
+        } else {
+          uni.showToast({ title: (res && res.message) || '加载失败', icon: 'none' })
+          self.plans = []
+        }
+      }).catch(function(err) {
+        self.loading = false
+        console.error('加载方案列表失败', err)
+        uni.showToast({ title: '加载失败', icon: 'none' })
+        self.plans = []
+      })
+    },
+    goDetail(planId) {
+      uni.navigateTo({ url: '/pages/teacher/plan-detail?planId=' + planId })
+    },
+    goCreatePlan() {
+      uni.navigateTo({ url: '/pages/teacher/plan-create' })
+    },
+    statusText(status) {
+      var map = { 0: '草稿', 1: '进行中', 2: '已完成', 3: '已取消' }
+      return map[status] || '未知'
+    },
+    formatTime(t) {
+      if (!t) return '-'
+      // 项目统一时间格式:取前19位并把 ISO 的 T 换成空格,避免 toLocaleString 的浏览器差异
+      return String(t).substring(0, 19).replace('T', ' ')
+    }
+  }
+}
+</script>
+
+<style scoped>
+.page {
+  min-height: 100vh;
+  background: #F5FAFE;
+  padding-bottom: 30rpx;
+}
+
+.header {
+  padding: 40rpx 30rpx 20rpx;
+}
+
+.title {
+  font-size: 36rpx;
+  font-weight: bold;
+  color: #1F2D3D;
+  display: block;
+}
+
+.subtitle {
+  font-size: 26rpx;
+  color: #8A94A6;
+  margin-top: 8rpx;
+  display: block;
+}
+
+.action-bar {
+  padding: 0 30rpx 20rpx;
+}
+
+.btn-primary {
+  width: 100%;
+  background: #4A9BD7;
+  color: #fff;
+  font-size: 30rpx;
+  font-weight: 600;
+  padding: 24rpx 0;
+  border-radius: 12rpx;
+  border: none;
+}
+
+.loading, .empty {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 100rpx 0;
+}
+
+.loading-text {
+  font-size: 28rpx;
+  color: #8A94A6;
+}
+
+.empty-icon {
+  font-size: 80rpx;
+}
+
+.empty-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  margin-top: 20rpx;
+}
+
+.empty-desc {
+  font-size: 26rpx;
+  color: #999;
+  margin-top: 10rpx;
+  text-align: center;
+}
+
+.plan-list {
+  padding: 0 30rpx;
+}
+
+.plan-card {
+  background: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+}
+
+.plan-card:active {
+  opacity: 0.8;
+}
+
+.card-top {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.plan-title {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #333;
+  flex: 1;
+}
+
+.plan-status {
+  font-size: 22rpx;
+  padding: 4rpx 16rpx;
+  border-radius: 20rpx;
+}
+
+.status-0 { background: #FFF3E0; color: #F97316; }
+.status-1 { background: #E8F5E9; color: #4CAF50; }
+.status-2 { background: #E3F2FD; color: #2196F3; }
+.status-3 { background: #F5F5F5; color: #999; }
+
+.plan-desc {
+  font-size: 26rpx;
+  color: #666;
+  margin-top: 12rpx;
+  display: block;
+  line-height: 1.5;
+}
+
+.card-meta {
+  display: flex;
+  flex-direction: column;
+  margin-top: 16rpx;
+  gap: 6rpx;
+}
+
+.meta-item {
+  font-size: 24rpx;
+  color: #bbb;
+}
+</style>

+ 5 - 1
cfc-frontend/pages/vendor/products/products.vue

@@ -146,7 +146,11 @@ export default {
       return map[status] || status
     },
     getImageUrl: function(path) {
-      return config.API_BASE_URL + path
+      if (!path || path === 'null' || path === 'undefined' || path === '/null') return ''
+      var s = String(path).trim()
+      if (!s || s === 'null' || s === '/null') return ''
+      if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) return s
+      return config.API_BASE_URL + (s.charAt(0) === '/' ? s : '/' + s)
     }
   }
 }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 12 - 38
docs/参考资料/530010234-侯.json


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 36 - 62
docs/参考资料/547982403.json


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 29 - 59
docs/参考资料/556168709-mi.json


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 13 - 80
docs/参考资料/儿童示例.json


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 355 - 27
docs/参考资料/朱评估报告.json


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 642 - 58
docs/参考资料/知识库/菌群营养知识库.json


+ 131 - 25
docs/参考资料/知识库/菌群营养知识库.md

@@ -28,22 +28,22 @@
 
 ## 一、食物营养含量库
 
-食材数:**226** 种。
+食材数:**332** 种。
 
 | 食材 | 分类 | 能量(kJ) | 蛋白(g) | 脂肪(g) | 碳水(g) | 淀粉(g) | 膳食纤维(g) | 胆固醇(mg) |
 | --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
-| 三文鱼 | 水产品 | 594.0 | 19.0 | 6.0 |  |  |  | 55.0 |
-| 冰淇淋 | 乳制品 | 690.0 | 1.0 | 3.0 | 32.0 |  |  | 8.0 |
+| 三文鱼 | 水产品 | 594.0 | 19.0 | 6.0 |  |  | 0 | 55.0 |
+| 冰淇淋 | 乳制品 | 690.0 | 1.0 | 3.0 | 32.0 |  | 0 | 8.0 |
 | 凤尾鱼 | 水产品 | 548.0 | 20.0 | 4.0 |  |  |  | 60.0 |
 | 利马豆 | 豆类及豆制品 | 1414.0 | 21.0 |  | 63.0 |  | 19.0 |  |
-| 南瓜 | 蔬菜 | 109.0 | 1.0 |  | 6.0 |  |  |  |
+| 南瓜 | 蔬菜 | 109.0 | 1.0 |  | 6.0 |  | 1.5 |  |
 | 卷心菜 | 蔬菜 | 103.0 | 1.0 |  | 5.0 |  | 2.0 |  |
-| 哈密瓜 | 水果 | 141.0 |  |  | 8.0 |  |  |  |
+| 哈密瓜 | 水果 | 141.0 |  |  | 8.0 |  | 0.2 |  |
 | 四季豆 | 蔬菜 | 131.0 | 1.0 |  | 6.0 |  | 2.0 |  |
 | 土豆 | 蔬菜 | 322.0 | 2.0 |  | 17.0 | 15.0 | 2.0 |  |
 | 土豆蔬菜汤 | 汤 | 126.0 | 1.0 | 1.0 | 3.0 |  |  | 1.0 |
 | 土豆面粉 | 蔬菜 | 1493.0 | 6.0 |  | 83.0 |  | 5.0 |  |
-| 墨鱼 | 水产品 | 331.0 | 16.0 |  |  |  |  | 112.0 |
+| 墨鱼 | 水产品 | 331.0 | 16.0 |  |  |  | 0 | 112.0 |
 | 大比目鱼 | 水产品 | 267.0 | 19.0 | 28.0 |  |  |  | 49.0 |
 | 大氏目鱼 | 水产品 | 382.0 | 18.0 | 1.0 |  |  |  | 49.0 |
 | 大白菜 | 蔬菜 | 55.0 | 1.0 |  | 2.0 |  | 1.0 |  |
@@ -53,8 +53,8 @@
 | 大豆面粉 | 豆类及豆制品 | 1816.0 | 37.0 | 20.0 | 31.0 |  | 9.0 |  |
 | 大麦 | 主食 | 1481.0 | 12.0 | 2.0 | 73.0 |  | 17.0 |  |
 | 奶油 | 乳制品 | 515.0 | 3.0 | 10.0 | 4.0 |  |  | 35.0 |
-| 奶酪 | 乳制品 | 1552.0 | 23.0 | 29.0 | 2.0 |  |  | 94.0 |
-| 嫩豆腐 | 豆类及豆制品 | 253.0 | 7.0 | 3.0 | 1.0 |  |  |  |
+| 奶酪 | 乳制品 | 1552.0 | 23.0 | 29.0 | 2.0 |  | 0 | 94.0 |
+| 嫩豆腐 | 豆类及豆制品 | 253.0 | 7.0 | 3.0 | 1.0 |  | 0.5 |  |
 | 小南瓜 | 蔬菜 | 69.0 | 1.0 |  | 3.0 |  | 1.0 |  |
 | 小米 | 主食 | 1582.0 | 11.0 | 4.0 | 72.0 |  | 8.0 |  |
 | 小萝卜 | 蔬菜 | 76.0 |  |  | 4.0 |  | 1.0 |  |
@@ -63,11 +63,11 @@
 | 小龙虾 | 水产品 | 322.0 | 15.0 |  |  |  |  | 114.0 |
 | 山核桃 | 干果 | 2889.0 | 9.0 | 71.0 | 13.0 |  | 9.0 |  |
 | 山核桃干 | 干果 | 2749.0 | 12.0 | 64.0 | 18.0 |  | 6.0 |  |
-| 山药 | 蔬菜 | 343.0 | 1.0 |  | 20.0 |  |  |  |
+| 山药 | 蔬菜 | 343.0 | 1.0 |  | 20.0 |  | 1.4 |  |
 | 开心果 | 干果 | 2392.0 | 21.0 | 45.0 | 28.0 | 1.0 | 10.0 |  |
 | 意大利面 | 主食 | 386.0 | 1.0 | 3.0 | 13.0 |  | 2.0 |  |
 | 扁豆 | 豆类及豆制品 | 1473.0 | 24.0 | 1.0 | 63.0 | 49.0 | 10.0 |  |
-| 扇贝 | 水产品 | 289.0 | 12.0 |  | 3.0 | 2.0 |  | 24.0 |
+| 扇贝 | 水产品 | 289.0 | 12.0 |  | 3.0 | 2.0 | 0 | 24.0 |
 | 无花果 | 水果 | 310.0 |  |  | 19.0 |  | 2.0 |  |
 | 木薯 | 蔬菜 | 667.0 | 1.0 |  | 38.0 |  | 1.0 |  |
 | 李子 | 水果 | 192.0 |  |  | 11.0 |  | 1.0 |  |
@@ -118,13 +118,13 @@
 | 牛肉肥 | 肉类 | 2845.0 | 10.0 | 70.0 |  |  |  | 95.0 |
 | 牛蒡根 | 蔬菜 | 302.0 | 1.0 |  | 17.0 |  | 3.0 |  |
 | 牛蛙 | 肉类 | 305.0 | 16.0 |  |  |  |  | 50.0 |
-| 牡蛎 | 水产品 | 339.0 | 9.0 | 2.0 | 4.0 |  |  | 50.0 |
+| 牡蛎 | 水产品 | 339.0 | 9.0 | 2.0 | 4.0 |  | 0 | 50.0 |
 | 猕猴桃 | 水果 | 255.0 | 1.0 |  | 14.0 |  | 3.0 |  |
 | 猪培根 | 肉类 | 1744.0 | 12.0 | 39.0 | 1.0 |  |  | 66.0 |
 | 猪头肉 | 肉类 | 658.0 | 13.0 | 10.0 |  |  |  | 69.0 |
 | 猪瘦肉 | 肉类 | 562.0 | 21.0 | 4.0 |  |  |  | 64.0 |
 | 猪耳朵 | 肉类 | 695.0 | 15.0 | 10.0 |  |  |  | 90.0 |
-| 猪肝 | 肉类 | 690.0 | 26.0 | 4.0 | 3.0 |  |  | 355.0 |
+| 猪肝 | 肉类 | 690.0 | 26.0 | 4.0 | 3.0 |  | 0 | 355.0 |
 | 猪脑 | 肉类 | 577.0 | 12.0 | 9.0 |  |  |  | 2552.0 |
 | 猪蹄 | 肉类 | 889.0 | 23.0 | 12.0 |  |  |  | 88.0 |
 | 玉米粒 | 主食 | 298.0 | 1.0 |  | 14.0 | 14.0 |  |  |
@@ -154,7 +154,7 @@
 | 素食蔬菜汤 | 汤 | 119.0 |  |  | 4.0 |  |  |  |
 | 红心萝卜 | 蔬菜 | 132.0 | 1.0 |  | 7.0 |  | 3.0 |  |
 | 红苹果 | 水果 | 247.0 |  |  | 14.0 |  | 2.0 |  |
-| 红豆 | 蔬菜 | 121.0 | 4.0 |  | 4.0 |  |  |  |
+| 红豆 | 蔬菜 | 121.0 | 4.0 |  | 4.0 |  | 7.7 |  |
 | 纳豆 | 豆类及豆制品 | 883.0 | 19.0 | 11.0 | 12.0 |  | 5.0 |  |
 | 绿豆 | 蔬菜 | 126.0 | 3.0 |  | 5.0 |  | 1.0 |  |
 | 羽扇豆 | 豆类及豆制品 | 1554.0 | 36.0 | 9.0 | 40.0 |  | 18.0 |  |
@@ -178,7 +178,7 @@
 | 花生酱 | 豆类及豆制品 | 2464.0 | 24.0 | 49.0 | 21.0 | 4.0 | 8.0 |  |
 | 芹菜 | 蔬菜 | 67.0 |  |  | 2.0 |  | 1.0 |  |
 | 苋菜叶 | 蔬菜 | 97.0 | 2.0 |  | 4.0 |  |  |  |
-| 苦瓜 | 蔬菜 | 126.0 | 5.0 |  | 3.0 |  |  |  |
+| 苦瓜 | 蔬菜 | 126.0 | 5.0 |  | 3.0 |  | 1.4 |  |
 | 苹果 | 水果 | 218.0 |  |  | 13.0 |  | 2.0 |  |
 | 苹果汁 | 水果 | 191.0 |  |  | 11.0 |  |  |  |
 | 茄子 | 蔬菜 | 104.0 |  |  | 5.0 |  | 3.0 |  |
@@ -191,7 +191,7 @@
 | 菠菜 | 蔬菜 | 97.0 | 2.0 |  | 3.0 |  | 2.0 |  |
 | 菠萝 | 水果 | 209.0 |  |  | 13.0 |  | 1.0 |  |
 | 菠萝蜜 | 水果 | 397.0 | 1.0 |  | 23.0 | 1.0 | 1.0 |  |
-| 葡萄 | 水果 | 280.0 |  |  | 17.0 |  |  |  |
+| 葡萄 | 水果 | 280.0 |  |  | 17.0 |  | 0.4 |  |
 | 葡萄干 | 水果 | 264.0 | 1.0 |  | 15.0 |  |  |  |
 | 葡萄干浆即食谷物 | 主食 | 1354.0 | 7.0 | 1.0 | 78.0 |  | 13.0 |  |
 | 葡萄柚 | 水果 | 134.0 |  |  | 8.0 |  | 1.0 |  |
@@ -201,12 +201,12 @@
 | 蕨类 | 蔬菜 | 143.0 | 4.0 |  | 5.0 |  |  |  |
 | 藜 | 蔬菜 | 180.0 | 4.0 |  | 7.0 |  | 4.0 |  |
 | 蘑菇 | 蔬菜 | 141.0 | 2.0 |  | 6.0 |  | 2.0 |  |
-| 虾 | 水产品 | 297.0 | 13.0 | 1.0 |  |  |  | 126.0 |
+| 虾 | 水产品 | 297.0 | 13.0 | 1.0 |  |  | 0 | 126.0 |
 | 蚕豆 | 豆类及豆制品 | 1425.0 | 26.0 | 1.0 | 58.0 |  | 25.0 |  |
 | 蛤蜊 | 水产品 | 360.0 | 14.0 |  | 3.0 | 1.0 |  | 30.0 |
-| 蟹 | 水产品 | 364.0 | 18.0 | 1.0 |  |  |  | 78.0 |
+| 蟹 | 水产品 | 364.0 | 18.0 | 1.0 |  |  | 0 | 78.0 |
 | 西兰花 | 蔬菜 | 141.0 | 2.0 |  | 6.0 |  | 2.0 |  |
-| 西瓜 | 水果 | 127.0 |  |  | 7.0 |  |  |  |
+| 西瓜 | 水果 | 127.0 |  |  | 7.0 |  | 0.4 |  |
 | 西红柿 | 蔬菜 | 74.0 |  |  | 3.0 |  | 1.0 |  |
 | 覆盆子 | 水果 | 220.0 | 1.0 |  | 11.0 |  | 6.0 |  |
 | 豆浆 | 豆类及豆制品 | 226.0 | 3.0 | 1.0 | 6.0 |  |  |  |
@@ -223,8 +223,8 @@
 | 香菇 | 蔬菜 | 160.0 | 1.0 |  | 6.0 |  | 3.0 |  |
 | 香蕉 | 水果 | 371.0 | 1.0 |  | 22.0 | 5.0 | 2.0 |  |
 | 鱼子酱 | 水产品 | 1105.0 | 24.0 | 17.0 | 4.0 |  |  | 588.0 |
-| 鱿鱼 | 水产品 | 385.0 | 15.0 | 1.0 | 3.0 |  |  | 233.0 |
-| 鲈鱼 | 水产品 | 381.0 | 19.0 |  |  |  |  | 90.0 |
+| 鱿鱼 | 水产品 | 385.0 | 15.0 | 1.0 | 3.0 |  | 0 | 233.0 |
+| 鲈鱼 | 水产品 | 381.0 | 19.0 |  |  |  | 0 | 90.0 |
 | 鲍鱼 | 水产品 | 439.0 | 17.0 |  | 6.0 |  |  | 85.0 |
 | 鲟鱼 | 水产品 | 439.0 | 16.0 | 4.0 |  |  |  | 60.0 |
 | 鲤鱼 | 水产品 | 531.0 | 17.0 | 5.0 |  |  |  | 66.0 |
@@ -234,30 +234,136 @@
 | 鲷鱼 | 水产品 | 418.0 | 20.0 | 1.0 |  |  |  | 37.0 |
 | 鲽鱼 | 水产品 | 294.0 | 12.0 | 1.0 |  |  |  | 45.0 |
 | 鳄梨 | 水果 | 670.0 | 2.0 | 14.0 | 8.0 |  | 6.0 |  |
-| 鳕鱼 | 水产品 | 364.0 | 18.0 |  |  |  |  | 41.0 |
+| 鳕鱼 | 水产品 | 364.0 | 18.0 |  |  |  | 0 | 41.0 |
 | 鳗鱼 | 水产品 | 770.0 | 18.0 | 11.0 |  |  |  | 126.0 |
 | 鳟鱼 | 水产品 | 619.0 | 20.0 | 6.0 |  |  |  | 58.0 |
 | 鸡心 | 肉类 | 640.0 | 15.0 | 9.0 |  |  |  | 136.0 |
 | 鸡汤 | 肉类 | 26.0 |  |  |  |  |  | 2.0 |
 | 鸡米花 | 快餐 | 1469.0 | 17.0 | 21.0 | 21.0 | 18.0 | 1.0 | 40.0 |
-| 鸡肉 | 肉类 | 604.0 | 28.0 | 3.0 |  |  |  | 86.0 |
+| 鸡肉 | 肉类 | 604.0 | 28.0 | 3.0 |  |  | 0 | 86.0 |
 | 鸡肝 | 肉类 | 496.0 | 16.0 | 4.0 |  |  |  | 345.0 |
-| 鸡蛋 | 蛋类 | 599.0 | 12.0 | 9.0 |  |  |  | 372.0 |
+| 鸡蛋 | 蛋类 | 599.0 | 12.0 | 9.0 |  |  | 0 | 372.0 |
 | 鸡蛋白 | 蛋类 | 216.0 | 10.0 |  |  |  |  |  |
 | 鸡蛋面包 | 主食 | 1201.0 | 9.0 | 6.0 | 47.0 |  | 2.0 | 51.0 |
 | 鸡蛋黄 | 蛋类 | 1346.0 | 15.0 | 26.0 | 3.0 |  |  | 1085.0 |
 | 鹅肝 | 肉类 | 556.0 | 16.0 | 4.0 | 6.0 |  |  | 515.0 |
 | 鹌鹑 | 肉类 | 803.0 | 19.0 | 12.0 |  |  |  | 76.0 |
-| 鹌鹑蛋 | 蛋类 | 663.0 | 13.0 | 11.0 |  |  |  | 844.0 |
+| 鹌鹑蛋 | 蛋类 | 663.0 | 13.0 | 11.0 |  |  | 0 | 844.0 |
 | 鹰嘴豆 | 豆类及豆制品 | 1581.0 | 20.0 | 6.0 | 62.0 |  | 12.0 |  |
 | 黄尾 | 水产品 | 611.0 | 23.0 | 5.0 |  |  |  | 55.0 |
 | 黄油 | 乳制品 | 2999.0 |  | 81.0 |  |  |  | 215.0 |
-| 黄瓜 | 蔬菜 | 65.0 |  |  | 3.0 |  |  |  |
+| 黄瓜 | 蔬菜 | 65.0 |  |  | 3.0 |  | 0.5 |  |
 | 黄豆 | 豆类及豆制品 | 1443.0 | 22.0 | 2.0 | 60.0 |  | 25.0 |  |
 | 黑莓 | 水果 | 181.0 | 1.0 |  | 9.0 |  | 5.0 |  |
 | 黑麦面包 | 主食 | 1188.0 | 9.0 | 3.0 | 53.0 |  | 6.0 |  |
 | 龙眼 | 水果 | 251.0 | 1.0 |  | 15.0 |  | 1.0 |  |
 | 龙虾 | 水产品 | 324.0 | 16.0 |  |  |  |  | 127.0 |
+| 白米饭 | 主食谷物 |  |  |  |  |  | — |  |
+| 糙米饭 | 主食谷物 |  |  |  |  |  | 3.5 |  |
+| 胚芽米饭 | 主食谷物 |  |  |  |  |  | 2.0 |  |
+| 小米粥 | 主食谷物 |  |  |  |  |  | 1.6 |  |
+| 燕麦饭 | 主食谷物 |  |  |  |  |  | 6.0 |  |
+| 即食燕麦片 | 主食谷物 |  |  |  |  |  | 6.0 |  |
+| 钢切燕麦 | 主食谷物 |  |  |  |  |  | 6.0 |  |
+| 藜麦 | 主食谷物 |  |  |  |  |  | 7.0 |  |
+| 荞麦 | 主食谷物 |  |  |  |  |  | 6.5 |  |
+| 荞麦面 | 主食谷物 |  |  |  |  |  | 4.0 |  |
+| 玉米面粥 | 主食谷物 |  |  |  |  |  | 2.0 |  |
+| 黑米(饭) | 主食谷物 |  |  |  |  |  | 3.9 |  |
+| 薏米 | 主食谷物 |  |  |  |  |  | 2.0 |  |
+| 高粱米 | 主食谷物 |  |  |  |  |  | 4.3 |  |
+| 青稞 | 主食谷物 |  |  |  |  |  | 9.0 |  |
+| 莜面 | 主食谷物 |  |  |  |  |  | 8.0 |  |
+| 全麦面包 | 主食谷物 |  |  |  |  |  | 6.0 |  |
+| 白面包 | 主食谷物 |  |  |  |  |  | 2.7 |  |
+| 白馒头 | 主食谷物 |  |  |  |  |  | 1.5 |  |
+| 挂面(煮) | 主食谷物 |  |  |  |  |  | 2.0 |  |
+| 米粉/米线 | 主食谷物 |  |  |  |  |  | 1.0 |  |
+| 绿豆粉丝 | 主食谷物 |  |  |  |  |  | 1.1 |  |
+| 红薯(蒸) | 主食谷物 |  |  |  |  |  | 3.0 |  |
+| 烤红薯 | 主食谷物 |  |  |  |  |  | 3.0 |  |
+| 紫薯(蒸) | 主食谷物 |  |  |  |  |  | 2.5 |  |
+| 土豆泥 | 主食谷物 |  |  |  |  |  | 1.8 |  |
+| 莲藕(煮) | 主食谷物 |  |  |  |  |  | 2.2 |  |
+| 冷却米饭(隔夜) | 主食谷物 |  |  |  |  |  | 1.0 |  |
+| 青香蕉 | 主食谷物 |  |  |  |  |  | 2.6 |  |
+| 黑豆(煮) | 豆类及豆制品 |  |  |  |  |  | 10.2 |  |
+| 芸豆(煮) | 豆类及豆制品 |  |  |  |  |  | 9.8 |  |
+| 北豆腐(老豆腐) | 豆类及豆制品 |  |  |  |  |  | 0.8 |  |
+| 无糖豆浆 | 豆类及豆制品 |  |  |  |  |  | 1.1 |  |
+| 豆干 | 豆类及豆制品 |  |  |  |  |  | 1.6 |  |
+| 天贝 | 豆类及豆制品 |  |  |  |  |  | 8.0 |  |
+| 毛豆(煮) | 豆类及豆制品 |  |  |  |  |  | 4.0 |  |
+| 油菜 | 蔬菜 |  |  |  |  |  | 1.1 |  |
+| 油麦菜 | 蔬菜 |  |  |  |  |  | 0.6 |  |
+| 空心菜 | 蔬菜 |  |  |  |  |  | 1.4 |  |
+| 苋菜 | 蔬菜 |  |  |  |  |  | 2.2 |  |
+| 芥蓝 | 蔬菜 |  |  |  |  |  | 1.6 |  |
+| 菜心 | 蔬菜 |  |  |  |  |  | 1.7 |  |
+| 茼蒿 | 蔬菜 |  |  |  |  |  | 1.2 |  |
+| 菜花 | 蔬菜 |  |  |  |  |  | 2.0 |  |
+| 番茄(鲜) | 蔬菜 |  |  |  |  |  | 0.5 |  |
+| 圣女果 | 蔬菜 |  |  |  |  |  | 1.8 |  |
+| 青椒/甜椒 | 蔬菜 |  |  |  |  |  | 1.4 |  |
+| 菊芋(洋姜) | 蔬菜 |  |  |  |  |  | 4.3 |  |
+| 冬瓜 | 蔬菜 |  |  |  |  |  | 0.7 |  |
+| 丝瓜 | 蔬菜 |  |  |  |  |  | 0.6 |  |
+| 茭白 | 蔬菜 |  |  |  |  |  | 1.9 |  |
+| 莴笋 | 蔬菜 |  |  |  |  |  | 0.6 |  |
+| 蒜苔 | 蔬菜 |  |  |  |  |  | 2.5 |  |
+| 平菇 | 蔬菜 |  |  |  |  |  | 2.3 |  |
+| 金针菇 | 蔬菜 |  |  |  |  |  | 2.7 |  |
+| 木耳(水发) | 蔬菜 |  |  |  |  |  | 2.6 |  |
+| 海带 | 蔬菜 |  |  |  |  |  | 3.0 |  |
+| 紫菜 | 蔬菜 |  |  |  |  |  | 21.6 |  |
+| 南瓜尖/红薯叶 | 蔬菜 |  |  |  |  |  | 2.0 |  |
+| 树莓 | 水果 |  |  |  |  |  | 6.5 |  |
+| 橙子 | 水果 |  |  |  |  |  | 2.4 |  |
+| 柚子 | 水果 |  |  |  |  |  | 0.4 |  |
+| 甜瓜/香瓜 | 水果 |  |  |  |  |  | 0.4 |  |
+| 木瓜 | 水果 |  |  |  |  |  | 0.8 |  |
+| 火龙果 | 水果 |  |  |  |  |  | 1.6 |  |
+| 山竹 | 水果 |  |  |  |  |  | 1.5 |  |
+| 椰子(椰肉) | 水果 |  |  |  |  |  | 4.7 |  |
+| 牛油果 | 水果 |  |  |  |  |  | 6.7 |  |
+| 番石榴(芭乐) | 水果 |  |  |  |  |  | 5.9 |  |
+| 干枣/红枣 | 水果 |  |  |  |  |  | 6.2 |  |
+| 枇杷 | 水果 |  |  |  |  |  | 0.8 |  |
+| 杨梅 | 水果 |  |  |  |  |  | 1.0 |  |
+| 百香果 | 水果 |  |  |  |  |  | 10.4 |  |
+| 猪肉(瘦) | 畜禽肉蛋 |  |  |  |  |  | 0 |  |
+| 牛肉(瘦) | 畜禽肉蛋 |  |  |  |  |  | 0 |  |
+| 羊肉(瘦) | 畜禽肉蛋 |  |  |  |  |  | 0 |  |
+| 鸭肉 | 畜禽肉蛋 |  |  |  |  |  | 0 |  |
+| 鸭蛋 | 畜禽肉蛋 |  |  |  |  |  | 0 |  |
+| 牛肉干(原味) | 畜禽肉蛋 |  |  |  |  |  | 0 |  |
+| 带鱼 | 水产品 |  |  |  |  |  | 0 |  |
+| 黄花鱼 | 水产品 |  |  |  |  |  | 0 |  |
+| 鲫鱼 | 水产品 |  |  |  |  |  | 0 |  |
+| 海带/裙带菜 | 水产品 |  |  |  |  |  | 3.0 |  |
+| 纯牛奶(全脂) | 乳制品及发酵 |  |  |  |  |  | 0 |  |
+| 无糖酸奶 | 乳制品及发酵 |  |  |  |  |  | 0 |  |
+| 调味/风味酸奶 | 乳制品及发酵 |  |  |  |  |  | 0 |  |
+| 开菲尔(发酵乳) | 乳制品及发酵 |  |  |  |  |  | 0 |  |
+| 奶粉(婴幼儿配方) | 乳制品及发酵 |  |  |  |  |  | 0 |  |
+| 无糖泡菜 | 乳制品及发酵 |  |  |  |  |  | 2.0 |  |
+| 味噌(汤) | 乳制品及发酵 |  |  |  |  |  | 2.5 |  |
+| 豆豉 | 乳制品及发酵 |  |  |  |  |  | 5.0 |  |
+| 康普茶(无糖) | 乳制品及发酵 |  |  |  |  |  | 0 |  |
+| 巴旦木(美国大杏仁) | 坚果种子 |  |  |  |  |  | 12.0 |  |
+| 南瓜子 | 坚果种子 |  |  |  |  |  | 6.0 |  |
+| 奇亚籽 | 坚果种子 |  |  |  |  |  | 34.0 |  |
+| 亚麻籽(熟) | 坚果种子 |  |  |  |  |  | 27.0 |  |
+| 板栗(鲜) | 坚果种子 |  |  |  |  |  | 1.7 |  |
+| 无糖绿茶 | 饮品零食调味 |  |  |  |  |  | 0 |  |
+| 黑咖啡(无糖) | 饮品零食调味 |  |  |  |  |  | 0 |  |
+| 纯可可粉/黑巧(70%+) | 饮品零食调味 |  |  |  |  |  | 11.0 |  |
+| 蜂蜜 | 饮品零食调味 |  |  |  |  |  | 0 |  |
+| 可乐等含糖汽水 | 饮品零食调味 |  |  |  |  |  | 0 |  |
+| 纯果汁(橙汁) | 饮品零食调味 |  |  |  |  |  | 0.2 |  |
+| 白粥 | 饮品零食调味 |  |  |  |  |  | 0.3 |  |
+| 藕粉 | 饮品零食调味 |  |  |  |  |  | 0.1 |  |
+| 麦芽糖/饴糖 | 饮品零食调味 |  |  |  |  |  | 0 |  |
 
 ## 二、菌-疾病关联知识库
 

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä