li.shaoyi hai 1 ano
pai
achega
6baddba49f

+ 2 - 6
src/packages/mobile/components/base/waterfall/index.vue

@@ -55,12 +55,8 @@ const render = () => {
                         if (images[n].complete) {
                             resolve()
                         } else {
-                            images[n].onload = () => {
-                                resolve()
-                            }
-                            images[n].onerror = () => {
-                                resolve()
-                            }
+                            images[n].onload = () => resolve()
+                            images[n].onerror = () => resolve()
                         }
                     })
                 }

+ 114 - 0
src/packages/mobile/components/base/waterfall/next.vue

@@ -0,0 +1,114 @@
+<template>
+    <div class="app-waterfall">
+        <ul ref="warterfallRef" v-if="dataList.length">
+            <li v-for="(item, index) in dataList" :key="index">
+                <slot :item="item">{{ item }}</slot>
+            </li>
+        </ul>
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, watch, nextTick, onActivated, onMounted } from 'vue'
+
+const props = defineProps({
+    //数据列表
+    dataList: {
+        type: Array,
+        default: () => ([])
+    },
+    //列数
+    column: {
+        type: Number,
+        default: 2
+    },
+    //间距
+    gap: {
+        type: Number,
+        default: 10
+    }
+})
+
+const warterfallRef = shallowRef<HTMLDivElement>()
+
+const state: { total: number; hightList: number[]; } = {
+    total: 0,
+    hightList: [] //瀑布流高度列表
+}
+
+const render = () => {
+    state.total = 0
+    state.hightList = []
+
+    nextTick(async () => {
+        const el = warterfallRef.value
+        if (el) {
+            const nodes = el.querySelectorAll('li')
+
+            for (let i = state.total; 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()
+                        }
+                    })
+                }
+
+                if (!el.offsetWidth) {
+                    // 在 keepalive 组件下,如果在数据未全部加载出来之前跳转了页面,这会导致元素获取不到宽度,从而影响瀑布流布局的正常显示
+                    // 所以需要停止还未加载完成的数据渲染,待页面重新打开后继续加载
+                    break
+                }
+
+                const space = (props.column - 1) * props.gap // 总间距
+                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.gap * i) + 'px'
+                    state.hightList.push(li.offsetHeight + props.gap)
+                } else {
+                    const minHeight = Math.min(...state.hightList) // 获取数组中最小值
+                    const index = state.hightList.findIndex((e) => e === minHeight) // 最小值的索引位置
+                    li.style.top = minHeight + 'px'
+                    li.style.left = (width * index) + (props.gap * index) + 'px'
+                    state.hightList[index] += li.offsetHeight + props.gap
+                }
+
+                state.total++
+            }
+
+            const maxHeight = Math.max(...state.hightList); // 获取数组中最大值
+            el.style.height = (maxHeight - props.gap) + 'px'
+        }
+    })
+}
+
+watch(() => props.dataList, () => render())
+
+onMounted(() => {
+    render()
+
+    onActivated(() => {
+        // 对未完成加载的数据进行渲染
+        if (props.dataList.length > state.total) {
+            render()
+        }
+    })
+})
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 1 - 1
src/packages/tss/router/index.ts

@@ -193,7 +193,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'capital',
         name: 'bank-capital',
-        component: () => import('@mobile/views/bank/capital/index.vue'),
+        component: () => import('../views/bank/capital/index.vue'),
       }
     ],
   },

+ 35 - 0
src/packages/tss/views/bank/capital/index.vue

@@ -0,0 +1,35 @@
+<template>
+    <app-view>
+        <template #header>
+            <app-navbar :title="$t('banksign.capital.title2')" />
+        </template>
+        <CellGroup v-for="(item, index) in accountStore.accountComputedList" :key="index">
+            <Cell :title="$t('account.accountid')" :value="item.accountid" />
+            <Cell :title="$t('account.balance2')" :value="formatDecimal(item.balance)" />
+            <Cell :title="$t('account.currentbalance')" :value="formatDecimal(item.currentbalance)" />
+            <Cell :title="$t('account.netWorth')" :value="formatDecimal(item.netvalue)" />
+            <Cell :title="$t('account.availableFunds2')" :value="formatDecimal(item.avaiableMoney)" />
+            <Cell :title="$t('account.usedMargin2')" :value="formatDecimal(item.usedmargin)" />
+            <Cell :title="$t('account.freezeMargin2')" :value="formatDecimal(item.freezeMargin)" />
+            <Cell :title="$t('account.profitLoss')">
+                <template #value>
+                    <span :class="handlePriceColor(item.profitLoss)">{{ formatDecimal(item.profitLoss) }}</span>
+                </template>
+            </Cell>
+            <Cell :title="$t('account.inamount')" :value="formatDecimal(item.inamount)" />
+            <Cell :title="$t('account.outamount')" :value="formatDecimal(item.outamount)" />
+            <Cell :title="$t('account.closepl')" :value="formatDecimal(item.closepl)" />
+            <Cell :title="$t('account.paycharge')" :value="formatDecimal(item.paycharge)" />
+            <Cell :title="$t('account.tradestatus')" :value="getTradeStatusName(item.tradestatus)" />
+        </CellGroup>
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { CellGroup, Cell } from 'vant'
+import { formatDecimal, handlePriceColor } from '@/filters'
+import { getTradeStatusName } from '@/constants/order'
+import { useAccountStore } from '@/stores'
+
+const accountStore = useAccountStore()
+</script>

+ 3 - 1
src/packages/tss/views/product/list/components/waterfall-list/index.vue

@@ -3,7 +3,8 @@
         <template #default="{ item }">
             <div class="goods" @click="rowClick(item)">
                 <div class="goods-image">
-                    <img :src="getFileUrl(item.pictureurl)" />
+                    <img :src="getFileUrl(item.pictureurl)" v-if="item.pictureurl" />
+                    <Image width="100%" height="160px" v-else />
                 </div>
                 <div class="goods-info">
                     <div class="goods-info__title">{{ item.goodscode }}</div>
@@ -18,6 +19,7 @@
 
 <script lang="ts" setup>
 import { PropType } from 'vue'
+import { Image } from 'vant'
 import { getFileUrl } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
 import { BuyOrSell, BuildType } from '@/constants/order'

+ 10 - 2
src/packages/tss/views/product/list/index.vue

@@ -9,7 +9,7 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, computed, onActivated } from 'vue'
+import { shallowRef, onMounted, computed, onActivated } from 'vue'
 import { Empty } from 'vant'
 import { useNavigation } from '@mobile/router/navigation'
 import { useUserStore, useFuturesStore } from '@/stores'
@@ -27,8 +27,16 @@ const groupInfo = computed(() => {
     return list.find((e) => e.goodsgroupid === groupId)
 })
 
-onActivated(() => {
+const getGoodsList = () => {
     const list = futuresStore.quotationList.filter((e) => e.goodsgroupid === groupId)
     dataList.value = list.map((e) => ({ ...e }))
+}
+
+futuresStore.onDataCompleted(() => {
+    getGoodsList()
+})
+
+onMounted(() => {
+    onActivated(() => getGoodsList())
 })
 </script>