Procházet zdrojové kódy

feat: 添加渠道ID字段并优化商品列表骨架屏加载

- 在Api.userInfo类型定义中添加channelId字段,用于标识企业渠道
- 在用户状态管理中初始化channelId为0
- 更新开发环境配置地址为田同学的开发环境
- 在商品搜索和详情页面中使用用户信息中的channelId替代硬编码的1
- 为小商品搜索页面添加骨架屏加载动画效果
- 优化商品详情页面结构,使用template包装确保正确渲染
zhangtao před 2 dny
rodič
revize
dd9cd6b1df

+ 4 - 0
src/api/api.type.d.ts

@@ -1,5 +1,9 @@
 namespace Api {
 namespace Api {
   interface userInfo {
   interface userInfo {
+    /**
+     * 渠道(企业ID)
+     */
+    channelId: number
     /**
     /**
      * 会员头像地址
      * 会员头像地址
      */
      */

+ 2 - 1
src/config/index.ts

@@ -14,7 +14,8 @@ const mapEnvVersion = {
   // develop: 'http://192.168.1.166:8080', // 张
   // develop: 'http://192.168.1.166:8080', // 张
   // develop: 'http://192.168.1.101:8080',
   // develop: 'http://192.168.1.101:8080',
   // develop: 'http://192.168.0.157:8080',
   // develop: 'http://192.168.0.157:8080',
-  develop: 'http://192.168.1.253:8080',
+  // develop: 'http://192.168.1.253:8080',
+  develop: 'http://192.168.1.89:8080', // 田
   // develop: 'http://47.109.84.152:8081',
   // develop: 'http://47.109.84.152:8081',
   /**
   /**
    * 体验版
    * 体验版

+ 1 - 0
src/store/user.ts

@@ -19,6 +19,7 @@ export const useUserStore = defineStore('user', {
     redirectName: '',
     redirectName: '',
     userInfo: {
     userInfo: {
       id: 0,
       id: 0,
+      channelId: 0,
     },
     },
   }),
   }),
   getters: {
   getters: {

+ 18 - 16
src/subPack-xsb/commonTab/components/index.vue

@@ -98,7 +98,7 @@ watch(() => backTop.value, () => {
         class="header-linear h320rpx px24rpx"
         class="header-linear h320rpx px24rpx"
         :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
         :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
       >
       >
-        <wd-skeleton theme="image" :loading="loading" :row-col="[{ height: '30px', width: '100%' }]">
+        <wd-skeleton animation="gradient" theme="image" :loading="loading" :row-col="[{ height: '30px', width: '100%' }]">
           <view class="h60rpx w-full flex items-center justify-between rounded-40rpx bg-white pr6rpx" @click="router.push({ name: 'xsb-search' })">
           <view class="h60rpx w-full flex items-center justify-between rounded-40rpx bg-white pr6rpx" @click="router.push({ name: 'xsb-search' })">
             <view class="flex items-center pb14rpx pl24rpx pt16rpx">
             <view class="flex items-center pb14rpx pl24rpx pt16rpx">
               <wd-icon name="search" size="14" color="#ccc" />
               <wd-icon name="search" size="14" color="#ccc" />
@@ -130,7 +130,7 @@ watch(() => backTop.value, () => {
       </view>
       </view>
 
 
       <view class="px24rpx" :class="[recommendText.length ? '-mt180rpx' : '-mt240rpx']">
       <view class="px24rpx" :class="[recommendText.length ? '-mt180rpx' : '-mt240rpx']">
-        <wd-skeleton theme="image" :loading="loading" :row-col="[{ height: '138px', width: '100%' }]">
+        <wd-skeleton theme="image" animation="gradient" :loading="loading" :row-col="[{ height: '138px', width: '100%' }]">
           <wd-swiper
           <wd-swiper
             :autoplay="false" :list="swiperList" :height="138" :indicator="false" value-key="advertImg" @click="handleGo"
             :autoplay="false" :list="swiperList" :height="138" :indicator="false" value-key="advertImg" @click="handleGo"
           />
           />
@@ -220,20 +220,22 @@ watch(() => backTop.value, () => {
           </scroll-view>
           </scroll-view>
         </view>
         </view>
         <view class="mt20rpx">
         <view class="mt20rpx">
-          <view class="flex items-center">
-            <scroll-view scroll-y type="custom">
-              <grid-view type="masonry" cross-axis-count="2" main-axis-gap="10" cross-axis-gap="10">
-                <wd-swiper
-                  :autoplay="false" :list="[
-                    `${StaticUrl}/xsb-swiper1.png`,
-                  ]" :height="231"
-                />
-                <view v-for="it in goodsList" :key="it.id">
-                  <itemGoods :item-goods="it" />
-                </view>
-              </grid-view>
-            </scroll-view>
-          </view>
+          <wd-skeleton theme="image" animation="gradient" :loading="loading" :row-col="[[{ height: '568rpx', width: '344rpx' }, { height: '568rpx', width: '344rpx' }], [{ height: '568rpx', width: '344rpx' }, { height: '568rpx', width: '344rpx' }]]">
+            <view class="flex items-center">
+              <scroll-view scroll-y type="custom">
+                <grid-view type="masonry" cross-axis-count="2" main-axis-gap="10" cross-axis-gap="10">
+                  <wd-swiper
+                    :autoplay="false" :list="[
+                      `${StaticUrl}/xsb-swiper1.png`,
+                    ]" :height="231"
+                  />
+                  <view v-for="it in goodsList" :key="it.id">
+                    <itemGoods :item-goods="it" />
+                  </view>
+                </grid-view>
+              </scroll-view>
+            </view>
+          </wd-skeleton>
         </view>
         </view>
         <wd-loadmore :state="state" :loading-props="{ color: '#9ED605', size: 20 }" @reload="emit('scrollBottom')" />
         <wd-loadmore :state="state" :loading-props="{ color: '#9ED605', size: 20 }" @reload="emit('scrollBottom')" />
       </view>
       </view>

+ 2 - 1
src/subPack-xsb/commonTab/index.vue

@@ -23,9 +23,10 @@ definePage({
   },
   },
 })
 })
 const { ScrollDown, topNavActive, leftActive, backTop, SelectShopInfo } = storeToRefs(useSysXsbStore())
 const { ScrollDown, topNavActive, leftActive, backTop, SelectShopInfo } = storeToRefs(useSysXsbStore())
+const { userInfo } = storeToRefs(useUserStore())
 const commonCategoryData = ref<Api.xsbCategories[]>([])
 const commonCategoryData = ref<Api.xsbCategories[]>([])
 const { data: goodsList, isLastPage, page, error, refresh } = usePagination((pageNum, pageSize) =>
 const { data: goodsList, isLastPage, page, error, refresh } = usePagination((pageNum, pageSize) =>
-  Apis.xsb.getSearchProductList({ data: { pageNum, pageSize, salesNum: 'DESC', shopId: Number(SelectShopInfo.value?.shopId) || 1, channelId: 1 } }), {
+  Apis.xsb.getSearchProductList({ data: { pageNum, pageSize, salesNum: 'DESC', shopId: Number(SelectShopInfo.value?.shopId) || 1, channelId: userInfo.value.channelId } }), {
   data: resp => resp.list,
   data: resp => resp.list,
   initialData: [],
   initialData: [],
   initialPage: 1,
   initialPage: 1,

+ 103 - 101
src/subPack-xsb/goods/index.vue

@@ -87,54 +87,55 @@ async function getGoodsDetaile() {
 </script>
 </script>
 
 
 <template>
 <template>
-  <view v-if="goodsInfo" class="page-xsb">
+  <view class="page-xsb">
     <wd-navbar
     <wd-navbar
       title="商品详情" :custom-style="`background-color:${isShowTab ? '#FFF !important' : 'transparent !important'}`" :bordered="false" :z-index="99"
       title="商品详情" :custom-style="`background-color:${isShowTab ? '#FFF !important' : 'transparent !important'}`" :bordered="false" :z-index="99"
       safe-area-inset-top left-arrow fixed @click-left="router.back()"
       safe-area-inset-top left-arrow fixed @click-left="router.back()"
     />
     />
-    <wd-swiper v-model:current="current" :list="swiperList" autoplay :height="375">
-      <template #indicator="{ current: currentIndex, total }">
-        <view class="custom-indicator absolute bottom-60rpx right-20rpx px26rpx">
-          {{ currentIndex + 1 }}/{{ total }}
-        </view>
-      </template>
-    </wd-swiper>
-    <view class="header view-0 relative z-3 rounded-t-32rpx px24rpx pt24rpx -mt30rpx">
-      <view class="flex items-center justify-between">
-        <view class="flex items-end text-#FF4D3A font-semibold">
-          <view class="text-24rpx">
-            ¥
+    <template v-if="goodsInfo">
+      <wd-swiper v-model:current="current" :list="swiperList" autoplay :height="375">
+        <template #indicator="{ current: currentIndex, total }">
+          <view class="custom-indicator absolute bottom-60rpx right-20rpx px26rpx">
+            {{ currentIndex + 1 }}/{{ total }}
           </view>
           </view>
-          <view class="text-36rpx line-height-[36rpx]">
-            {{ goodsInfo?.channelProdPrice }}
+        </template>
+      </wd-swiper>
+      <view class="view-0 header relative z-3 rounded-t-32rpx px24rpx pt24rpx -mt30rpx">
+        <view class="flex items-center justify-between">
+          <view class="flex items-end text-#FF4D3A font-semibold">
+            <view class="text-24rpx">
+              ¥
+            </view>
+            <view class="text-36rpx line-height-[36rpx]">
+              {{ goodsInfo?.channelProdPrice }}
+            </view>
           </view>
           </view>
-        </view>
         <!-- <view>
         <!-- <view>
           <image class="h40rpx w40rpx" :src="`${StaticUrl}/collect-yes.png`" />
           <image class="h40rpx w40rpx" :src="`${StaticUrl}/collect-yes.png`" />
         </view> -->
         </view> -->
+        </view>
       </view>
       </view>
-    </view>
-    <view class="sticky left-0 z-99 box-border h84rpx w-full flex items-center justify-between bg-white px24rpx" :style="{ top: `${statusBarHeight + MenuButtonHeight}px`, opacity: isShowTab ? 1 : 0 }" :class="[isShowTab ? '' : '']">
-      <view v-for="item in goodsDetaileTabList" :key="item.id" class="relative flex items-center text-32rpx font-semibold" @click="handleGoCurren(item.id)">
-        {{ item.title }}
-        <view v-show="currentDetaile == item.id" class="line absolute left-50% h12rpx w40rpx rounded-8rpx bg-[var(--them-color)] -bottom-15rpx -translate-x-50%" />
+      <view class="sticky left-0 z-99 box-border h84rpx w-full flex items-center justify-between bg-white px24rpx" :style="{ top: `${statusBarHeight + MenuButtonHeight}px`, opacity: isShowTab ? 1 : 0 }" :class="[isShowTab ? '' : '']">
+        <view v-for="item in goodsDetaileTabList" :key="item.id" class="relative flex items-center text-32rpx font-semibold" @click="handleGoCurren(item.id)">
+          {{ item.title }}
+          <view v-show="currentDetaile == item.id" class="line absolute left-50% h12rpx w40rpx rounded-8rpx bg-[var(--them-color)] -bottom-15rpx -translate-x-50%" />
+        </view>
       </view>
       </view>
-    </view>
-    <view class="px24rpx">
-      <view class="-mt64rpx">
-        <view class="text-left text-28rpx font-semibold">
-          <!-- <view v-for="i in 2" :key="i" class="mr5px inline-block">
+      <view class="px24rpx">
+        <view class="-mt64rpx">
+          <view class="text-left text-28rpx font-semibold">
+            <!-- <view v-for="i in 2" :key="i" class="mr5px inline-block">
             <wd-tag type="primary">
             <wd-tag type="primary">
               新品{{ i }}
               新品{{ i }}
             </wd-tag>
             </wd-tag>
           </view> -->
           </view> -->
-          {{ goodsInfo.prodName }}
+            {{ goodsInfo.prodName }}
+          </view>
         </view>
         </view>
-      </view>
-      <!-- <view class="mt16rpx text-24rpx text-#AAAAAA">
+        <!-- <view class="mt16rpx text-24rpx text-#AAAAAA">
         优选产地,皮薄核小,维c满满
         优选产地,皮薄核小,维c满满
       </view> -->
       </view> -->
-      <!-- <view class="mt20rpx flex items-center">
+        <!-- <view class="mt20rpx flex items-center">
         <view
         <view
           v-for="item in 2" :key="item"
           v-for="item in 2" :key="item"
           class="mr16rpx flex items-center justify-center border-1rpx border-#BC9264 rounded-8rpx border-solid bg-[#FFF5E9] px16rpx py6rpx text-24rpx text-#BC9264 font-semibold"
           class="mr16rpx flex items-center justify-center border-1rpx border-#BC9264 rounded-8rpx border-solid bg-[#FFF5E9] px16rpx py6rpx text-24rpx text-#BC9264 font-semibold"
@@ -143,45 +144,45 @@ async function getGoodsDetaile() {
         </view>
         </view>
       </view> -->
       </view> -->
 
 
-      <view class="mt20rpx flex items-center justify-between rounded-16rpx bg-white p24rpx">
-        <view class="flex items-center">
-          <view class="flex-shrink-0">
-            <view class="text-28rpx font-semibold">
-              {{ goodsInfo.brandName }}
-            </view>
-            <view class="mt16rpx text-24rpx text-#AAAAAA">
-              品牌
+        <view class="mt20rpx flex items-center justify-between rounded-16rpx bg-white p24rpx">
+          <view class="flex items-center">
+            <view class="flex-shrink-0">
+              <view class="text-28rpx font-semibold">
+                {{ goodsInfo.brandName }}
+              </view>
+              <view class="mt16rpx text-24rpx text-#AAAAAA">
+                品牌
+              </view>
             </view>
             </view>
           </view>
           </view>
           <view class="mx24rpx">
           <view class="mx24rpx">
             <wd-divider vertical color="#F0F0F0" />
             <wd-divider vertical color="#F0F0F0" />
           </view>
           </view>
-        </view>
-        <view class="flex items-center">
-          <view class="flex-shrink-0">
-            <view class="text-28rpx font-semibold">
-              {{ goodsInfo.weight }}
-            </view>
-            <view class="mt16rpx text-24rpx text-#AAAAAA">
-              重量
+          <view class="flex items-center">
+            <view class="flex-shrink-0">
+              <view class="text-28rpx font-semibold">
+                {{ goodsInfo.weight }}
+              </view>
+              <view class="mt16rpx text-24rpx text-#AAAAAA">
+                重量
+              </view>
             </view>
             </view>
           </view>
           </view>
           <view class="mx24rpx">
           <view class="mx24rpx">
             <wd-divider vertical color="#F0F0F0" />
             <wd-divider vertical color="#F0F0F0" />
           </view>
           </view>
-        </view>
-        <view class="flex items-center">
-          <view class="flex-shrink-0">
-            <view class="text-28rpx font-semibold">
-              {{ goodsInfo.weightUnit }}
-            </view>
-            <view class="mt16rpx text-24rpx text-#AAAAAA">
-              单位
+          <view class="flex items-center">
+            <view class="flex-shrink-0">
+              <view class="text-28rpx font-semibold">
+                {{ goodsInfo.weightUnit }}
+              </view>
+              <view class="mt16rpx text-24rpx text-#AAAAAA">
+                单位
+              </view>
             </view>
             </view>
           </view>
           </view>
+          <wd-icon name="chevron-right" size="22px" color="#AAAAAA" />
         </view>
         </view>
-        <wd-icon name="chevron-right" size="22px" color="#AAAAAA" />
-      </view>
       <!-- <view class="view-1 mt20rpx flex items-center rounded-16rpx bg-white p24rpx">
       <!-- <view class="view-1 mt20rpx flex items-center rounded-16rpx bg-white p24rpx">
         <view class="w-full flex items-center justify-between">
         <view class="w-full flex items-center justify-between">
           <view class="text-32rpx font-semibold">
           <view class="text-32rpx font-semibold">
@@ -239,15 +240,15 @@ async function getGoodsDetaile() {
           <view v-for="item, idx in goodsTabData" :key="idx" class="mr14rpx transition-all transition-duration-400 ease-in" :class="[currentTabGoods == idx ? 'rounded-12rpx w-40rpx h12rpx bg-[var(--them-color)]' : 'w12rpx h12rpx rounded-50% bg-#F0F0F0']" />
           <view v-for="item, idx in goodsTabData" :key="idx" class="mr14rpx transition-all transition-duration-400 ease-in" :class="[currentTabGoods == idx ? 'rounded-12rpx w-40rpx h12rpx bg-[var(--them-color)]' : 'w12rpx h12rpx rounded-50% bg-#F0F0F0']" />
         </view>
         </view>
       </view> -->
       </view> -->
-    </view>
+      </view>
 
 
-    <view class="view-2 mt20rpx bg-white">
-      <view class="p24rpx text-32rpx font-semibold">
-        商品详情
-        <rich-text :nodes="goodsContent" />
+      <view class="view-2 mt20rpx bg-white">
+        <view class="p24rpx text-32rpx font-semibold">
+          商品详情
+          <rich-text :nodes="goodsContent" />
+        </view>
       </view>
       </view>
-    </view>
-    <!-- <view class="view-3 mt28rpx flex items-center justify-center">
+      <!-- <view class="view-3 mt28rpx flex items-center justify-center">
       <view class="flex items-center">
       <view class="flex items-center">
         <image
         <image
           :src="`${StaticUrl}/goods-recommend.png`"
           :src="`${StaticUrl}/goods-recommend.png`"
@@ -262,50 +263,51 @@ async function getGoodsDetaile() {
         />
         />
       </view>
       </view>
     </view> -->
     </view> -->
-    <view class="h180rpx" />
-    <view class="ios shadow-fixed fixed bottom-0 left-0 w-full rounded-t-32rpx bg-white">
-      <view class="flex items-center justify-between px24rpx py20rpx">
-        <view class="mr36rpx" @click="router.replace({ name: 'xsb-homeTabbar' })">
-          <image
-            :src="`${StaticUrl}/goods-home.png`"
-            class="h44rpx w44rpx"
-          />
-          <view class="text-20rpx">
-            首页
-          </view>
-        </view>
-        <view class="mr36rpx">
-          <image
-            :src="`${StaticUrl}/goods-kf.png`"
-            class="h44rpx w44rpx"
-          />
-          <view class="text-20rpx">
-            客服
+      <view class="h180rpx" />
+      <view class="ios shadow-fixed fixed bottom-0 left-0 w-full rounded-t-32rpx bg-white">
+        <view class="flex items-center justify-between px24rpx py20rpx">
+          <view class="mr36rpx" @click="router.replace({ name: 'xsb-homeTabbar' })">
+            <image
+              :src="`${StaticUrl}/goods-home.png`"
+              class="h44rpx w44rpx"
+            />
+            <view class="text-20rpx">
+              首页
+            </view>
           </view>
           </view>
-        </view>
-        <view @click="router.replace({ name: 'xsb-homeTabbar', animationType: 'fade-out', params: { name: 'xsb-cart' } })">
-          <image
-            :src="`${StaticUrl}/goods-cart.png`"
-            class="h44rpx w44rpx"
-          />
-          <view class="text-20rpx">
-            购物车
+          <view class="mr36rpx">
+            <image
+              :src="`${StaticUrl}/goods-kf.png`"
+              class="h44rpx w44rpx"
+            />
+            <view class="text-20rpx">
+              客服
+            </view>
           </view>
           </view>
-        </view>
-        <view class="flex items-center">
-          <view class="w220rpx">
-            <wd-button hairline plain block>
-              加入购物车
-            </wd-button>
+          <view @click="router.replace({ name: 'xsb-homeTabbar', animationType: 'fade-out', params: { name: 'xsb-cart' } })">
+            <image
+              :src="`${StaticUrl}/goods-cart.png`"
+              class="h44rpx w44rpx"
+            />
+            <view class="text-20rpx">
+              购物车
+            </view>
           </view>
           </view>
-          <view class="ml20rpx w220rpx" @click="router.push({ name: 'common-confirmOrder' })">
-            <wd-button block class="w-full">
-              立即购买
-            </wd-button>
+          <view class="flex items-center">
+            <view class="w220rpx">
+              <wd-button hairline plain block>
+                加入购物车
+              </wd-button>
+            </view>
+            <view class="ml20rpx w220rpx" @click="router.push({ name: 'common-confirmOrder' })">
+              <wd-button block class="w-full">
+                立即购买
+              </wd-button>
+            </view>
           </view>
           </view>
         </view>
         </view>
       </view>
       </view>
-    </view>
+    </template>
   </view>
   </view>
 </template>
 </template>
 
 

+ 2 - 1
src/subPack-xsb/search/index.vue

@@ -17,6 +17,7 @@ const tabbarlist = ref([
 ])
 ])
 const activeTab = ref(0)
 const activeTab = ref(0)
 const { confirm: showConfirm } = useGlobalMessage()
 const { confirm: showConfirm } = useGlobalMessage()
+const { userInfo } = storeToRefs(useUserStore())
 
 
 const { data, send, isLastPage, page, error } = usePagination((pageNum, pageSize) => Apis.xsb.getSearchProductList({ data: {
 const { data, send, isLastPage, page, error } = usePagination((pageNum, pageSize) => Apis.xsb.getSearchProductList({ data: {
   keywords: searchText.value,
   keywords: searchText.value,
@@ -25,7 +26,7 @@ const { data, send, isLastPage, page, error } = usePagination((pageNum, pageSize
   priceSort: activeTab.value === 2 ? 'DESC' : '',
   priceSort: activeTab.value === 2 ? 'DESC' : '',
   salesNum: activeTab.value === 1 ? 'DESC' : '',
   salesNum: activeTab.value === 1 ? 'DESC' : '',
   shopId: 1,
   shopId: 1,
-  channelId: 1,
+  channelId: userInfo.value.channelId,
 } }), {
 } }), {
   immediate: false,
   immediate: false,
   data: resp => resp.list,
   data: resp => resp.list,