Selaa lähdekoodia

首页接入病例分享/用嗓科普真实接口,恢复医生角色可见性判断

- 列表/详情改为真实接口 method=article(action=list/get_info_by_id),按后台确认的字段名映射(hospital_name/doctor_name/pic_url/create_time),移除占位 mock 数据
- 列表分页改为固定高度 scroll-view + 触底加载,避免首页因内容增多无限变长
- 病例分析分享恢复按 is_doctor 角色判断显隐,移除临时演示旁路
- "我的"页暂时下线耳鸣检测报告/听力功能检测报告两个入口

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
wzz 1 kuukausi sitten
vanhempi
commit
b96e14640a
3 muutettua tiedostoa jossa 100 lisäystä ja 60 poistoa
  1. 20 4
      src/pages/index/articleDetail.vue
  2. 79 44
      src/pages/index/index.vue
  3. 1 12
      src/pages/selfCenter/index.vue

+ 20 - 4
src/pages/index/articleDetail.vue

@@ -33,13 +33,29 @@ export default {
   },
   methods: {
     async getDetail() {
-      // TODO: 详情接口待后台确认,当前 method/action/字段均为占位,content 期望为富文本HTML字符串
-      const res = await request('content', 'detail', { id: this.id, category: this.category })
+      const res = await request('article', 'get_info_by_id', { id: this.id })
       if (res.code === 200) {
-        this.article = res.data
-        uni.setNavigationBarTitle({ title: res.data.title || '详情' })
+        const item = res.data || {}
+        this.article = {
+          title: item.title,
+          hospital: item.hospital_name,
+          doctor: item.doctor_name,
+          date: this.formatDate(item.create_time),
+          content: item.content,
+        }
+        uni.setNavigationBarTitle({ title: item.title || '详情' })
+      } else {
+        console.error('getDetail failed', this.id, res)
       }
     },
+    formatDate(ts) {
+      if (!ts) return ''
+      const d = new Date(Number(ts) * 1000)
+      const y = d.getFullYear()
+      const m = String(d.getMonth() + 1).padStart(2, '0')
+      const day = String(d.getDate()).padStart(2, '0')
+      return `${y}-${m}-${day}`
+    },
   },
 }
 </script>

+ 79 - 44
src/pages/index/index.vue

@@ -32,28 +32,34 @@
       <view class="notice-title-box" style="margin: 0 auto;">
         <view class="notice-font margin-right-30">病例分析分享</view>
       </view>
-      <view class="article-item" v-for="item in caseShareList" :key="item.id" @click="goArticleDetail(item, 'case_share')">
-        <view class="article-item-text">
-          <view class="article-item-title">{{ item.title }}</view>
-          <view class="article-item-sub">{{ item.hospital }}  {{ item.doctor }}</view>
-          <view class="article-item-date">{{ item.date }}</view>
+      <scroll-view scroll-y class="article-scroll" @scrolltolower="loadMoreCaseShare">
+        <view class="article-item" v-for="item in caseShareList" :key="item.id" @click="goArticleDetail(item, 'case_share')">
+          <view class="article-item-text">
+            <view class="article-item-title">{{ item.title }}</view>
+            <view class="article-item-sub">{{ item.hospital }}  {{ item.doctor }}</view>
+            <view class="article-item-date">{{ item.date }}</view>
+          </view>
+          <image class="article-item-img" :src="item.cover" mode="aspectFill"></image>
         </view>
-        <image class="article-item-img" :src="item.cover" mode="aspectFill"></image>
-      </view>
+        <view class="scroll-end-tip" v-if="!caseShareHasMore && caseShareList.length">没有更多了</view>
+      </scroll-view>
     </view>
 
     <view class="notice-box" style="width:90%;margin-top: 30rpx;">
       <view class="notice-title-box" style="margin: 0 auto;">
         <view class="notice-font margin-right-30">用嗓科普</view>
       </view>
-      <view class="article-item" v-for="item in voiceScienceList" :key="item.id" @click="goArticleDetail(item, 'voice_science')">
-        <view class="article-item-text">
-          <view class="article-item-title">{{ item.title }}</view>
-          <view class="article-item-sub">{{ item.hospital }}  {{ item.doctor }}</view>
-          <view class="article-item-date">{{ item.date }}</view>
+      <scroll-view scroll-y class="article-scroll" @scrolltolower="loadMoreVoiceScience">
+        <view class="article-item" v-for="item in voiceScienceList" :key="item.id" @click="goArticleDetail(item, 'voice_science')">
+          <view class="article-item-text">
+            <view class="article-item-title">{{ item.title }}</view>
+            <view class="article-item-sub">{{ item.hospital }}  {{ item.doctor }}</view>
+            <view class="article-item-date">{{ item.date }}</view>
+          </view>
+          <image class="article-item-img" :src="item.cover" mode="aspectFill"></image>
         </view>
-        <image class="article-item-img" :src="item.cover" mode="aspectFill"></image>
-      </view>
+        <view class="scroll-end-tip" v-if="!voiceScienceHasMore && voiceScienceList.length">没有更多了</view>
+      </scroll-view>
     </view>
   </view>
 </template>
@@ -77,21 +83,17 @@ export default {
     return {
       navList: [],
       totalFinish: 0,
-      // TODO: 病例分析分享是否可见依赖用户角色(普通用户不可见),当前先按 is_doctor 判断,
-      // 具体角色字段以后台接口(info_by_openid)返回的 is_doctor 为准,如角色体系有调整需要同步修改这里
-      // FIXME-DEMO: 临时改为游客也可见,方便预览"病例分析分享"新需求样式,联调时记得改回 is_doctor 判断
-      showCaseShare: true,
-      // FIXME-DEMO: 以下为临时 mock 数据,仅用于预览列表样式;接口(content/list)联调后应删除,
-      // 改为 getArticleList 请求失败/为空时的正常空状态
-      caseShareList: [
-        { id: 'mock-1', title: '一例慢性咽喉反流合并声嘶病例分析', hospital: '西安中心医院', doctor: '张医生', date: '2026-07-20', cover: '/static/logo.png' },
-        { id: 'mock-2', title: '教师职业性嗓音疲劳典型病例', hospital: '西安中心医院', doctor: '李医生', date: '2026-07-15', cover: '/static/logo.png' },
-      ],
-      voiceScienceList: [
-        { id: 'mock-3', title: '什么是嗓音疲劳?如何自测?', hospital: '', doctor: '', date: '2026-07-10', cover: '/static/logo.png' },
-        { id: 'mock-4', title: '教师、主播等用嗓职业如何护嗓', hospital: '', doctor: '', date: '2026-07-05', cover: '/static/logo.png' },
-        { id: 'mock-5', title: 'VHI量表在嗓音评估中的应用', hospital: '', doctor: '', date: '2026-06-28', cover: '/static/logo.png' },
-      ],
+      // 病例分析分享是否可见依赖用户角色(普通用户不可见),判断依据是 info_by_openid 接口返回的 is_doctor 字段
+      showCaseShare: false,
+      caseShareList: [],
+      caseSharePage: 1,
+      caseShareHasMore: false,
+      caseShareLoading: false,
+      voiceScienceList: [],
+      voiceSciencePage: 1,
+      voiceScienceHasMore: false,
+      voiceScienceLoading: false,
+      articlePageSize: 10,
     };
   },
   async onShow() {
@@ -129,31 +131,55 @@ export default {
     },
     async getUserRole() {
       // 普通用户看不到"病例分析分享",判断依据沿用1.0"我的"模块里的 is_doctor 字段
-      // FIXME-DEMO: 临时不根据角色隐藏,联调时把下面这行的注释去掉,删掉上面 data() 里 showCaseShare:true 的临时改动
       const res = await request('user', 'info_by_openid', { openId: currentOpenId() })
       if (res.code === 200) {
-        // this.showCaseShare = Number(res.data.is_doctor) === 1
+        this.showCaseShare = Number(res.data.is_doctor) === 1
       }
     },
-    async getArticleList(category) {
-      // TODO: 病例分析分享/用嗓科普 列表接口待后台确认,当前 method/action/字段均为占位
-      const res = await request('content', 'list', { category })
+    async getArticleList(category, loadMore = false) {
+      const categoryId = category === 'case_share' ? 1 : 2
+      const pageKey = category === 'case_share' ? 'caseSharePage' : 'voiceSciencePage'
+      const hasMoreKey = category === 'case_share' ? 'caseShareHasMore' : 'voiceScienceHasMore'
+      const listKey = category === 'case_share' ? 'caseShareList' : 'voiceScienceList'
+      const loadingKey = category === 'case_share' ? 'caseShareLoading' : 'voiceScienceLoading'
+      if (this[loadingKey]) return
+      if (loadMore && !this[hasMoreKey]) return
+      this[loadingKey] = true
+      const page = loadMore ? this[pageKey] + 1 : 1
+      const res = await request('article', 'list', { category_id: categoryId, page, page_size: this.articlePageSize })
+      this[loadingKey] = false
       if (res.code === 200) {
-        const list = (res.data || []).map(item => ({
+        const rawList = (res.data && res.data.list) || []
+        const list = rawList.map(item => ({
           id: item.id,
           title: item.title,
-          hospital: item.hospital,
-          doctor: item.doctor,
-          date: item.date,
-          cover: item.cover,
+          hospital: item.hospital_name,
+          doctor: item.doctor_name,
+          date: this.formatDate(item.create_time),
+          cover: item.pic_url ? (getApp().globalData.shareUrl + item.pic_url) : '',
         }))
-        // FIXME-DEMO: 只有真的拿到数据才覆盖 mock 列表,避免占位接口返回空值把演示数据冲掉
-        if (list.length) {
-          if (category === 'case_share') this.caseShareList = list
-          else this.voiceScienceList = list
-        }
+        this[listKey] = loadMore ? this[listKey].concat(list) : list
+        this[pageKey] = page
+        const pageCount = Number(res.data && res.data.page_count) || 1
+        this[hasMoreKey] = page < pageCount
+      } else {
+        console.error('getArticleList failed', category, res)
       }
     },
+    formatDate(ts) {
+      if (!ts) return ''
+      const d = new Date(Number(ts) * 1000)
+      const y = d.getFullYear()
+      const m = String(d.getMonth() + 1).padStart(2, '0')
+      const day = String(d.getDate()).padStart(2, '0')
+      return `${y}-${m}-${day}`
+    },
+    loadMoreCaseShare() {
+      this.getArticleList('case_share', true)
+    },
+    loadMoreVoiceScience() {
+      this.getArticleList('voice_science', true)
+    },
     goArticleDetail(item, category) {
       uni.navigateTo({
         url: `/pages/index/articleDetail?id=${item.id}&category=${category}`
@@ -286,4 +312,13 @@ export default {
   border-radius: 8rpx;
   flex-shrink: 0;
 }
+.article-scroll {
+  max-height: 700rpx;
+}
+.scroll-end-tip {
+  text-align: center;
+  font-size: 24rpx;
+  color: #a7adba;
+  padding: 16rpx 0;
+}
 </style>

+ 1 - 12
src/pages/selfCenter/index.vue

@@ -38,6 +38,7 @@ export default {
       userNickName: "",
       isWith:0,
       is_doctor: 0,
+      // 暂时下线:耳鸣检测报告(id:2)/听力功能检测报告(id:3),需要时把这两项加回来即可
       list: [
         {
           icoin: "/static/selfCenter/self-1.png",
@@ -46,18 +47,6 @@ export default {
           id: 1
         },
         {
-          icoin: "/static/selfCenter/self-1.png",
-          name: "耳鸣检测报告" ,
-          url: "/pages/selfCenter/imageDetection?type=tinnitus",
-          id: 2
-        },
-        {
-          icoin: "/static/selfCenter/self-1.png",
-          name: "听力功能检测报告" ,
-          url: "/pages/selfCenter/imageDetection?type=hearing",
-          id: 3
-        },
-        {
           icoin: "/static/selfCenter/self-3.png",
           name: "关于我们" ,
           url: "/pages/selfCenter/aboutUs",