Просмотр исходного кода

fix(ui): 首页未登录态热门商品简介纯文本化 + 按实际销量排序

任务: home-hot-products-intro-sales
- pages/index-home/index.vue:
  - loadDiscoverProducts 传 sort=[{column:'salesCount',order:'desc'}],后端 SortInterceptor/SortUtil 据此按 products.sales_count 降序返回
  - desc 改用 intro(简介)优先、description 回退,统一经新增 plainText() 剥离 HTML 标签与实体,避免商品卡片展示 HTML 源码
- components/DimensionProducts.vue:layout='mall' 卡片新增商品简介行(仅 prod.desc 存在时显示,两行截断)
  - 已登录态首页/成长页推荐商品不传 products 数组(走自加载 getDimensionProducts),不注入 desc,不受影响

验证:verify-vue-compile.js 2 文件 PASS;audit-mp-antipatterns ERROR 0
Agnes Agent 1 неделя назад
Родитель
Сommit
0c4d92e997

+ 13 - 0
cfc-frontend/components/DimensionProducts.vue

@@ -8,6 +8,7 @@
         <image class="product-img" :class="layout === 'mall' ? 'product-img-mall' : ''" :src="getImageUrl(prod.coverImage) || '/static/default-product.png'" mode="aspectFill"  lazy-load />
         <view class="product-body" :class="layout === 'mall' ? 'product-body-mall' : ''">
           <text class="product-name" :class="layout === 'mall' ? 'product-name-mall' : ''">{{ prod.name }}</text>
+          <text v-if="layout === 'mall' && prod.desc" class="product-desc-mall">{{ prod.desc }}</text>
           <view class="price-row">
             <text class="product-price" :class="layout === 'mall' ? 'product-price-mall' : ''" v-if="prod.priceLabel">{{ prod.priceLabel }}</text>
             <text class="product-price" :class="layout === 'mall' ? 'product-price-mall' : ''" v-else-if="prod.price">{{ formatPriceWithSymbol(prod.price) }}</text>
@@ -229,6 +230,18 @@ export default {
   -webkit-box-orient: vertical;
   white-space: normal;
 }
+.product-desc-mall {
+  display: -webkit-box;
+  font-size: calc(22rpx * var(--font-scale, 1));
+  color: $facade-text-muted;
+  line-height: 1.5;
+  margin-bottom: 8rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+  white-space: normal;
+}
 .product-price-mall {
   font-size: calc(28rpx * var(--font-scale, 1));
 }

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

@@ -2103,11 +2103,11 @@ title: '添加家庭成员',
         self._checkSplashReady()
       })
     },
-    // 热门商品:从后台取 3 个,后台按 sort_order 升序、createdAt 倒序返回。
+    // 热门商品:从后台取 3 个,按实际销量(sales_count)降序返回。
     // 接口异常或无数据时保留兜底项,避免区块空白。
     loadDiscoverProducts: function() {
       var self = this
-      productList({ page: 1, size: 3 }).then(function(res) {
+      productList({ page: 1, size: 3, sort: [{ column: 'salesCount', order: 'desc' }] }).then(function(res) {
         if (res && res.code === 200 && res.data) {
           var records = res.data.records || []
           if (records.length) {
@@ -2116,7 +2116,8 @@ title: '添加家庭成员',
                 id: item.id,
                 name: item.name || '',
                 coverImage: item.coverImage || item.image || '',
-                desc: item.description || item.summary || '',
+                // 商品简介:优先 intro(详细介绍/简介),回退 description;统一剥离 HTML 标签与实体,避免展示源码
+                desc: self.plainText(item.intro || item.description || ''),
                 price: (item.price != null && Number(item.price) > 0) ? (Number(item.price) / 100) : null
               }
             })
@@ -2124,6 +2125,21 @@ title: '添加家庭成员',
         }
       }).catch(function() {})
     },
+    // 富文本(HTML)→ 纯文本:去 style/script 标签与 HTML 标签、解码常见实体、压缩空白
+    plainText: function(html) {
+      if (!html) return ''
+      return String(html)
+        .replace(/<style[\s\S]*?<\/style>/gi, ' ')
+        .replace(/<script[\s\S]*?<\/script>/gi, ' ')
+        .replace(/<[^>]+>/g, ' ')
+        .replace(/&nbsp;/gi, ' ')
+        .replace(/&lt;/gi, '<')
+        .replace(/&gt;/gi, '>')
+        .replace(/&amp;/gi, '&')
+        .replace(/&quot;/gi, '"')
+        .replace(/\s+/g, ' ')
+        .trim()
+    },
     loadFeaturedArticles: function() {
       var self = this
       this.articlesLoading = true