Преглед изворни кода

feat: 替换内容展示组件为u-parse,优化关于我们和用户协议页面

在关于我们和用户协议页面中,将rich-text组件替换为u-parse组件,以支持更灵活的HTML内容解析。更新了数据结构,添加了articleHtml和articleTagStyle字段,并在数据加载时格式化内容。调整了样式以确保内容在不同设备上的适配性。
ylong пре 2 недеља
родитељ
комит
3abd5b07b7
3 измењених фајлова са 102 додато и 22 уклоњено
  1. 38 8
      pages-home/pages/about-us.vue
  2. 44 14
      pages-home/pages/user-agreement.vue
  3. 20 0
      utils/article-content.js

+ 38 - 8
pages-home/pages/about-us.vue

@@ -2,20 +2,31 @@
     <view class="user-agreement">
         <!-- <view class="agreement-title">{{ aboutUsData.title }}</view> -->
         <view class="agreement-content">
-            <rich-text :nodes="aboutUsData.content"></rich-text>
+            <u-parse
+                v-if="articleHtml"
+                :html="articleHtml"
+                :autoscroll="true"
+                :autoset-title="false"
+                :tag-style="articleTagStyle"
+                class="agreement-parse"
+            />
         </view>
     </view>
 </template>
 
 <script>
+import { ARTICLE_TAG_STYLE, formatArticleHtml } from '@/utils/article-content.js'
+
 export default {
     data() {
         return {
             aboutUsData: {
-                title: "",
-                content: "",
+                title: '',
+                content: '',
             },
-        };
+            articleHtml: '',
+            articleTagStyle: ARTICLE_TAG_STYLE,
+        }
     },
     onLoad() {
         this.getAboutUs();
@@ -30,7 +41,8 @@ export default {
                 .get("/token/getArticleOne?code=aboutShuHi")
                 .then((res) => {
                     if (res.code === 200) {
-                        this.aboutUsData = res.data;
+                        this.aboutUsData = res.data
+                        this.articleHtml = formatArticleHtml(res.data.content || '')
                     } else {
                         this.$u.toast(res.msg || "获取关于书嗨失败");
                     }
@@ -62,10 +74,28 @@ export default {
         font-size: 28rpx;
         color: $app-theme-text-color;
         line-height: 1.8;
+        width: 100%;
+        overflow: hidden;
+    }
 
-        :deep(rich-text) {
-            width: 100%;
-        }
+    .agreement-parse {
+        width: 100%;
+    }
+}
+
+::v-deep .agreement-parse {
+    .interlayer {
+        width: 100%;
+        max-width: 100%;
+    }
+
+    .article-table-scroll,
+    view[style*='overflow'] {
+        width: 100% !important;
+        max-width: 100%;
+        overflow-x: auto !important;
+        overflow-y: hidden;
+        -webkit-overflow-scrolling: touch;
     }
 }
 </style>

+ 44 - 14
pages-home/pages/user-agreement.vue

@@ -2,23 +2,33 @@
     <view class="user-agreement">
         <view class="agreement-title">{{ agreementData.title }}</view>
         <view class="agreement-content">
-            <rich-text :nodes="agreementData.content"></rich-text>
+            <u-parse
+                v-if="articleHtml"
+                :html="articleHtml"
+                :autoscroll="true"
+                :autoset-title="false"
+                :tag-style="articleTagStyle"
+                class="agreement-parse"
+            />
         </view>
     </view>
 </template>
 
 <script>
 import { ARTICLE_CODE, ARTICLE_TITLE } from '@/utils/policy-config.js'
+import { ARTICLE_TAG_STYLE, formatArticleHtml } from '@/utils/article-content.js'
 
 export default {
     data() {
         return {
             articleCode: ARTICLE_CODE.orderAgreement,
             agreementData: {
-                title: "",
-                content: "",
+                title: '',
+                content: '',
             },
-        };
+            articleHtml: '',
+            articleTagStyle: ARTICLE_TAG_STYLE,
+        }
     },
     onLoad(options) {
         const code = options.code || ARTICLE_CODE.orderAgreement
@@ -40,23 +50,24 @@ export default {
     methods: {
         fetchAgreement() {
             uni.showLoading({
-                title: "加载中...",
-            });
+                title: '加载中...',
+            })
             uni.$u.http
                 .get(`/token/getArticleOne?code=${this.articleCode}`)
                 .then((res) => {
                     if (res.code === 200) {
-                        this.agreementData = res.data;
+                        this.agreementData = res.data
+                        this.articleHtml = formatArticleHtml(res.data.content || '')
                     } else {
-                        this.$u.toast(res.msg || "获取协议内容失败");
+                        this.$u.toast(res.msg || '获取协议内容失败')
                     }
                 })
                 .finally(() => {
-                    uni.hideLoading();
-                });
+                    uni.hideLoading()
+                })
         },
     },
-};
+}
 </script>
 
 <style lang="scss" scoped>
@@ -78,10 +89,29 @@ export default {
         font-size: 28rpx;
         color: $app-theme-text-color;
         line-height: 1.8;
+        width: 100%;
+        overflow: hidden;
+    }
 
-        :deep(rich-text) {
-            width: 100%;
-        }
+    .agreement-parse {
+        width: 100%;
+    }
+}
+
+/* u-parse 表格外层滚动容器(autoscroll 生成的 div) */
+::v-deep .agreement-parse {
+    .interlayer {
+        width: 100%;
+        max-width: 100%;
+    }
+
+    .article-table-scroll,
+    view[style*='overflow'] {
+        width: 100% !important;
+        max-width: 100%;
+        overflow-x: auto !important;
+        overflow-y: hidden;
+        -webkit-overflow-scrolling: touch;
     }
 }
 </style>

+ 20 - 0
utils/article-content.js

@@ -0,0 +1,20 @@
+/** 协议/富文本文章 u-parse 标签样式 */
+export const ARTICLE_TAG_STYLE = {
+    p: 'margin:0 0 20rpx;line-height:1.8;font-size:28rpx;color:#333;',
+    img: 'max-width:100%;height:auto;display:block;',
+    table: 'border-collapse:collapse;min-width:100%;font-size:24rpx;',
+    th: 'border:1px solid #e5e5e5;padding:16rpx 20rpx;background:#f7f7f7;white-space:nowrap;font-size:24rpx;',
+    td: 'border:1px solid #e5e5e5;padding:16rpx 20rpx;white-space:nowrap;font-size:24rpx;',
+}
+
+/** 预处理 CMS 富文本:图片自适应、宽表格横向滚动 */
+export function formatArticleHtml(html) {
+    if (!html || typeof html !== 'string') return ''
+    let result = html.replace(/<img\b/gi, '<img style="max-width:100%;height:auto;display:block;"')
+    result = result.replace(
+        /<table\b/gi,
+        '<div class="article-table-scroll" style="width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;"><table'
+    )
+    result = result.replace(/<\/table>/gi, '</table></div>')
+    return result
+}