li.shaoyi 2 gadi atpakaļ
vecāks
revīzija
a87fe7f51e

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

@@ -114,7 +114,38 @@
 }
 
 /* 商品列表 */
-.g-goods-list {}
+.g-goods-list {
+    padding: 0 .2rem;
+
+    .goods {
+        background-color: #fff;
+        border-radius: .12rem;
+        overflow: hidden;
+
+        &-image {
+            font-size: 0;
+        }
+
+        &-info {
+            padding: .2rem;
+
+            &__title {
+                font-size: .26rem;
+                margin-bottom: .1rem;
+            }
+
+            &__price {
+                .unit {
+                    &::before {
+                        content: '¥';
+                    }
+
+                    color: red;
+                }
+            }
+        }
+    }
+}
 
 /* 订单列表 */
 .g-order-list {

+ 12 - 1
src/packages/mobile/components/modules/waterfall/index.less

@@ -1 +1,12 @@
-.app-waterfall {}
+.app-waterfall {
+    ul {
+        position: relative;
+
+        li {
+            position: absolute;
+            opacity: 0;
+            color: #333;
+            //transition: opacity .2s;
+        }
+    }
+}

+ 78 - 4
src/packages/mobile/components/modules/waterfall/index.vue

@@ -1,18 +1,92 @@
 <template>
     <div class="app-waterfall">
-        <div class="app-waterfall-item" v-for="(item, index) in dataList" :key="index">
-            <slot :item="item"></slot>
-        </div>
+        <ul ref="warterfallRef">
+            <li v-for="(item, index) in dataList" :key="index">
+                <slot :item="item"></slot>
+            </li>
+        </ul>
     </div>
 </template>
 
 <script lang="ts" setup>
-defineProps({
+import { shallowRef, watch, nextTick } from 'vue'
+
+const props = defineProps({
+    //数据列表
     dataList: {
         type: Array,
         default: () => ([])
+    },
+    //列数
+    column: {
+        type: Number,
+        default: 2
+    },
+    //间距
+    spacing: {
+        type: Number,
+        default: 10
     }
 })
+
+const warterfallRef = shallowRef<HTMLDivElement>()
+const total = shallowRef(0)
+const hightList: number[] = [] //瀑布流高度列表
+
+const render = () => {
+    nextTick(async () => {
+        const el = warterfallRef.value
+        if (el) {
+            const nodes = el.querySelectorAll('li')
+
+            for (let i = total.value; i < nodes.length; i++) {
+                const li = nodes[i]
+                const images = li.querySelectorAll('img')
+
+                // 等待所有图片加载完成
+                for (let n = 0; n < images.length; n++) {
+                    await new Promise<void>((resolve) => {
+                        if (images[n].complete) {
+                            resolve()
+                        } else {
+                            images[n].onload = () => {
+                                resolve()
+                            }
+                            images[n].onerror = () => {
+                                resolve()
+                            }
+                        }
+                    })
+                }
+
+                const space = (props.column - 1) * props.spacing // 总间距
+                const width = (el.offsetWidth - space) / props.column // 每列的宽度
+
+                li.style.width = width + 'px'
+                li.style.opacity = '1'
+
+                //判断是否首行
+                if (i < props.column) {
+                    li.style.top = '0'
+                    li.style.left = (width * i) + (props.spacing * i) + 'px'
+                    hightList.push(li.offsetHeight + props.spacing)
+                } 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
+                }
+            }
+
+            const maxHeight = Math.max(...hightList); // 获取数组中最大值
+            el.style.height = maxHeight + 'px'
+            total.value = nodes.length
+        }
+    })
+}
+
+watch(() => props.dataList, () => render())
 </script>
 
 <style lang="less">

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

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

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

@@ -19,6 +19,10 @@
             <img src="@mobile/assets/icons/cpjs.svg" />
             <span>预售竞拍</span>
           </li>
+          <li>
+            <img src="@mobile/assets/icons/cpjs.svg" />
+            <span>预售中签</span>
+          </li>
           <li @click="switchTab(2)">
             <img src="@mobile/assets/icons/cpjg.svg" />
             <span>订单转让</span>
@@ -33,6 +37,10 @@
             <img src="@mobile/assets/icons/wdrw.svg" />
             <span>订单挂牌</span>
           </li>
+          <li @click="routerTo('pricing-list')">
+            <img src="@mobile/assets/icons/ccwl.svg" />
+            <span>挂牌点价</span>
+          </li>
           <li @click="routerTo('spot-list')">
             <img src="@mobile/assets/icons/htzr.svg" />
             <span>现货贸易</span>

+ 1 - 1
src/packages/mobile/views/home/main/index.less

@@ -61,7 +61,7 @@
                 display: flex;
                 flex-direction: column;
                 align-items: center;
-                width: calc(~'100% / 3');
+                width: calc(~'100% / 4');
                 text-align: center;
 
                 img {

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

@@ -1,7 +1,7 @@
 .g-detail {
     &__banner {
         background-color: #ddd;
-        min-height: 3rem;
+        min-height: 4rem;
 
         .van-swipe-item {
             height: 4rem;

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

@@ -3,14 +3,13 @@
         <template #header>
             <app-navbar title="预售竞拍" :show-back-button="false" />
         </template>
-        <Swipe :autoplay="5000" indicator-color="white" lazy-render>
+        <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>
-        <div>正在抢购</div>
-        <div class="waterfall">
-            <div class="waterfall-item" v-for="(item, index) in startList" :key="index">
+        <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">
@@ -24,11 +23,11 @@
                         </div>
                     </div>
                 </div>
-            </div>
-        </div>
-        <div>发售历史</div>
-        <div class="waterfall">
-            <div class="waterfall-item" v-for="(item, index) in endList" :key="index">
+            </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">
@@ -42,16 +41,17 @@
                         </div>
                     </div>
                 </div>
-            </div>
-        </div>
+            </template>
+        </Waterfall>
     </app-view>
 </template>
 
 <script lang="ts" setup>
-import { Swipe, SwipeItem, Tag } from 'vant'
+import { Swipe, SwipeItem, 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'
 
 const { dataList: bannerList } = useRequest(queryPresaleAuctions, {
     params: {

+ 10 - 29
src/packages/mobile/views/presale/list/index.less

@@ -1,35 +1,16 @@
 .presale-list {
-    .waterfall {
-        display: flex;
-        flex-wrap: wrap;
-        padding: .12rem;
+    .banner {
+        background-color: #ddd;
+        min-height: 3rem;
 
-        &-item {
-            width: 50%;
-            padding: .12rem;
+        .van-swipe-item {
+            height: 3rem;
+            font-size: 0;
 
-            .goods {
-                background-color: #fff;
-                border-radius: .12rem;
-                overflow: hidden;
-
-                &-image {
-                    font-size: 0;
-                }
-
-                &-info {
-                    padding: .2rem;
-
-                    &__price {
-                        .unit {
-                            &::before {
-                                content: '¥';
-                            }
-
-                            color: red;
-                        }
-                    }
-                }
+            img {
+                width: 100%;
+                height: 100%;
+                object-fit: cover;
             }
         }
     }

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

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

+ 10 - 0
src/packages/mobile/views/pricing/list/Index.vue

@@ -0,0 +1,10 @@
+<template>
+    <app-view>
+        <template #header>
+            <app-navbar title="挂牌点价" />
+        </template>
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+</script>