Quellcode durchsuchen

1.优化文章展示。2.处理分类id逻辑

wzz vor 2 Wochen
Ursprung
Commit
56a3f7ac62

+ 69 - 18
src/pages/index/articleDetail.vue

@@ -1,40 +1,91 @@
-<!-- 病例分析分享 / 用嗓科普 详情页,和"关于我们"一样用 web-view 整页加载后台的静态 HTML -->
+<!-- 病例分析分享 / 用嗓科普 详情页:标题/作者/日期用列表页带过来的数据自己渲染,
+     正文自己把后台的静态 HTML 当纯文本抓下来,交给 mp-html 渲染(不再用 web-view 整页加载远程页面) -->
 <template>
-  <view class="content">
-    <view class="artical">
-      <web-view :src="urlParse"></web-view>
-    </view>
+  <view class="detail-page">
+    <view class="detail-title">{{ article.title }}</view>
+    <view class="detail-sub">{{ article.hospital }}  {{ article.doctor }}  {{ article.date }}</view>
+    <view class="detail-divider"></view>
+    <mp-html :content="article.content" :tag-style="tagStyle" selectable />
   </view>
 </template>
 
 <script>
+import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html.vue'
+
 export default {
+  components: { mpHtml },
   data() {
     return {
       id: '',
       category: '',
-      urlParse: '',
+      contentUrl: '',
+      article: {
+        title: '',
+        hospital: '',
+        doctor: '',
+        date: '',
+        content: '',
+      },
+      // 控制正文默认字号/行距,让阅读体验更接近文章而不是大段大字
+      tagStyle: {
+        p: 'font-size: 28rpx; line-height: 48rpx; color: #333333; margin-bottom: 20rpx;',
+        span: 'font-size: 28rpx; line-height: 48rpx; color: #333333;',
+        div: 'font-size: 28rpx; line-height: 48rpx; color: #333333;',
+        img: 'max-width: 100%;',
+        h1: 'font-size: 32rpx; line-height: 46rpx; color: #0d1937;',
+        h2: 'font-size: 30rpx; line-height: 44rpx; color: #0d1937;',
+      },
     }
   },
   onLoad(query) {
     this.id = query.id
     this.category = query.category
+    this.article.title = decodeURIComponent(query.title || '')
+    this.article.hospital = decodeURIComponent(query.hospital || '')
+    this.article.doctor = decodeURIComponent(query.doctor || '')
+    this.article.date = decodeURIComponent(query.date || '')
+    uni.setNavigationBarTitle({ title: this.article.title || '详情' })
     // 详情地址格式:{shareUrl}content/{id除以1000向下取整}/{id}.html
-    this.urlParse = getApp().globalData.shareUrl + 'content/' + Math.floor(this.id / 1000) + '/' + this.id + '.html?time=' + Date.now()
+    this.contentUrl = getApp().globalData.shareUrl + 'content/' + Math.floor(this.id / 1000) + '/' + this.id + '.html?time=' + Date.now()
+    this.getContent()
+  },
+  methods: {
+    getContent() {
+      uni.request({
+        url: this.contentUrl,
+        method: 'GET',
+        // 这里拿的是静态 HTML 文件,不是 JSON,关掉自动 JSON 解析,直接拿原始文本
+        dataType: 'text',
+        success: (res) => {
+          this.article.content = typeof res.data === 'string' ? res.data : ''
+        },
+        fail: (err) => {
+          console.error('getContent failed', this.contentUrl, err)
+        },
+      })
+    },
   },
 }
 </script>
 
-<style lang="scss" scoped>
-.content {
-  display: flex;
-  flex-direction: column;
-
-  .artical {
-    font-size: 32rpx;
-    box-shadow: 0px 4rpx 32rpx rgba(0, 0, 0, 0.1);
-    border-radius: 32rpx;
-    padding: 30rpx;
-  }
+<style scoped>
+.detail-page {
+  padding: 30rpx;
+}
+.detail-title {
+  font-size: 34rpx;
+  font-weight: bold;
+  color: #0d1937;
+  line-height: 48rpx;
+}
+.detail-sub {
+  font-size: 24rpx;
+  color: #a7adba;
+  margin: 16rpx 0 20rpx;
+}
+.detail-divider {
+  height: 1px;
+  background-color: #f0f0f0;
+  margin-bottom: 30rpx;
 }
 </style>

+ 17 - 5
src/pages/index/index.vue

@@ -20,7 +20,7 @@
       </view>
     </view>
     <view class="page-nav-box">
-      <view v-for="(item, index) in navList" :key="index" class="nav-content" @click="goDetailPage(item)">
+      <view v-for="(item, index) in navList" :key="index" class="nav-content" @click="goDetailPage(item, index)">
         <view class="nav-badge" :style="{ background: badgeOf(item.task_name).color }">{{ badgeOf(item.task_name).label }}</view>
         <view class="nav-task-name">{{ item.task_name }}</view>
         <view v-if="item.finish_flag" style="color: #ff7356;font-size: 22rpx;">已完成</view>
@@ -181,13 +181,25 @@ export default {
       this.getArticleList('voice_science', true)
     },
     goArticleDetail(item, category) {
+      // 标题/医院/医生/日期列表页已经有了,直接带过去,详情页不用再单独请求一次
+      const params = [
+        `id=${item.id}`,
+        `category=${category}`,
+        `title=${encodeURIComponent(item.title || '')}`,
+        `hospital=${encodeURIComponent(item.hospital || '')}`,
+        `doctor=${encodeURIComponent(item.doctor || '')}`,
+        `date=${encodeURIComponent(item.date || '')}`,
+      ].join('&')
       uni.navigateTo({
-        url: `/pages/index/articleDetail?id=${item.id}&category=${category}`
+        url: `/pages/index/articleDetail?${params}`
       })
     },
-    goDetailPage(item) {
-      item.category_id == 1 ? uni.navigateTo({
-        url: "/pages/sickForm/history?finish=" + item.finish_flag
+    goDetailPage(item, index) {
+      // 病史信息固定是列表第一项,不再依赖后台给的 category_id 具体数值(1.0/2.0 之间这个值变过,导致路由跳错)
+      // 但 category_id 本身还是要带给 history.vue,它填完表单后要原样传给 blurb.vue -> historyDetail.vue,
+      // 否则后面进动态问卷时 category_id 会丢失,取不到题目
+      index === 0 ? uni.navigateTo({
+        url: "/pages/sickForm/history?id=" + item.category_id + "&finish=" + item.finish_flag
       }) :
         uni.navigateTo({
           url: "/pages/sickForm/blurb?id=" + item.category_id + '&name=' + item.task_name + '&finish=' + item.finish_flag

+ 10 - 1
src/pages/sickForm/history.vue

@@ -232,6 +232,9 @@ export default {
   },
   onLoad(query) {
 	  this.isFinish = query.finish || false
+	  // 从首页带过来的分类 id,提交后跳转 blurb.vue -> historyDetail.vue 时要原样传下去,
+	  // 否则动态问卷那边拿不到正确的 category_id,会用错误的默认值查不到题目
+	  this.pageId = query.id || ''
   },
  async onShow() {
 	  const scene = getApp().globalData.sceneParam
@@ -429,7 +432,7 @@ export default {
 	     const res = await request('user', 'update_case_info', this.baseFormData)
 	     if (res.code === 200) {
 			uni.navigateTo({
-			  url:"/pages/sickForm/blurb?finish=" + this.isFinish
+			  url:"/pages/sickForm/blurb?id=" + this.pageId + "&finish=" + this.isFinish
 			});
 	     } else {
 			console.error('update_case_info failed', res)
@@ -488,6 +491,12 @@ export default {
 }
 .picker-class-box {
 	color: #333;
+	border: 1px solid #e5e5e5;
+	border-radius: 8rpx;
+	padding: 0 20rpx;
+	height: 70rpx;
+	line-height: 70rpx;
+	box-sizing: border-box;
 }
 .footer-btn {
 	width: 94%;

+ 7 - 4
src/pages/sickForm/historyDetail.vue

@@ -68,11 +68,14 @@ export default {
 		return !!(item && item.isShow)
 	},
 	// "头痛的时间"是"病史信息"模块里一道写死用 id=205 特殊渲染的题目。题目 id 是各量表各自独立编号的,不是全局唯一,
-	// VHI-30 量表里也存在 id=205 的题目(内容跟头痛无关),加了两层判断:进入模块时的顶层 category_id(pageId) + 题目 id,
-	// pageId=1 已确认是进入"病史信息"模块时传的顶层分类 ID,比页面名称字符串更可靠,顺带保留页面名称兜底。
-	// TODO: 等"病史信息"题目接口有真实数据后,最好换成后台专门给这道题的类型标识字段来判断,不再靠 id/分类猜测
+	// VHI-30 量表里也存在 id=205 的题目(内容跟头痛无关)。判断条件:进入模块时的顶层 category_id(pageId) + 页面模块名称 + 题目 id + 题目内容文字包含"头痛"。
+	// 最后这层内容文字判断是关键:就算以后分类 35 底下顺序编号又巧合排到 205、但内容跟头痛无关,
+	// 只要题目文字里没有"头痛",就不会被误判成这个特殊控件,会按正常题目样式显示它自己的真实内容。
+	// 1.0 时代"病史信息"分类 ID 是 1,2.0 后台重新设计后变成了 35,且题库内容也整体换过;这道题在新题库里是否还存在还没验证,
+	// 等后台真的把这道题配上后,需要确认题目文字是否真的包含"头痛",不含的话这里的关键词要跟着调整。
+	// TODO: 长期来看最好换成后台专门给这道题的类型标识字段来判断,不再靠 id/分类/文字组合猜测
 	isHeadacheItem(item){
-		return !!(item && (item.id == 205 || item.id == '205') && (this.pageId == 1 || this.pageId == '1') && this.pageName === '病史信息')
+		return !!(item && (item.id == 205 || item.id == '205') && (this.pageId == 35 || this.pageId == '35') && this.pageName === '病史信息' && item.name && item.name.includes('头痛'))
 	},
 	unitChange(e){
 			 this.unitValue = e.detail.value;