li.shaoyi 2 年之前
父節點
當前提交
dfabba960d

+ 5 - 1
src/packages/mobile/assets/themes/global/global.less

@@ -115,7 +115,7 @@
 
 /* 商品列表 */
 .g-goods-list {
-    padding: 0 .2rem;
+    padding: .2rem;
 
     .goods {
         background-color: #fff;
@@ -123,6 +123,10 @@
         overflow: hidden;
 
         &-image {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            min-height: 2.4rem;
             font-size: 0;
         }
 

+ 15 - 0
src/packages/mobile/components/base/banner/index.less

@@ -0,0 +1,15 @@
+.app-banner {
+    background-color: #ddd;
+
+    .van-swipe {
+        &-item {
+            font-size: 0;
+
+            img {
+                width: 100%;
+                height: 100%;
+                object-fit: cover;
+            }
+        }
+    }
+}

+ 41 - 0
src/packages/mobile/components/base/banner/index.vue

@@ -0,0 +1,41 @@
+<template>
+    <div class="app-banner" :style="`min-height: ${swipeHeight};`">
+        <Swipe :autoplay="5000" indicator-color="white" lazy-render>
+            <SwipeItem v-for="(src, index) in dataList" :key="index" @click="$emit('click')"
+                :style="`height: ${swipeHeight};`">
+                <slot :src="src">
+                    <img :src="getFileUrl(src)" />
+                </slot>
+            </SwipeItem>
+        </Swipe>
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { PropType, computed } from 'vue'
+import { Swipe, SwipeItem } from 'vant'
+import { getFileUrl } from '@/filters'
+
+const props = defineProps({
+    //数据列表
+    dataList: {
+        type: Array as PropType<string[]>,
+        default: () => ([])
+    },
+    height: {
+        type: [Number, String],
+        default: 150,
+    }
+})
+
+const swipeHeight = computed(() => {
+    if (typeof props.height === 'number') {
+        return props.height + 'px'
+    }
+    return props.height
+})
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 0 - 0
src/packages/mobile/components/modules/waterfall/index.less → src/packages/mobile/components/base/waterfall/index.less


+ 8 - 8
src/packages/mobile/components/modules/waterfall/index.vue → src/packages/mobile/components/base/waterfall/index.vue

@@ -2,7 +2,7 @@
     <div class="app-waterfall">
         <ul ref="warterfallRef">
             <li v-for="(item, index) in dataList" :key="index">
-                <slot :item="item"></slot>
+                <slot :item="item">{{ item }}</slot>
             </li>
         </ul>
     </div>
@@ -23,7 +23,7 @@ const props = defineProps({
         default: 2
     },
     //间距
-    spacing: {
+    gap: {
         type: Number,
         default: 10
     }
@@ -59,7 +59,7 @@ const render = () => {
                     })
                 }
 
-                const space = (props.column - 1) * props.spacing // 总间距
+                const space = (props.column - 1) * props.gap // 总间距
                 const width = (el.offsetWidth - space) / props.column // 每列的宽度
 
                 li.style.width = width + 'px'
@@ -68,19 +68,19 @@ const render = () => {
                 //判断是否首行
                 if (i < props.column) {
                     li.style.top = '0'
-                    li.style.left = (width * i) + (props.spacing * i) + 'px'
-                    hightList.push(li.offsetHeight + props.spacing)
+                    li.style.left = (width * i) + (props.gap * i) + 'px'
+                    hightList.push(li.offsetHeight + props.gap)
                 } else {
                     const minHeight = Math.min(...hightList) // 获取数组中最小值
                     const index = hightList.findIndex((e) => e === minHeight) // 最小值的索引位置
                     li.style.top = minHeight + 'px'
-                    li.style.left = (width * index) + (props.spacing * index) + 'px'
-                    hightList[index] += li.offsetHeight + props.spacing
+                    li.style.left = (width * index) + (props.gap * index) + 'px'
+                    hightList[index] += li.offsetHeight + props.gap
                 }
             }
 
             const maxHeight = Math.max(...hightList); // 获取数组中最大值
-            el.style.height = maxHeight + 'px'
+            el.style.height = (maxHeight - props.gap) + 'px'
             total.value = nodes.length
         }
     })

+ 16 - 0
src/packages/mobile/router/index.ts

@@ -241,6 +241,22 @@ const routes: Array<RouteRecordRaw> = [
     ],
   },
   {
+    path: '/ballot',
+    component: Page,
+    children: [
+      {
+        path: 'list',
+        name: 'ballot-list',
+        component: () => import('../views/ballot/list/Index.vue'),
+      },
+      {
+        path: 'detail',
+        name: 'ballot-detail',
+        component: () => import('../views/ballot/detail/Index.vue'),
+      },
+    ],
+  },
+  {
     path: '/bank',
     component: Page,
     children: [

+ 10 - 0
src/packages/mobile/views/ballot/detail/Index.vue

@@ -0,0 +1,10 @@
+<template>
+    <app-view>
+        <template #header>
+            <app-navbar title="商品详情" />
+        </template>
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+</script>

+ 83 - 0
src/packages/mobile/views/ballot/list/Index.vue

@@ -0,0 +1,83 @@
+<template>
+    <app-view class="ballot-list">
+        <template #header>
+            <app-navbar title="预售中签" />
+        </template>
+        <Banner :data-list="bannerList" />
+        <Waterfall class="g-goods-list" :data-list="startList">
+            <template #default="{ item }">
+                <div class="goods"
+                    @click="$router.push({ name: 'presale-detail', params: { item: JSON.stringify(item) } })">
+                    <div class="goods-image">
+                        <img :src="getFileUrl(item.attachmenturl)" />
+                    </div>
+                    <div class="goods-info">
+                        <div class="goods-info__title">{{ item.goodsname }}</div>
+                        <div class="goods-info__price">
+                            <Tag type="danger">卖价</Tag>
+                            <span class="unit">{{ item.startprice }}</span>
+                        </div>
+                    </div>
+                </div>
+            </template>
+        </Waterfall>
+        <Divider>发售历史</Divider>
+        <Waterfall class="g-goods-list" :data-list="endList">
+            <template #default="{ item }">
+                <div class="goods"
+                    @click="$router.push({ name: 'presale-detail', params: { item: JSON.stringify(item) } })">
+                    <div class="goods-image">
+                        <img :src="getFileUrl(item.attachmenturl)" />
+                    </div>
+                    <div class="goods-info">
+                        <div class="goods-info__title">{{ item.goodsname }}</div>
+                        <div class="goods-info__price">
+                            <Tag type="danger">卖价</Tag>
+                            <span class="unit">{{ item.refprice }}</span>
+                        </div>
+                    </div>
+                </div>
+            </template>
+        </Waterfall>
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef } from 'vue'
+import { Tag, Divider } from 'vant'
+import { getFileUrl } from '@/filters'
+import { useRequest } from '@/hooks/request'
+import { queryPresaleAuctions } from '@/services/api/presale'
+import Banner from '@mobile/components/base/banner/index.vue'
+import Waterfall from '@mobile/components/base/waterfall/index.vue'
+
+const bannerList = shallowRef<string[]>([])
+
+useRequest(queryPresaleAuctions, {
+    params: {
+        presalemode: 5,
+        presalestatusstr: '1'
+    },
+    onSuccess: (res) => {
+        bannerList.value = res.data.map((e) => e.bannerpicurl)
+    }
+})
+
+const { dataList: startList } = useRequest(queryPresaleAuctions, {
+    params: {
+        presalemode: 5,
+        presalestatusstr: '2'
+    },
+})
+
+const { dataList: endList } = useRequest(queryPresaleAuctions, {
+    params: {
+        presalemode: 5,
+        presalestatusstr: '3,4'
+    },
+})
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 3 - 0
src/packages/mobile/views/ballot/list/index.less

@@ -0,0 +1,3 @@
+.ballot-list {
+    --van-divider-margin: 0;
+}

+ 1 - 1
src/packages/mobile/views/home/main/Index.vue

@@ -19,7 +19,7 @@
             <img src="@mobile/assets/icons/cpjs.svg" />
             <span>预售竞拍</span>
           </li>
-          <li>
+          <li @click="routerTo('ballot-list')">
             <img src="@mobile/assets/icons/cpjs.svg" />
             <span>预售中签</span>
           </li>

+ 4 - 7
src/packages/mobile/views/presale/detail/Index.vue

@@ -3,11 +3,7 @@
         <template #header>
             <app-navbar title="商品详情" />
         </template>
-        <Swipe class="g-detail__banner" :autoplay="5000" indicator-color="white" lazy-render>
-            <SwipeItem v-for="(url, index) in detailBanners" :key="index">
-                <img :src="url" />
-            </SwipeItem>
-        </Swipe>
+        <Banner :data-list="detailBanners" height="4rem" />
         <div class="g-detail__info">
             <div class="pricebar">
                 <div class="pricebar-left">
@@ -71,10 +67,11 @@
 
 <script lang="ts" setup>
 import { computed, defineAsyncComponent } from 'vue'
-import { Swipe, SwipeItem, Button, Tag } from 'vant'
+import { Button, Tag } from 'vant'
 import { getFileUrl, parsePercent } from '@/filters'
 import { useComponent } from '@/hooks/component'
 import { useNavigation } from '@/hooks/navigation'
+import Banner from '@mobile/components/base/banner/index.vue'
 
 const componentMap = new Map<string, unknown>([
     ['delisting', defineAsyncComponent(() => import('./components/delisting/index.vue'))], // 摘牌
@@ -88,7 +85,7 @@ const detail: Model.PresaleAuctionsRsp = JSON.parse(qs.toString() || '{}')
 // 商品banner
 const detailBanners = computed(() => {
     const bannerpicurl = detail.bannerpicurl ?? ''
-    return bannerpicurl?.split(',').map((path) => getFileUrl(path))
+    return bannerpicurl?.split(',').map((path) => path)
 })
 
 // 预售定金

+ 0 - 16
src/packages/mobile/views/presale/detail/index.less

@@ -1,20 +1,4 @@
 .g-detail {
-    &__banner {
-        background-color: #ddd;
-        min-height: 4rem;
-
-        .van-swipe-item {
-            height: 4rem;
-            font-size: 0;
-
-            img {
-                width: 100%;
-                height: 100%;
-                object-fit: cover;
-            }
-        }
-    }
-
     &__info {
         background-color: #fff;
         border-bottom-left-radius: .2rem;

+ 12 - 9
src/packages/mobile/views/presale/list/Index.vue

@@ -3,11 +3,7 @@
         <template #header>
             <app-navbar title="预售竞拍" :show-back-button="false" />
         </template>
-        <Swipe class="banner" :autoplay="5000" indicator-color="white" lazy-render>
-            <SwipeItem v-for="(item, index) in bannerList" :key="index">
-                <img :src="getFileUrl(item.bannerpicurl)" />
-            </SwipeItem>
-        </Swipe>
+        <Banner :data-list="bannerList" />
         <Waterfall class="g-goods-list" :data-list="startList">
             <template #default="{ item }">
                 <div class="goods"
@@ -37,7 +33,7 @@
                         <div class="goods-info__title">{{ item.goodsname }}</div>
                         <div class="goods-info__price">
                             <Tag type="danger">预售价</Tag>
-                            <span class="unit">{{ item.startprice }}</span>
+                            <span class="unit">{{ item.refprice }}</span>
                         </div>
                     </div>
                 </div>
@@ -47,17 +43,24 @@
 </template>
 
 <script lang="ts" setup>
-import { Swipe, SwipeItem, Tag, Divider } from 'vant'
+import { shallowRef } from 'vue'
+import { Tag, Divider } from 'vant'
 import { getFileUrl } from '@/filters'
 import { useRequest } from '@/hooks/request'
 import { queryPresaleAuctions } from '@/services/api/presale'
-import Waterfall from '@mobile/components/modules/waterfall/index.vue'
+import Banner from '@mobile/components/base/banner/index.vue'
+import Waterfall from '@mobile/components/base/waterfall/index.vue'
+
+const bannerList = shallowRef<string[]>([])
 
-const { dataList: bannerList } = useRequest(queryPresaleAuctions, {
+useRequest(queryPresaleAuctions, {
     params: {
         presalemode: 4,
         presalestatus: 1
     },
+    onSuccess: (res) => {
+        bannerList.value = res.data.map((e) => e.bannerpicurl)
+    }
 })
 
 const { dataList: startList } = useRequest(queryPresaleAuctions, {

+ 1 - 15
src/packages/mobile/views/presale/list/index.less

@@ -1,17 +1,3 @@
 .presale-list {
-    .banner {
-        background-color: #ddd;
-        min-height: 3rem;
-
-        .van-swipe-item {
-            height: 3rem;
-            font-size: 0;
-
-            img {
-                width: 100%;
-                height: 100%;
-                object-fit: cover;
-            }
-        }
-    }
+    --van-divider-margin: 0;
 }

+ 1 - 1
src/services/api/presale/index.ts

@@ -1,4 +1,4 @@
-import { useLoginStore, useAccountStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import http from '@/services/http'
 import { RequestConfig } from '@/services/http/types'
 

+ 1 - 0
src/types/model/presale.d.ts

@@ -3,6 +3,7 @@ declare namespace Model {
     interface PresaleAuctionsReq {
         presalemode: number; // 预售模式 - 1:一口价 2:大宗式竞拍 3:挂牌预售(HSBY)
         presalestatus?: number; // 预售状态 - 1:未开始 2:预售中 3:已结束
+        presalestatusstr?: string; // 预售状态 - 1:未开始 2:预售中 3:已结束 4:已关闭 (多个逗号分隔)
         page?: number; // 页码
         pagesize?: number; // 每页条数
     }