Procházet zdrojové kódy

feat(shop): 商城入口统一指向商品商城/移除积分商城+推荐商品文案统一+商城标题'浠艾福商城'

E2E Test Bot před 1 měsícem
rodič
revize
87b1303c87

+ 1 - 12
cfc-frontend/pages.json

@@ -430,7 +430,7 @@
         {
           "path": "index/index",
           "style": {
-            "navigationBarTitleText": "商品首页"
+            "navigationBarTitleText": "浠艾福商城"
           }
         },
         {
@@ -682,17 +682,6 @@
         }
       ]
     },
-    {
-      "root": "pages/points",
-      "pages": [
-        {
-          "path": "mall",
-          "style": {
-            "navigationBarTitleText": "积分商城"
-          }
-        }
-      ]
-    },
     {
       "root": "pages/wealth-sub",
       "pages": [

+ 1 - 1
cfc-frontend/pages/action/index.vue

@@ -72,7 +72,7 @@
       dimensionCode="action"
       :familyId="activeChildId"
       :products="dimensionProducts"
-      title="为你推荐"
+      title="推荐商品"
       @productClick="goProductDetail"
       @moreProducts="goMoreProducts" />
 

+ 1 - 1
cfc-frontend/pages/body/index.vue

@@ -111,7 +111,7 @@
       dimensionCode="body"
       :familyId="activeChildId"
       :products="dimensionProducts"
-      title="为你推荐"
+      title="推荐商品"
       @productClick="goProductDetail"
       @moreProducts="goMoreProducts" />
 

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

@@ -197,7 +197,7 @@ export default {
       this.loadProducts()
     },
     goShop() {
-      uni.navigateTo({ url: '/pages/points/mall' })
+      uni.navigateTo({ url: '/pages/shop/index' })
     },
     goDetail(id) {
       uni.navigateTo({ url: '/pages/shop/detail/detail?id=' + id })

+ 1 - 1
cfc-frontend/pages/mind/index.vue

@@ -117,7 +117,7 @@
       dimensionCode="mind"
       :familyId="currentChildId"
       :products="dimensionProducts"
-      title="为你推荐"
+      title="推荐商品"
       @productClick="goProductDetail"
       @moreProducts="goMoreProducts" />
 

+ 0 - 619
cfc-frontend/pages/points/mall.vue

@@ -1,619 +0,0 @@
-<template>
-  <view class="container">
-    <view class="header">
-      <text class="title">积分商城</text>
-      <view class="points-info">
-        <text class="points-label">我的积分</text>
-        <text class="points-value">{{ systemPoints }}</text>
-      </view>
-    </view>
-
-    <view class="category-tabs">
-      <view
-        v-for="tab in categories"
-        :key="tab.key"
-        class="tab-item"
-        :class="{ active: currentCategory === tab.key }"
-        @click="onCategoryChange(tab.key)"
-      >
-        <text class="tab-text">{{ tab.label }}</text>
-      </view>
-    </view>
-
-    <scroll-view
-      scroll-y
-      class="product-list"
-      @scrolltolower="onLoadMore"
-      refresher-enabled
-      :refresher-triggered="refreshing"
-      @refresherrefresh="onRefresh"
-    >
-      <view v-if="products.length > 0" class="product-grid">
-        <view
-          v-for="product in products"
-          :key="product.id"
-          class="product-card"
-          @click="onProductClick(product)"
-        >
-          <image
-            class="product-cover"
-            :src="getImageUrl(product.coverImage) || '/static/default-product.png'"
-            mode="aspectFill"
-          />
-          <view class="product-info">
-            <text class="product-name">{{ product.name }}</text>
-            <text class="product-points">{{ product.pointsPrice }} 积分</text>
-            <view class="exchange-btn" @click.stop="onExchangeClick(product)">
-              <text class="exchange-btn-text">兑换</text>
-            </view>
-          </view>
-        </view>
-      </view>
-      <view v-else-if="!loading" class="empty-state">
-        <text class="empty-text">暂无商品</text>
-      </view>
-      <view v-if="loadingMore" class="loading-more">
-        <text class="loading-text">加载中...</text>
-      </view>
-    </scroll-view>
-
-    <view class="records-btn" @click="onRecordsClick">
-      <text class="records-btn-text">兑换记录</text>
-    </view>
-
-    <view v-if="showExchangeModal" class="modal-mask" @click="onCloseModal">
-      <view class="modal-content" @click.stop>
-        <text class="modal-title">确认兑换</text>
-        <view v-if="selectedProduct" class="modal-product">
-          <image
-            class="modal-cover"
-            :src="selectedProduct.coverImage || '/static/default-product.png'"
-            mode="aspectFill"
-          />
-          <view class="modal-info">
-            <text class="modal-name">{{ selectedProduct.name }}</text>
-            <text class="modal-points">{{ selectedProduct.pointsPrice }} 积分</text>
-          </view>
-        </view>
-        <view class="modal-actions">
-          <view class="modal-btn cancel" @click="onCloseModal">
-            <text class="modal-btn-text">取消</text>
-          </view>
-          <view class="modal-btn confirm" @click="onConfirmExchange">
-            <text class="modal-btn-text">确认兑换</text>
-          </view>
-        </view>
-      </view>
-    </view>
-
-    <view v-if="showRecordsModal" class="modal-mask" @click="onCloseRecordsModal">
-      <view class="modal-content records-modal" @click.stop>
-        <text class="modal-title">兑换记录</text>
-        <scroll-view scroll-y class="records-list">
-          <view v-if="records.length > 0">
-            <view
-              v-for="record in records"
-              :key="record.id"
-              class="record-item"
-            >
-              <view class="record-header">
-                <text class="record-name">{{ record.productName }}</text>
-                <text class="record-points">-{{ record.pointsCost }}积分</text>
-              </view>
-              <view class="record-meta">
-                <text class="record-code">兑换码: {{ record.redeemCode }}</text>
-                <text class="record-date">{{ formatDate(record.createdAt) }}</text>
-              </view>
-            </view>
-          </view>
-          <view v-else class="empty-state">
-            <text class="empty-text">暂无兑换记录</text>
-          </view>
-        </scroll-view>
-        <view class="modal-close" @click="onCloseRecordsModal">
-          <text class="modal-close-text">关闭</text>
-        </view>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script>
-import {
-  getPointsExchangeProducts,
-  submitPointsExchange,
-  getPointsExchangeRecords,
-  getSystemBalance
-} from '@/utils/api.js'
-import config from '@/config.js'
-
-export default {
-  data() {
-    return {
-      categories: [
-        { key: 'all', label: '全部' },
-        { key: 'vip', label: 'VIP' },
-        { key: 'redeem', label: '兑换' },
-        { key: 'flow', label: '流量' },
-        { key: 'gift', label: '礼品' }
-      ],
-      currentCategory: 'all',
-      products: [],
-      records: [],
-      systemPoints: 0,
-      pageNum: 1,
-      pageSize: 10,
-      loading: false,
-      loadingMore: false,
-      refreshing: false,
-      hasMore: true,
-      showExchangeModal: false,
-      showRecordsModal: false,
-      selectedProduct: null
-    }
-  },
-  onLoad() {
-    this.loadSystemPoints()
-    this.loadProducts()
-  },
-  onShow() {
-    this.loadSystemPoints()
-  },
-  methods: {
-    loadSystemPoints() {
-      var childId = uni.getStorageSync('currentChildId')
-      getSystemBalance(childId).then(function(res) {
-        if (res.code === 200 && res.data) {
-          this.systemPoints = res.data.systemPoints || 0
-        }
-      }.bind(this)).catch(function() {})
-    },
-    loadProducts() {
-      this.loading = true
-      getPointsExchangeProducts({
-        category: this.currentCategory,
-        pageNum: this.pageNum,
-        pageSize: this.pageSize
-      }).then(function(res) {
-        this.loading = false
-        if (res.code === 200 && res.data) {
-          var list = res.data.records || []
-          if (this.pageNum === 1) {
-            this.products = list
-          } else {
-            this.products = this.products.concat(list)
-          }
-          this.hasMore = list.length >= this.pageSize
-        }
-      }.bind(this)).catch(function() {
-        this.loading = false
-      }.bind(this))
-    },
-    onCategoryChange(category) {
-      this.currentCategory = category
-      this.pageNum = 1
-      this.products = []
-      this.loadProducts()
-    },
-    onRefresh() {
-      this.refreshing = true
-      this.pageNum = 1
-      getPointsExchangeProducts({
-        category: this.currentCategory,
-        pageNum: 1,
-        pageSize: this.pageSize
-      }).then(function(res) {
-        this.refreshing = false
-        if (res.code === 200 && res.data) {
-          this.products = res.data.records || []
-          this.hasMore = (res.data.records || []).length >= this.pageSize
-        }
-      }.bind(this)).catch(function() {
-        this.refreshing = false
-      }.bind(this))
-    },
-    onLoadMore() {
-      if (!this.hasMore && !this.loadingMore) {
-        this.loadingMore = true
-        this.pageNum = this.pageNum + 1
-        getPointsExchangeProducts({
-          category: this.currentCategory,
-          pageNum: this.pageNum,
-          pageSize: this.pageSize
-        }).then(function(res) {
-          this.loadingMore = false
-          if (res.code === 200 && res.data) {
-            var list = res.data.records || []
-            this.products = this.products.concat(list)
-            this.hasMore = list.length >= this.pageSize
-          }
-        }.bind(this)).catch(function() {
-          this.loadingMore = false
-        }.bind(this))
-      }
-    },
-    onProductClick(product) {
-      this.selectedProduct = product
-      this.showExchangeModal = true
-    },
-    onExchangeClick(product) {
-      this.selectedProduct = product
-      this.showExchangeModal = true
-    },
-    onCloseModal() {
-      this.showExchangeModal = false
-      this.selectedProduct = null
-    },
-    onConfirmExchange() {
-      if (!this.selectedProduct) {
-        return
-      }
-      var productId = this.selectedProduct.id
-      submitPointsExchange({ productId: productId, quantity: 1 }).then(function(res) {
-        if (res.code === 200) {
-          uni.showToast({ title: '兑换成功', icon: 'success' })
-          this.loadSystemPoints()
-          this.loadProducts()
-        }
-      }.bind(this)).catch(function(err) {
-        uni.showToast({ title: err && err.message ? err.message : '兑换失败', icon: 'none' })
-      }.bind(this))
-      this.onCloseModal()
-    },
-    onRecordsClick() {
-      this.loadRecords()
-      this.showRecordsModal = true
-    },
-    loadRecords() {
-      getPointsExchangeRecords().then(function(res) {
-        if (res.code === 200 && res.data) {
-          this.records = res.data || []
-        }
-      }.bind(this)).catch(function() {})
-    },
-    onCloseRecordsModal() {
-      this.showRecordsModal = false
-    },
-    formatDate(dateStr) {
-      if (!dateStr) {
-        return ''
-      }
-      var date = new Date(dateStr)
-      var year = date.getFullYear()
-      var month = date.getMonth() + 1
-      var day = date.getDate()
-      return year + '-' + (month < 10 ? '0' + month : month) + '-' + (day < 10 ? '0' + day : day)
-    },
-    getImageUrl: function(path) {
-      return config.API_BASE_URL + path
-    }
-  }
-}
-</script>
-
-<style scoped>
-.container {
-  min-height: 100vh;
-  background-color: #f5f5f5;
-  padding-bottom: 120rpx;
-}
-
-.header {
-  background: linear-gradient(135deg, #ff8c42 0%, #ff6b35 100%);
-  padding: 40rpx 30rpx;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-
-.title {
-  font-size: 40rpx;
-  font-weight: bold;
-  color: #ffffff;
-}
-
-.points-info {
-  display: flex;
-  flex-direction: column;
-  align-items: flex-end;
-}
-
-.points-label {
-  font-size: 24rpx;
-  color: rgba(255, 255, 255, 0.8);
-}
-
-.points-value {
-  font-size: 48rpx;
-  font-weight: bold;
-  color: #ffffff;
-}
-
-.category-tabs {
-  display: flex;
-  background-color: #ffffff;
-  padding: 20rpx 0;
-  border-bottom: 1rpx solid #eeeeee;
-  overflow-x: auto;
-}
-
-.tab-item {
-  flex: 1;
-  text-align: center;
-  padding: 16rpx 0;
-  margin: 0 10rpx;
-  border-radius: 30rpx;
-  background-color: #f5f5f5;
-}
-
-.tab-item.active {
-  background-color: #ff8c42;
-}
-
-.tab-text {
-  font-size: 28rpx;
-  color: #666666;
-}
-
-.tab-item.active .tab-text {
-  color: #ffffff;
-  font-weight: bold;
-}
-
-.product-list {
-  padding: 20rpx;
-}
-
-.product-grid {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: space-between;
-}
-
-.product-card {
-  width: 48%;
-  background-color: #ffffff;
-  border-radius: 16rpx;
-  overflow: hidden;
-  margin-bottom: 20rpx;
-  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
-}
-
-.product-cover {
-  width: 100%;
-  height: 240rpx;
-}
-
-.product-info {
-  padding: 20rpx;
-}
-
-.product-name {
-  font-size: 28rpx;
-  color: #333333;
-  font-weight: bold;
-  display: block;
-  margin-bottom: 10rpx;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.product-points {
-  font-size: 32rpx;
-  color: #ff6b35;
-  font-weight: bold;
-  display: block;
-  margin-bottom: 16rpx;
-}
-
-.exchange-btn {
-  background: linear-gradient(135deg, #ff8c42 0%, #ff6b35 100%);
-  border-radius: 30rpx;
-  padding: 16rpx 0;
-  text-align: center;
-}
-
-.exchange-btn-text {
-  font-size: 28rpx;
-  color: #ffffff;
-  font-weight: bold;
-}
-
-.empty-state {
-  text-align: center;
-  padding: 100rpx 0;
-}
-
-.empty-text {
-  font-size: 28rpx;
-  color: #999999;
-}
-
-.loading-more {
-  text-align: center;
-  padding: 30rpx 0;
-}
-
-.loading-text {
-  font-size: 24rpx;
-  color: #999999;
-}
-
-.records-btn {
-  position: fixed;
-  bottom: 40rpx;
-  left: 50%;
-  transform: translateX(-50%);
-  background: linear-gradient(135deg, #ff8c42 0%, #ff6b35 100%);
-  border-radius: 40rpx;
-  padding: 24rpx 60rpx;
-  box-shadow: 0 4rpx 12rpx rgba(255, 107, 53, 0.3);
-}
-
-.records-btn-text {
-  font-size: 30rpx;
-  color: #ffffff;
-  font-weight: bold;
-}
-
-.modal-mask {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background-color: rgba(0, 0, 0, 0.5);
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  z-index: 1000;
-}
-
-.modal-content {
-  background-color: #ffffff;
-  border-radius: 20rpx;
-  padding: 40rpx;
-  width: 80%;
-  max-width: 600rpx;
-}
-
-.records-modal {
-  max-height: 70vh;
-  display: flex;
-  flex-direction: column;
-}
-
-.modal-title {
-  font-size: 36rpx;
-  font-weight: bold;
-  color: #333333;
-  text-align: center;
-  display: block;
-  margin-bottom: 30rpx;
-}
-
-.modal-product {
-  display: flex;
-  align-items: center;
-  margin-bottom: 30rpx;
-  padding: 20rpx;
-  background-color: #f9f9f9;
-  border-radius: 12rpx;
-}
-
-.modal-cover {
-  width: 120rpx;
-  height: 120rpx;
-  border-radius: 8rpx;
-  margin-right: 20rpx;
-}
-
-.modal-info {
-  flex: 1;
-}
-
-.modal-name {
-  font-size: 30rpx;
-  color: #333333;
-  font-weight: bold;
-  display: block;
-  margin-bottom: 10rpx;
-}
-
-.modal-points {
-  font-size: 32rpx;
-  color: #ff6b35;
-  font-weight: bold;
-}
-
-.modal-actions {
-  display: flex;
-  justify-content: space-between;
-}
-
-.modal-btn {
-  flex: 1;
-  padding: 20rpx 0;
-  border-radius: 12rpx;
-  text-align: center;
-  margin: 0 10rpx;
-}
-
-.modal-btn.cancel {
-  background-color: #f5f5f5;
-}
-
-.modal-btn.confirm {
-  background: linear-gradient(135deg, #ff8c42 0%, #ff6b35 100%);
-}
-
-.modal-btn-text {
-  font-size: 30rpx;
-  color: #666666;
-  font-weight: bold;
-}
-
-.modal-btn.confirm .modal-btn-text {
-  color: #ffffff;
-}
-
-.records-list {
-  flex: 1;
-  overflow-y: auto;
-  max-height: 50vh;
-}
-
-.record-item {
-  padding: 20rpx 0;
-  border-bottom: 1rpx solid #eeeeee;
-}
-
-.record-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 10rpx;
-}
-
-.record-name {
-  font-size: 28rpx;
-  color: #333333;
-  font-weight: bold;
-}
-
-.record-points {
-  font-size: 28rpx;
-  color: #ff6b35;
-  font-weight: bold;
-}
-
-.record-meta {
-  display: flex;
-  justify-content: space-between;
-}
-
-.record-code {
-  font-size: 24rpx;
-  color: #666666;
-}
-
-.record-date {
-  font-size: 24rpx;
-  color: #999999;
-}
-
-.modal-close {
-  margin-top: 20rpx;
-  padding: 20rpx 0;
-  background: linear-gradient(135deg, #ff8c42 0%, #ff6b35 100%);
-  border-radius: 12rpx;
-  text-align: center;
-}
-
-.modal-close-text {
-  font-size: 30rpx;
-  color: #ffffff;
-  font-weight: bold;
-}
-</style>

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

@@ -65,10 +65,10 @@
       :refresher-triggered="refreshing"
       @refresherrefresh="onRefresh"
     >
-      <!-- 为你推荐 -->
+      <!-- 推荐商品 -->
       <view class="recommend-section" v-if="recommended.length > 0">
         <view class="recommend-header">
-          <text class="recommend-title">🔥 为你推荐</text>
+          <text class="recommend-title">🔥 推荐商品</text>
         </view>
         <scroll-view scroll-x enable-flex show-scrollbar="false" class="recommend-scroll">
           <view
@@ -410,7 +410,7 @@ export default {
   font-weight: 500;
 }
 
-/* 为你推荐 */
+  /* 推荐商品 */
 .recommend-section {
   background: #fff;
   border-radius: 16rpx;

+ 2 - 10
cfc-frontend/pages/wealth/index.vue

@@ -9,14 +9,6 @@
         tagline="利他创富 · 价值共享"
         quote="富足源于利他与坚持" />
 
-      <!-- 商品推荐 -->
-      <DimensionProducts
-        dimensionCode="wealth"
-        :products="dimensionProducts"
-        title="为你推荐"
-        @productClick="goProductDetail"
-        @moreProducts="goMoreProducts" />
-
       <!-- 推荐阅读 -->
       <ArticleBookshelf
         :articles="wealthArticles"
@@ -174,7 +166,7 @@
         dimensionCode="wealth"
         :familyId="activeChildId"
         :products="dimensionProducts"
-        title="为你推荐"
+        title="推荐商品"
         @productClick="goProductDetail"
         @moreProducts="goMoreProducts" />
 
@@ -604,7 +596,7 @@ export default {
       var routes = {
         education: '/pages/assessment/results',
         social: '/pages/activity/index',
-        points: '/pages/points/mall',
+        points: '/pages/shop/index',
         emotion: '/pages/mind-detail/emotion-report',
         understanding: '/pages/mind-detail/emotion-trend',
         legacy: '/pages/wishes/index'

+ 1 - 1
cfc-frontend/pages/wisdom/index.vue

@@ -103,7 +103,7 @@
       dimensionCode="wisdom"
       :familyId="activeChildId"
       :products="dimensionProducts"
-      title="为你推荐"
+      title="推荐商品"
       @productClick="goProductDetail"
       @moreProducts="goMoreProducts" />