li.shaoyi 1 рік тому
батько
коміт
8b2dd62ca4
59 змінених файлів з 1023 додано та 1984 видалено
  1. 2 2
      oem/sbyj/config/appconfig.json
  2. 1 1
      public/config/appconfig.json
  3. 214 0
      src/business/market/index.ts
  4. 9 40
      src/packages/gcszt/router/index.ts
  5. 0 35
      src/packages/gcszt/views/home/Index.vue
  6. 0 67
      src/packages/gcszt/views/home/main/Index.vue
  7. 0 89
      src/packages/gcszt/views/home/main/index.less
  8. 12 65
      src/packages/gstj/router/index.ts
  9. 0 41
      src/packages/gstj/views/home/Index.vue
  10. 0 67
      src/packages/gstj/views/home/main/Index.vue
  11. 0 89
      src/packages/gstj/views/home/main/index.less
  12. 2 1
      src/packages/mobile/components/base/tabbar/types.ts
  13. 0 85
      src/packages/mobile/components/layouts/home/index.vue
  14. 1 1
      src/packages/mobile/components/modules/hqchart/candlestick/index.less
  15. 1 2
      src/packages/mobile/components/modules/hqchart/timeline/index.less
  16. 5 5
      src/packages/mobile/components/modules/hqchart/timeline/index.vue
  17. 27 235
      src/packages/mobile/router/index.ts
  18. 2 5
      src/packages/mobile/router/navigation.ts
  19. 222 0
      src/packages/mobile/router/section.ts
  20. 14 5
      src/packages/mobile/views/ballot/list/Index.vue
  21. 17 12
      src/packages/mobile/views/goods/list/Index.vue
  22. 177 33
      src/packages/mobile/views/home/Index.vue
  23. 1 1
      src/packages/mobile/views/home/index.less
  24. 80 50
      src/packages/mobile/views/home/main/Index.vue
  25. 7 13
      src/packages/mobile/views/home/main/index.less
  26. 1 1
      src/packages/mobile/views/market/detail/Index.vue
  27. 10 4
      src/packages/mobile/views/market/list/Index.vue
  28. 16 3
      src/packages/mobile/views/presale/list/Index.vue
  29. 1 1
      src/packages/mobile/views/pricing/detail/Index.vue
  30. 16 3
      src/packages/mobile/views/pricing/list/Index.vue
  31. 11 3
      src/packages/mobile/views/spot/list/Index.vue
  32. 10 4
      src/packages/mobile/views/swap/list/Index.vue
  33. 16 3
      src/packages/mobile/views/transfer/list/Index.vue
  34. 1 1
      src/packages/pc/views/footer/goods/trade/index.vue
  35. 12 26
      src/packages/pc/views/market/trade/index.vue
  36. 1 1
      src/packages/pc/views/query/trade/goods/history/index.vue
  37. 1 1
      src/packages/pc/views/query/trade/goods/list/index.vue
  38. 1 1
      src/packages/qdhs/views/goods/detail/index.vue
  39. 61 3
      src/packages/qdhs/views/home/Index.vue
  40. 14 0
      src/packages/qdhs/views/home/index.less
  41. 8 32
      src/packages/qxst/router/index.ts
  42. 0 29
      src/packages/qxst/views/home/Index.vue
  43. 0 67
      src/packages/qxst/views/home/main/Index.vue
  44. 0 89
      src/packages/qxst/views/home/main/index.less
  45. 1 1
      src/packages/sbyj/views/market/detail/index.vue
  46. 1 1
      src/packages/sbyj/views/order/close/index.vue
  47. 19 75
      src/packages/tc/router/index.ts
  48. 0 41
      src/packages/tc/views/home/Index.vue
  49. 0 67
      src/packages/tc/views/home/main/Index.vue
  50. 0 123
      src/packages/tc/views/home/main/index.less
  51. 8 58
      src/packages/tjmd/router/index.ts
  52. 0 41
      src/packages/tjmd/views/home/Index.vue
  53. 9 17
      src/packages/tjmd/views/home/main/Index.vue
  54. 9 82
      src/packages/zrwyt/router/index.ts
  55. 0 41
      src/packages/zrwyt/views/home/Index.vue
  56. 0 96
      src/packages/zrwyt/views/home/main/Index.vue
  57. 0 123
      src/packages/zrwyt/views/home/main/index.less
  58. 1 1
      src/services/api/market/index.ts
  59. 1 1
      src/types/model/market.d.ts

+ 2 - 2
oem/sbyj/config/appconfig.json

@@ -1,8 +1,8 @@
 {
   "appId": "com.muchinfo.sbyj",
   "appName": "水贝亿爵",
-  "version": "1.0.3",
-  "versionCode": "100003",
+  "version": "1.0.4",
+  "versionCode": "100004",
   "apiUrl": "http://192.168.31.171:8080/cfg?key=test_171",
   "tradeChannel": "ws",
   "modules": [

+ 1 - 1
public/config/appconfig.json

@@ -1,6 +1,6 @@
 {
   "appId": "com.muchinfo.app",
-  "appName": "多元世纪交易中心",
+  "appName": "多元世纪",
   "version": "1.0.5",
   "versionCode": "10005",
   "apiUrl": "http://192.168.31.204:8080/cfg?key=test_204",

+ 214 - 0
src/business/market/index.ts

@@ -0,0 +1,214 @@
+import { shallowRef, computed } from 'vue'
+import { RouteRecordRaw } from 'vue-router'
+import { useUserStore } from '@/stores'
+import { getMarketSections } from '@/services/api/market'
+
+// 待优化-----考虑转换成动态路由
+export function useMarketSection(onReady?: () => void) {
+    const userStore = useUserStore()
+    const dataList = shallowRef<Model.MarketSectionsRsp[]>([])
+    const routes: RouteRecordRaw[] = [] // 动态路由列表
+
+    // 板块列表
+    const marketSections = computed(() => {
+        const idSet = new Set(userStore.userData.markets.map((e) => e.marketid.toString()))
+        const sections: Model.MarketSectionsRsp[] = JSON.parse(JSON.stringify(dataList.value))
+
+        return sections.filter((item) => {
+            // 过滤掉没有市场权限的板块
+            item.marketsectionconfignews = item.marketsectionconfignews.reduce<Model.Marketsectionconfignew[]>((pre, cur) => {
+                const arr = cur.marketids.split(',')
+                cur.marketids = arr.filter((id) => idSet.has(id)).join(',')
+                if (cur.marketids) {
+                    pre.push(cur)
+                }
+                return pre
+            }, [])
+            return item.marketsectionconfignews.length
+        })
+    })
+
+    // 所有市场板块
+    const allMarket = computed(() => marketSections.value.reduce<Model.Marketsectionconfignew[]>((pre, cur) => [...pre, ...cur.marketsectionconfignews], []))
+
+    getMarketSections().then((res) => {
+        dataList.value = res.data
+    }).finally(() => {
+
+        // allMarket.value.forEach((item) => {
+        //     const routeName = `section-${item.marketsectionid}-${item.orderindex}`
+        //     const baseRoute: RouteRecordRaw = {
+        //         path: routeName,
+        //         name: routeName,
+        //         component: import('@mobile/components/layouts/page/index.vue'),
+        //         children: []
+        //     }
+        //     const props = {
+        //         title: item.displayname,
+        //         marketids: item.marketids
+        //     }
+
+        //     switch (item.trademode) {
+        //         case 10:
+        //             baseRoute.children = [
+        //                 {
+        //                     path: 'list',
+        //                     name: routeName + '-list',
+        //                     component: () => import('@mobile/views/pricing/list/Index.vue'),
+        //                     props
+        //                 },
+        //                 {
+        //                     path: 'detail',
+        //                     name: routeName + '-detail',
+        //                     component: () => import('@mobile/views/pricing/detail/Index.vue'),
+        //                 }
+        //             ]
+        //             routes.push(baseRoute)
+        //             break
+        //         case 17:
+        //             baseRoute.children = [
+        //                 {
+        //                     path: 'list',
+        //                     name: routeName + '-list',
+        //                     component: () => import('@mobile/views/spot/list/Index.vue'),
+        //                     props
+        //                 },
+        //                 {
+        //                     path: 'detail',
+        //                     name: routeName + '-detail',
+        //                     component: () => import('@mobile/views/spot/detail/Index.vue'),
+        //                 },
+        //                 {
+        //                     path: 'add',
+        //                     name: routeName + '-add',
+        //                     component: () => import('@mobile/views/spot/add/index.vue'),
+        //                 }
+        //             ]
+        //             routes.push(baseRoute)
+        //             break
+        //         case 46:
+        //             baseRoute.children = [
+        //                 {
+        //                     path: 'list',
+        //                     name: routeName + '-list',
+        //                     component: () => import('@mobile/views/swap/list/Index.vue'),
+        //                     props
+        //                 },
+        //                 {
+        //                     path: 'detail',
+        //                     name: routeName + '-detail',
+        //                     component: () => import('@mobile/views/swap/detail/Index.vue'),
+        //                 },
+        //             ]
+        //             routes.push(baseRoute)
+        //             break
+        //         case 48:
+        //             baseRoute.children = [
+        //                 {
+        //                     path: 'list',
+        //                     name: routeName + '-list',
+        //                     component: () => import('@mobile/views/presale/list/Index.vue'),
+        //                     props
+        //                 },
+        //                 {
+        //                     path: 'detail',
+        //                     name: routeName + '-detail',
+        //                     component: () => import('@mobile/views/presale/detail/Index.vue'),
+        //                 },
+        //             ]
+        //             routes.push(baseRoute)
+        //             break
+        //         case 49:
+        //             baseRoute.children = [
+        //                 {
+        //                     path: 'list',
+        //                     name: routeName + '-list',
+        //                     component: () => import('@mobile/views/transfer/list/Index.vue'),
+        //                     props
+        //                 },
+        //                 {
+        //                     path: 'detail',
+        //                     name: routeName + '-detail',
+        //                     component: () => import('@mobile/views/transfer/detail/Index.vue'),
+        //                 },
+        //                 {
+        //                     path: 'detail2',
+        //                     name: routeName + '-detail2',
+        //                     component: () => import('@mobile/views/transfer/detail2/index.vue'),
+        //                 },
+        //                 {
+        //                     path: 'delisting',
+        //                     name: routeName + '-delisting',
+        //                     component: () => import('@mobile/views/transfer/delisting/Index.vue'),
+        //                 },
+        //             ]
+        //             routes.push(baseRoute)
+        //             break
+        //         case 16:
+        //         case 50:
+        //             baseRoute.children = [
+        //                 {
+        //                     path: 'list',
+        //                     name: routeName + '-list',
+        //                     component: () => import('@mobile/views/goods/list/Index.vue'),
+        //                     props
+        //                 },
+        //                 {
+        //                     path: 'detail',
+        //                     name: routeName + '-detail',
+        //                     component: () => import('@mobile/views/goods/detail/Index.vue'),
+        //                 },
+        //                 {
+        //                     path: 'trade',
+        //                     name: routeName + '-trade',
+        //                     component: () => import('@mobile/views/goods/trade/index.vue'),
+        //                 },
+        //             ]
+        //             routes.push(baseRoute)
+        //             break
+        //         case 51:
+        //             baseRoute.children = [
+        //                 {
+        //                     path: 'list',
+        //                     name: routeName + '-list',
+        //                     component: () => import('@mobile/views/ballot/list/Index.vue'),
+        //                     props
+        //                 },
+        //                 {
+        //                     path: 'detail',
+        //                     name: routeName + '-detail',
+        //                     component: () => import('@mobile/views/ballot/detail/Index.vue'),
+        //                 },
+        //             ]
+        //             routes.push(baseRoute)
+        //             break
+        //         case 99:
+        //             baseRoute.children = [
+        //                 {
+        //                     path: 'list',
+        //                     name: routeName + '-list',
+        //                     component: () => import('@mobile/views/market/list/Index.vue'),
+        //                     props
+        //                 },
+        //                 {
+        //                     path: 'detail',
+        //                     name: routeName + '-detail',
+        //                     component: () => import('@mobile/views/market/detail/Index.vue'),
+        //                 },
+        //             ]
+        //             routes.push(baseRoute)
+        //             break
+        //     }
+        // })
+
+        // console.log(routes)
+
+        onReady && onReady()
+    })
+
+    return {
+        marketSections,
+        allMarket,
+        routes
+    }
+}

+ 9 - 40
src/packages/gcszt/router/index.ts

@@ -1,6 +1,7 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import { useLoginStore } from '@/stores'
 import { clearPending } from '@/services/http/pending'
+import { homeRoutes, pageRoutes } from '@mobile/router/section'
 import service from '@/services'
 import Page from '@mobile/components/layouts/page/index.vue'
 import animateRouter from '@mobile/router/animateRouter'
@@ -31,42 +32,25 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: '',
         name: 'home',
-        component: () => import('../views/home/Index.vue'),
+        component: () => import('@mobile/views/home/Index.vue'),
         children: [
           {
             path: '',
             name: 'home-index',
-            component: () => import('../views/home/main/Index.vue'),
+            component: () => import('@mobile/views/home/main/Index.vue'),
             meta: {
               ignoreAuth: true,
             },
           },
           {
-            path: '50103',
-            name: 'home-50103',
-            component: () => import('@mobile/views/goods/list/Index.vue'),
-            props: {
-              title: '周清挂牌',
-              marketId: 50103
-            }
-          },
-          {
-            path: '50104',
-            name: 'home-50104',
-            component: () => import('@mobile/views/goods/list/Index.vue'),
-            props: {
-              title: '月清挂牌',
-              marketId: 50104
-            }
-          },
-          {
             path: 'mine',
             name: 'home-mine',
             component: () => import('../views/mine/Index.vue'),
-          }
+          },
+          ...homeRoutes
         ]
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/user',
@@ -158,22 +142,6 @@ const routes: Array<RouteRecordRaw> = [
     ],
   },
   {
-    path: '/goods',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'goods-detail',
-        component: () => import('@mobile/views/goods/detail/Index.vue'),
-      },
-      {
-        path: 'trade',
-        name: 'goods-trade',
-        component: () => import('@mobile/views/goods/trade/index.vue'),
-      },
-    ],
-  },
-  {
     path: '/bank',
     component: Page,
     children: [
@@ -302,7 +270,8 @@ const routes: Array<RouteRecordRaw> = [
         },
       },
     ]
-  }
+  },
+  ...pageRoutes
 ]
 
 const router = animateRouter.create({

+ 0 - 35
src/packages/gcszt/views/home/Index.vue

@@ -1,35 +0,0 @@
-<template>
-  <LayoutHome :tabs="tabList" ios-update-url="" />
-</template>
-
-<script lang="ts" setup>
-import { Tabbar } from '@mobile/components/base/tabbar/types'
-import LayoutHome from '@mobile/components/layouts/home/index.vue'
-
-const tabList: Tabbar[] = [
-  {
-    name: 'home-index',
-    label: '首页',
-    icon: 'g-icon-home--line',
-    activeIcon: 'g-icon-home--fill',
-  },
-  {
-    name: 'home-50103',
-    label: '周清挂牌',
-    icon: 'g-icon-listing--line',
-    activeIcon: 'g-icon-listing--fill',
-  },
-  {
-    name: 'home-50104',
-    label: '月清挂牌',
-    icon: 'g-icon-listing--line',
-    activeIcon: 'g-icon-listing--fill',
-  },
-  {
-    name: 'home-mine',
-    label: '我的',
-    icon: 'g-icon-mine--line',
-    activeIcon: 'g-icon-mine--fill',
-  }
-]
-</script>

+ 0 - 67
src/packages/gcszt/views/home/main/Index.vue

@@ -1,67 +0,0 @@
-<template>
-  <app-view class="home-main">
-    <template #header>
-      <app-navbar :title="globalStore.getSystemInfo('appName')" :show-back-button="false" />
-    </template>
-    <Banner :data-list="topBanners" />
-    <PullRefresh class="home-main__container" v-model="refreshing" @refresh="onRefresh">
-      <app-block>
-        <Cell title="通知公告" value="更多" :to="{ name: 'notice-list' }" icon="volume" is-link />
-      </app-block>
-      <app-block class="home-main__news">
-        <CellGroup class="article">
-          <Cell class="home-main__titlebar" title="市场资讯" value="更多" icon="fire" :to="{ name: 'news-list' }" is-link />
-          <template v-for="(item, index) in newsList" :key="index">
-            <Cell class="article-item" :title="item.title" :value="formatDate(item.publishdate, 'MM/DD')"
-              :to="{ name: 'news-detail', query: { id: item.id } }" />
-          </template>
-        </CellGroup>
-      </app-block>
-    </PullRefresh>
-  </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from "vue";
-import { Cell, CellGroup, PullRefresh } from "vant";
-import { formatDate } from "@/filters";
-import { queryImageConfigs } from "@/services/api/common";
-import { queryNewTitles } from "@/services/api/news";
-import { useGlobalStore } from '@/stores'
-import Banner from '@mobile/components/base/banner/index.vue'
-
-const globalStore = useGlobalStore()
-const refreshing = shallowRef(false); // 是否处于加载中状态
-const topBanners = shallowRef<string[]>([]); // 轮播图列表
-const newsList = shallowRef<Model.NewTitlesRsp[]>([]); // 资讯列表
-
-// 下拉刷新
-const onRefresh = () => {
-  if (!topBanners.value.length) {
-    queryImageConfigs({
-      data: {
-        imageType: 1,
-      }
-    }).then((res) => {
-      topBanners.value = res.data.map((e) => e.imagepath)
-    })
-  }
-  // 市场资讯
-  queryNewTitles({
-    data: {
-      page: 1,
-      pagesize: 10,
-    }
-  }).then((res) => {
-    newsList.value = res.data
-  }).finally(() => {
-    refreshing.value = false
-  })
-}
-
-onRefresh()
-</script>
-
-<style lang="less">
-@import "./index.less";
-</style>

+ 0 - 89
src/packages/gcszt/views/home/main/index.less

@@ -1,89 +0,0 @@
-@import '@mobile/assets/themes/base/mixin.less';
-
-.home-main {
-    &__header {
-        background: linear-gradient(var(--navbar-background), var(--navbar-background) 60%, transparent 60%);
-        padding: .2rem;
-    }
-
-    &__iconbar {
-        ul {
-            display: flex;
-            flex-wrap: wrap;
-            padding-top: .24rem;
-
-            &:last-child {
-                padding-bottom: .24rem;
-            }
-
-            li {
-                display: flex;
-                flex-direction: column;
-                align-items: center;
-                width: calc(~'100% / 4');
-                text-align: center;
-
-                .app-iconfont {
-                    &__icon {
-                        font-size: .8rem;
-                    }
-
-                    &__label {
-                        font-size: .24rem;
-                        margin-top: .1rem;
-                    }
-                }
-            }
-        }
-    }
-
-    &__titlebar {
-        .van-cell__title {
-            font-size: .32rem;
-            font-weight: bold;
-        }
-
-        .van-cell__value {
-            flex: none;
-            color: #666;
-        }
-    }
-
-    &__market {
-        .scrollbar {
-            width: 100%;
-            padding: .2rem;
-        }
-
-        .van-swipe {
-            height: 32px;
-            background-color: #f6f6f6;
-
-            ul {
-                display: flex;
-                justify-content: space-around;
-                align-items: center;
-                height: inherit;
-                font-size: .26rem;
-            }
-        }
-    }
-
-    &__news {
-        .article {
-            &-item {
-                .van-cell__title {
-                    span {
-                        .mixin-text-overflow()
-                    }
-                }
-
-                .van-cell__value {
-                    flex: initial;
-                    font-size: .24rem;
-                    margin-left: .48rem;
-                }
-            }
-        }
-    }
-}

+ 12 - 65
src/packages/gstj/router/index.ts

@@ -1,6 +1,7 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import { useLoginStore } from '@/stores'
 import { clearPending } from '@/services/http/pending'
+import { homeRoutes, pageRoutes } from '@mobile/router/section'
 import service from '@/services'
 import Page from '@mobile/components/layouts/page/index.vue'
 import animateRouter from '@mobile/router/animateRouter'
@@ -31,51 +32,28 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: '',
         name: 'home',
-        component: () => import('../views/home/Index.vue'),
+        component: () => import('@mobile/views/home/Index.vue'),
+        props: {
+          iosUpdateUrl: 'https://itunes.apple.com/lookup?id=6459789608'
+        },
         children: [
           {
             path: '',
             name: 'home-index',
-            component: () => import('../views/home/main/Index.vue'),
+            component: () => import('@mobile/views/home/main/Index.vue'),
             meta: {
               ignoreAuth: true,
             },
           },
           {
-            path: '50101',
-            name: 'home-50101',
-            component: () => import('@mobile/views/goods/list/Index.vue'),
-            props: {
-              title: '协议转让',
-              marketId: 50101
-            }
-          },
-          {
-            path: '50102',
-            name: 'home-50102',
-            component: () => import('@mobile/views/goods/list/Index.vue'),
-            props: {
-              title: '订单挂牌',
-              marketId: 50102
-            }
-          },
-          {
-            path: '16201',
-            name: 'home-16201',
-            component: () => import('@mobile/views/goods/list/Index.vue'),
-            props: {
-              title: '全款挂牌',
-              marketId: 16201
-            }
-          },
-          {
             path: 'mine',
             name: 'home-mine',
             component: () => import('../views/mine/Index.vue'),
-          }
+          },
+          ...homeRoutes
         ]
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/user',
@@ -156,38 +134,6 @@ const routes: Array<RouteRecordRaw> = [
     ],
   },
   {
-    path: '/goods',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'goods-detail',
-        component: () => import('@mobile/views/goods/detail/Index.vue'),
-      },
-      {
-        path: 'trade',
-        name: 'goods-trade',
-        component: () => import('@mobile/views/goods/trade/index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/spot',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'spot-detail',
-        component: () => import('@mobile/views/spot/detail/Index.vue'),
-      },
-      {
-        path: 'add',
-        name: 'spot-add',
-        component: () => import('@mobile/views/spot/add/index.vue'),
-      },
-    ],
-  },
-  {
     path: '/bank',
     component: Page,
     children: [
@@ -337,7 +283,8 @@ const routes: Array<RouteRecordRaw> = [
         },
       },
     ]
-  }
+  },
+  ...pageRoutes
 ]
 
 const router = animateRouter.create({

+ 0 - 41
src/packages/gstj/views/home/Index.vue

@@ -1,41 +0,0 @@
-<template>
-  <LayoutHome :tabs="tabList" ios-update-url="https://itunes.apple.com/lookup?id=6459789608" />
-</template>
-
-<script lang="ts" setup>
-import { Tabbar } from '@mobile/components/base/tabbar/types'
-import LayoutHome from '@mobile/components/layouts/home/index.vue'
-
-const tabList: Tabbar[] = [
-  {
-    name: 'home-index',
-    label: '首页',
-    icon: 'g-icon-home--line',
-    activeIcon: 'g-icon-home--fill',
-  },
-  {
-    name: 'home-50102',
-    label: '订单挂牌',
-    icon: 'g-icon-listing--line',
-    activeIcon: 'g-icon-listing--fill',
-  },
-  {
-    name: 'home-50101',
-    label: '协议转让',
-    icon: 'g-icon-transfer--line',
-    activeIcon: 'g-icon-transfer--fill',
-  },
-  {
-    name: 'home-16201',
-    label: '全款挂牌',
-    icon: 'g-icon-listing--line',
-    activeIcon: 'g-icon-listing--fill',
-  },
-  {
-    name: 'home-mine',
-    label: '我的',
-    icon: 'g-icon-mine--line',
-    activeIcon: 'g-icon-mine--fill',
-  }
-]
-</script>

+ 0 - 67
src/packages/gstj/views/home/main/Index.vue

@@ -1,67 +0,0 @@
-<template>
-  <app-view class="home-main">
-    <template #header>
-      <app-navbar :title="globalStore.getSystemInfo('appName')" :show-back-button="false" />
-    </template>
-    <Banner :data-list="topBanners" />
-    <PullRefresh class="home-main__container" v-model="refreshing" @refresh="onRefresh">
-      <app-block>
-        <Cell title="通知公告" value="更多" :to="{ name: 'notice-list' }" icon="volume" is-link />
-      </app-block>
-      <app-block class="home-main__news">
-        <CellGroup class="article">
-          <Cell class="home-main__titlebar" title="市场资讯" value="更多" icon="fire" :to="{ name: 'news-list' }" is-link />
-          <template v-for="(item, index) in newsList" :key="index">
-            <Cell class="article-item" :title="item.title" :value="formatDate(item.publishdate, 'MM/DD')"
-              :to="{ name: 'news-detail', query: { id: item.id } }" />
-          </template>
-        </CellGroup>
-      </app-block>
-    </PullRefresh>
-  </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from "vue";
-import { Cell, CellGroup, PullRefresh } from "vant";
-import { formatDate } from "@/filters";
-import { queryImageConfigs } from "@/services/api/common";
-import { queryNewTitles } from "@/services/api/news";
-import { useGlobalStore } from '@/stores'
-import Banner from '@mobile/components/base/banner/index.vue'
-
-const globalStore = useGlobalStore()
-const refreshing = shallowRef(false); // 是否处于加载中状态
-const topBanners = shallowRef<string[]>([]); // 轮播图列表
-const newsList = shallowRef<Model.NewTitlesRsp[]>([]); // 资讯列表
-
-// 下拉刷新
-const onRefresh = () => {
-  if (!topBanners.value.length) {
-    queryImageConfigs({
-      data: {
-        imageType: 1,
-      }
-    }).then((res) => {
-      topBanners.value = res.data.map((e) => e.imagepath)
-    })
-  }
-  // 市场资讯
-  queryNewTitles({
-    data: {
-      page: 1,
-      pagesize: 10,
-    }
-  }).then((res) => {
-    newsList.value = res.data
-  }).finally(() => {
-    refreshing.value = false
-  })
-}
-
-onRefresh()
-</script>
-
-<style lang="less">
-@import "./index.less";
-</style>

+ 0 - 89
src/packages/gstj/views/home/main/index.less

@@ -1,89 +0,0 @@
-@import '@mobile/assets/themes/base/mixin.less';
-
-.home-main {
-    &__header {
-        background: linear-gradient(var(--navbar-background), var(--navbar-background) 60%, transparent 60%);
-        padding: .2rem;
-    }
-
-    &__iconbar {
-        ul {
-            display: flex;
-            flex-wrap: wrap;
-            padding-top: .24rem;
-
-            &:last-child {
-                padding-bottom: .24rem;
-            }
-
-            li {
-                display: flex;
-                flex-direction: column;
-                align-items: center;
-                width: calc(~'100% / 4');
-                text-align: center;
-
-                .app-iconfont {
-                    &__icon {
-                        font-size: .8rem;
-                    }
-
-                    &__label {
-                        font-size: .24rem;
-                        margin-top: .1rem;
-                    }
-                }
-            }
-        }
-    }
-
-    &__titlebar {
-        .van-cell__title {
-            font-size: .32rem;
-            font-weight: bold;
-        }
-
-        .van-cell__value {
-            flex: none;
-            color: #666;
-        }
-    }
-
-    &__market {
-        .scrollbar {
-            width: 100%;
-            padding: .2rem;
-        }
-
-        .van-swipe {
-            height: 32px;
-            background-color: #f6f6f6;
-
-            ul {
-                display: flex;
-                justify-content: space-around;
-                align-items: center;
-                height: inherit;
-                font-size: .26rem;
-            }
-        }
-    }
-
-    &__news {
-        .article {
-            &-item {
-                .van-cell__title {
-                    span {
-                        .mixin-text-overflow()
-                    }
-                }
-
-                .van-cell__value {
-                    flex: initial;
-                    font-size: .24rem;
-                    margin-left: .48rem;
-                }
-            }
-        }
-    }
-}

+ 2 - 1
src/packages/mobile/components/base/tabbar/types.ts

@@ -1,7 +1,8 @@
-export interface Tabbar {
+export interface Tabbar<T = unknown> {
     name: string;
     label: string;
     iconType?: 'iconfont' | 'image';
     icon: string;
     activeIcon?: string;
+    params?: T;
 }

+ 0 - 85
src/packages/mobile/components/layouts/home/index.vue

@@ -1,85 +0,0 @@
-<template>
-  <div class="app-home g-flex">
-    <router-view v-slot="{ Component }">
-      <RouterTransition :css="cssTransition">
-        <!-- 缓存所有组件 -->
-        <keep-alive>
-          <component class="g-flex__body" :is="Component" />
-        </keep-alive>
-      </RouterTransition>
-    </router-view>
-    <app-tabbar :data-list="tabs" :data-index="currentTab" @click="onTabClick" />
-    <app-updater :ios-update-url="iosUpdateUrl" />
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, nextTick, watch, onMounted, onActivated, computed, PropType } from 'vue'
-import { fullloading } from '@/utils/vant'
-import { Tabbar } from '@mobile/components/base/tabbar/types'
-import { useNavigation } from '@mobile/router/navigation'
-import { useLogin } from '@/business/login'
-import { useLoginStore, useFuturesStore } from '@/stores'
-import AppTabbar from '@mobile/components/base/tabbar/index.vue'
-import AppUpdater from '@mobile/components/base/updater/index.vue'
-import RouterTransition from '@mobile/components/base/router-transition/index.vue'
-
-const props = defineProps({
-  tabs: {
-    type: Array as PropType<Tabbar[]>,
-    required: true
-  },
-  iosUpdateUrl: String
-})
-
-const { route, routerTo } = useNavigation()
-const { userLogin } = useLogin()
-const loginStore = useLoginStore()
-const futuresStore = useFuturesStore()
-const cssTransition = shallowRef(true) // 是否使用css动画
-const currentTab = shallowRef(0)
-
-const tabIndex = computed(() => props.tabs.findIndex((e) => e.name === route.name))
-
-const onTabClick = (index: number) => {
-  const { name } = props.tabs[index]
-  if (index === 0 || loginStore.token) {
-    routerTo(name, true)
-  } else {
-    fullloading((hideLoading) => {
-      userLogin(true).then(() => {
-        routerTo(name, true)
-      }).catch(() => {
-        routerTo('user-login')
-      }).finally(() => {
-        hideLoading()
-      })
-    }, '加载中...')
-  }
-}
-
-watch(() => route.name, () => {
-  if (tabIndex.value > -1) {
-    cssTransition.value = false
-    currentTab.value = tabIndex.value
-  }
-  nextTick(() => {
-    cssTransition.value = true
-  })
-})
-
-onMounted(() => {
-  currentTab.value = tabIndex.value
-})
-
-onActivated(() => {
-  // 页面显示时刷新盘面(待优化)
-  if (loginStore.token && futuresStore.goodsList.length) {
-    futuresStore.getQuoteDay()
-  }
-})
-</script>
-  
-<style lang="less">
-@import './index.less';
-</style>

+ 1 - 1
src/packages/mobile/components/modules/hqchart/candlestick/index.less

@@ -4,7 +4,7 @@
     flex-direction: column;
     height: 8rem;
     overflow: hidden;
-    padding:0 .1rem;
+    padding:0 .2rem;
 
     .app-hqchart {
         flex: 1;

+ 1 - 2
src/packages/mobile/components/modules/hqchart/timeline/index.less

@@ -1,10 +1,9 @@
-.app-candlestick {
+.app-timeline {
     flex: 1;
     display: flex;
     flex-direction: column;
     height: 8rem;
     overflow: hidden;
-    padding:0 .1rem;
 
     .app-hqchart {
         flex: 1;

+ 5 - 5
src/packages/mobile/components/modules/hqchart/timeline/index.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="app-candlestick">
+    <div class="app-timeline">
         <HQChart @ready="onReady" />
     </div>
 </template>
@@ -49,12 +49,12 @@ const chartOption = {
     },
     DayCount: 1,
     Border: {
-        Left: 0,
-        Right: 0,
+        Left: 60,
+        Right: 60,
         Top: 36,
         Bottom: 25,
-        AutoLeft: { Blank: 15, MinWidth: 30 },
-        AutoRight: { Blank: 15, MinWidth: 30 },
+        AutoLeft: { Blank: 10, MinWidth: 30 },
+        AutoRight: { Blank: 10, MinWidth: 30 },
     },
     MinuteLine: {
         IsShowAveragePrice: false, // 不显示均线

+ 27 - 235
src/packages/mobile/router/index.ts

@@ -1,20 +1,21 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import { useLoginStore } from '@/stores'
 import { clearPending } from '@/services/http/pending'
+import { homeRoutes, pageRoutes } from './section'
 import service from '@/services'
 import Page from '@mobile/components/layouts/page/index.vue'
 import animateRouter from './animateRouter'
 
 const loginStore = useLoginStore()
 
-const routes: Array<RouteRecordRaw> = [
+const routes: RouteRecordRaw[] = [
   {
     path: '/:pathMatch(.*)*',
     name: 'error',
     component: () => import('../views/error/404.vue'),
     meta: {
       ignoreAuth: true,
-    },
+    }
   },
   {
     path: '/boot',
@@ -22,7 +23,7 @@ const routes: Array<RouteRecordRaw> = [
     component: () => import('../views/boot/Index.vue'),
     meta: {
       ignoreAuth: true,
-    },
+    }
   },
   {
     path: '/',
@@ -42,42 +43,14 @@ const routes: Array<RouteRecordRaw> = [
             },
           },
           {
-            path: 'ballot',
-            name: 'home-ballot',
-            component: () => import('../views/ballot/list/Index.vue'),
-          },
-          {
-            path: 'goods',
-            name: 'home-16201',
-            component: () => import('../views/goods/list/Index.vue'),
-            props: {
-              title: '全款挂牌',
-              marketId: 16201
-            }
-          },
-          // {
-          //   path: 'spot',
-          //   name: 'home-spot',
-          //   component: () => import('../views/spot/list/Index.vue'),
-          // },
-          {
-            path: 'transfer',
-            name: 'home-transfer',
-            component: () => import('../views/transfer/list/Index.vue'),
-          },
-          // {
-          //   path: 'swap',
-          //   name: 'home-swap',
-          //   component: () => import('../views/swap/list/Index.vue'),
-          // },
-          {
             path: 'mine',
             name: 'home-mine',
             component: () => import('../views/mine/Index.vue'),
-          }
+          },
+          ...homeRoutes
         ]
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/user',
@@ -121,8 +94,8 @@ const routes: Array<RouteRecordRaw> = [
         path: 'avatar',
         name: 'user-avatar',
         component: () => import('../views/user/avatar/Index.vue'),
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/account',
@@ -132,20 +105,20 @@ const routes: Array<RouteRecordRaw> = [
         path: 'certification',
         name: 'account-certification',
         component: () => import('../views/account/certification/Index.vue'),
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/news',
     component: Page,
     children: [
       {
-        path: '',
+        path: 'list',
         name: 'news-list',
         component: () => import('../views/news/list/Index.vue'),
         meta: {
           ignoreAuth: true,
-        },
+        }
       },
       {
         path: 'detail',
@@ -153,191 +126,9 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import('../views/news/detail/Index.vue'),
         meta: {
           ignoreAuth: true,
-        },
-      },
-    ],
-  },
-  {
-    path: '/market',
-    component: Page,
-    children: [
-      {
-        path: '',
-        name: 'market-list',
-        component: () => import('../views/market/list/Index.vue'),
-        props: {
-          showBackButton: true
-        }
-      },
-      {
-        path: 'detail',
-        name: 'market-detail',
-        component: () => import('../views/market/detail/Index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/goods',
-    component: Page,
-    children: [
-      {
-        path: '50101',
-        name: 'goods-50101',
-        component: () => import('../views/goods/list/Index.vue'),
-        props: {
-          title: '日清挂牌',
-          marketId: 50101,
-          showBackButton: true
-        }
-      },
-      {
-        path: '50102',
-        name: 'goods-50102',
-        component: () => import('../views/goods/list/Index.vue'),
-        props: {
-          title: '中远期挂牌',
-          marketId: 50102,
-          showBackButton: true
-        }
-      },
-      {
-        path: '50103',
-        name: 'goods-50103',
-        component: () => import('../views/goods/list/Index.vue'),
-        props: {
-          title: '周清挂牌',
-          marketId: 50103,
-          showBackButton: true
-        }
-      },
-      {
-        path: '50104',
-        name: 'goods-50104',
-        component: () => import('../views/goods/list/Index.vue'),
-        props: {
-          title: '月清挂牌',
-          marketId: 50104,
-          showBackButton: true
-        }
-      },
-      {
-        path: 'detail',
-        name: 'goods-detail',
-        component: () => import('../views/goods/detail/Index.vue'),
-      },
-      {
-        path: 'trade',
-        name: 'goods-trade',
-        component: () => import('../views/goods/trade/index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/presale',
-    component: Page,
-    children: [
-      {
-        path: '',
-        name: 'presale-list',
-        component: () => import('../views/presale/list/Index.vue'),
-      },
-      {
-        path: 'detail',
-        name: 'presale-detail',
-        component: () => import('../views/presale/detail/Index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/transfer',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'transfer-detail',
-        component: () => import('../views/transfer/detail/Index.vue'),
-      },
-      {
-        path: 'detail2',
-        name: 'transfer-detail2',
-        component: () => import('../views/transfer/detail2/index.vue'),
-      },
-      {
-        path: 'delisting',
-        name: 'transfer-delisting',
-        component: () => import('../views/transfer/delisting/Index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/swap',
-    component: Page,
-    children: [
-      {
-        path: '',
-        name: 'swap-list',
-        component: () => import('../views/swap/list/Index.vue'),
-        props: {
-          showBackButton: true
-        }
-      },
-      {
-        path: 'detail',
-        name: 'swap-detail',
-        component: () => import('../views/swap/detail/Index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/spot',
-    component: Page,
-    children: [
-      {
-        path: '',
-        name: 'spot-list',
-        component: () => import('../views/spot/list/Index.vue'),
-        props: {
-          showBackButton: true
         }
-      },
-      {
-        path: 'detail',
-        name: 'spot-detail',
-        component: () => import('../views/spot/detail/Index.vue'),
-      },
-      {
-        path: 'add',
-        name: 'spot-add',
-        component: () => import('../views/spot/add/index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/pricing',
-    component: Page,
-    children: [
-      {
-        path: '',
-        name: 'pricing-list',
-        component: () => import('../views/pricing/list/Index.vue'),
-      },
-      {
-        path: 'detail',
-        name: 'pricing-detail',
-        component: () => import('../views/pricing/detail/Index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/ballot',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'ballot-detail',
-        component: () => import('../views/ballot/detail/Index.vue'),
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/bank',
@@ -444,7 +235,7 @@ const routes: Array<RouteRecordRaw> = [
         name: 'mine-email',
         component: () => import('../views/mine/email/Index.vue'),
       }
-    ],
+    ]
   },
   {
     path: '/notice',
@@ -454,8 +245,8 @@ const routes: Array<RouteRecordRaw> = [
         path: '',
         name: 'notice-list',
         component: () => import('../views/notice/list/index.vue'),
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/rules',
@@ -467,7 +258,7 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import("../views/rules/zcxy/Index.vue"),
         meta: {
           ignoreAuth: true,
-        },
+        }
       },
       {
         path: "yhkhfxgzs",
@@ -475,7 +266,7 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import("../views/rules/fxgzs/Index.vue"),
         meta: {
           ignoreAuth: true,
-        },
+        }
       },
       {
         path: "yszc",
@@ -483,7 +274,7 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import("../views/rules/yszc/Index.vue"),
         meta: {
           ignoreAuth: true,
-        },
+        }
       },
       {
         path: "gywm",
@@ -491,7 +282,7 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import("../views/rules/gywm/Index.vue"),
         meta: {
           ignoreAuth: true,
-        },
+        }
       },
       {
         path: "fwrx",
@@ -499,10 +290,11 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import("../views/rules/fwrx/Index.vue"),
         meta: {
           ignoreAuth: true,
-        },
-      },
+        }
+      }
     ]
-  }
+  },
+  ...pageRoutes
 ]
 
 const router = animateRouter.create({

+ 2 - 5
src/packages/mobile/router/navigation.ts

@@ -36,15 +36,12 @@ export function useNavigation() {
     // 获取查询字符串
     const getQueryString = (name: string) => {
         const qs = route.query[name]
-        if (qs) {
-            return qs.toString()
-        }
-        return ''
+        return qs?.toString()
     }
 
     const getQueryStringToNumber = (name: string) => {
         const reg = /^[0-9]+.?[0-9]*/
-        const value = getQueryString(name)
+        const value = getQueryString(name) ?? ''
         return reg.test(value) ? Number(value) : 0
     }
 

+ 222 - 0
src/packages/mobile/router/section.ts

@@ -0,0 +1,222 @@
+import { RouteRecordRaw } from 'vue-router'
+import Page from '@mobile/components/layouts/page/index.vue'
+
+const homeRoutes: RouteRecordRaw[] = [
+    {
+        path: 'pricing',
+        name: 'home-pricing',
+        component: () => import('@mobile/views/pricing/list/Index.vue'),
+    },
+    {
+        path: 'ballot',
+        name: 'home-ballot',
+        component: () => import('@mobile/views/ballot/list/Index.vue'),
+    },
+    {
+        path: 'goods',
+        name: 'home-goods',
+        component: () => import('@mobile/views/goods/list/Index.vue')
+    },
+    {
+        path: 'presale',
+        name: 'home-presale',
+        component: () => import('@mobile/views/presale/list/Index.vue')
+    },
+    {
+        path: 'spot',
+        name: 'home-spot',
+        component: () => import('@mobile/views/spot/list/Index.vue'),
+    },
+    {
+        path: 'transfer',
+        name: 'home-transfer',
+        component: () => import('@mobile/views/transfer/list/Index.vue'),
+    },
+    {
+        path: 'swap',
+        name: 'home-swap',
+        component: () => import('@mobile/views/swap/list/Index.vue'),
+    },
+    {
+        path: 'market',
+        name: 'home-market',
+        component: () => import('@mobile/views/market/list/Index.vue'),
+    }
+]
+
+const pageRoutes: RouteRecordRaw[] = [
+    {
+        path: '/pricing',
+        component: Page,
+        children: [
+            {
+                path: 'list',
+                name: 'pricing-list',
+                component: () => import('@mobile/views/pricing/list/Index.vue'),
+            },
+            {
+                path: 'detail',
+                name: 'pricing-detail',
+                component: () => import('@mobile/views/pricing/detail/Index.vue'),
+            }
+        ]
+    },
+    {
+        path: '/spot',
+        component: Page,
+        children: [
+            {
+                path: 'list',
+                name: 'spot-list',
+                component: () => import('@mobile/views/spot/list/Index.vue'),
+                props: {
+                    showBackButton: true
+                }
+            },
+            {
+                path: 'detail',
+                name: 'spot-detail',
+                component: () => import('@mobile/views/spot/detail/Index.vue'),
+            },
+            {
+                path: 'add',
+                name: 'spot-add',
+                component: () => import('@mobile/views/spot/add/index.vue'),
+            }
+        ]
+    },
+    {
+        path: '/swap',
+        component: Page,
+        children: [
+            {
+                path: 'list',
+                name: 'swap-list',
+                component: () => import('@mobile/views/swap/list/Index.vue'),
+                props: {
+                    showBackButton: true
+                }
+            },
+            {
+                path: 'detail',
+                name: 'swap-detail',
+                component: () => import('@mobile/views/swap/detail/Index.vue'),
+            }
+        ]
+    },
+    {
+        path: '/presale',
+        component: Page,
+        children: [
+            {
+                path: 'list',
+                name: 'presale-list',
+                component: () => import('@mobile/views/presale/list/Index.vue'),
+                props: {
+                    showBackButton: true
+                }
+            },
+            {
+                path: 'detail',
+                name: 'presale-detail',
+                component: () => import('@mobile/views/presale/detail/Index.vue'),
+            }
+        ]
+    },
+    {
+        path: '/transfer',
+        component: Page,
+        children: [
+            {
+                path: 'list',
+                name: 'transfer-list',
+                component: () => import('@mobile/views/transfer/list/Index.vue'),
+                props: {
+                    showBackButton: true
+                }
+            },
+            {
+                path: 'detail',
+                name: 'transfer-detail',
+                component: () => import('@mobile/views/transfer/detail/Index.vue'),
+            },
+            {
+                path: 'detail2',
+                name: 'transfer-detail2',
+                component: () => import('@mobile/views/transfer/detail2/index.vue'),
+            },
+            {
+                path: 'delisting',
+                name: 'transfer-delisting',
+                component: () => import('@mobile/views/transfer/delisting/Index.vue'),
+            }
+        ]
+    },
+    {
+        path: '/goods',
+        component: Page,
+        children: [
+            {
+                path: 'list',
+                name: 'goods-list',
+                component: () => import('@mobile/views/goods/list/Index.vue'),
+                props: {
+                    showBackButton: true
+                }
+            },
+            {
+                path: 'detail',
+                name: 'goods-detail',
+                component: () => import('@mobile/views/goods/detail/Index.vue'),
+            },
+            {
+                path: 'trade',
+                name: 'goods-trade',
+                component: () => import('@mobile/views/goods/trade/index.vue'),
+            }
+        ]
+    },
+    {
+        path: '/ballot',
+        component: Page,
+        children: [
+            {
+                path: 'list',
+                name: 'ballot-list',
+                component: () => import('@mobile/views/ballot/list/Index.vue'),
+                props: {
+                    showBackButton: true
+                }
+            },
+            {
+                path: 'detail',
+                name: 'ballot-detail',
+                component: () => import('@mobile/views/ballot/detail/Index.vue'),
+            }
+        ]
+    },
+    {
+        path: '/market',
+        component: Page,
+        children: [
+            {
+                path: 'list',
+                name: 'market-list',
+                component: () => import('@mobile/views/market/list/Index.vue'),
+                props: {
+                    showBackButton: true
+                }
+            },
+            {
+                path: 'detail',
+                name: 'market-detail',
+                component: () => import('@mobile/views/market/detail/Index.vue'),
+            }
+        ]
+    }
+]
+
+export {
+    homeRoutes,
+    pageRoutes
+}

+ 14 - 5
src/packages/mobile/views/ballot/list/Index.vue

@@ -1,7 +1,7 @@
 <template>
     <app-view class="ballot-list">
         <template #header>
-            <app-navbar :title="title ?? '预售中签'" :show-back-button="false">
+            <app-navbar :title="titleName" :show-back-button="showBackButton">
                 <template #right>
                     <Icon name="bars" size=".4rem" @click="isWaterfall = !isWaterfall" />
                 </template>
@@ -81,7 +81,7 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef } from 'vue'
+import { shallowRef, computed, PropType } from 'vue'
 import { Tag, Divider, Icon } from 'vant'
 import { getFileUrl, getFirstImage } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
@@ -90,14 +90,23 @@ import { queryPresaleAuctions } from '@/services/api/presale'
 import Banner from '@mobile/components/base/banner/index.vue'
 import Waterfall from '@mobile/components/base/waterfall/index.vue'
 
-defineProps({
-    title: String,
+const props = defineProps({
+    showBackButton: {
+        type: Boolean,
+        default: false
+    },
+    marketSection: {
+        type: Object as PropType<Model.Marketsectionconfignew>
+    }
 })
 
 const isWaterfall = shallowRef(false)
-const { router, setGlobalUrlParams } = useNavigation()
+const { router, getQueryString, setGlobalUrlParams } = useNavigation()
 const bannerList = shallowRef<string[]>([])
 
+const title = getQueryString('title')
+const titleName = computed(() => title ? decodeURIComponent(title) : props.marketSection?.displayname ?? '预售中签')
+
 const { dataList } = useRequest(queryPresaleAuctions, {
     params: {
         presalemode: 5,

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

@@ -1,7 +1,7 @@
 <template>
     <app-view>
         <template #header>
-            <app-navbar :title="title ?? '订单挂牌'" :show-back-button="showBackButton" />
+            <app-navbar :title="titleName" :show-back-button="showBackButton" />
         </template>
         <app-list :columns="columns" :data-list="futuresStore.marketGoodsList" @row-click="rowClick">
             <!-- 商品名称/代码 -->
@@ -66,7 +66,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onUnmounted, onActivated, watch } from 'vue'
+import { computed, onUnmounted, onActivated, watch, PropType } from 'vue'
 import { parsePercent, handleNumberValue, formatDecimal } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
 import { useFuturesStore } from '@/stores'
@@ -74,21 +74,22 @@ import quoteSocket from '@/services/websocket/quote'
 import AppList from '@mobile/components/base/list/index.vue'
 
 const props = defineProps({
-    title: String,
-    marketId: {
-        type: Number,
-        required: true
-    },
     showBackButton: {
         type: Boolean,
         default: false
     },
+    marketSection: {
+        type: Object as PropType<Model.Marketsectionconfignew>
+    }
 })
 
-const { router } = useNavigation()
+const { router, getQueryString } = useNavigation()
 const subscribe = quoteSocket.createSubscribe()
 const futuresStore = useFuturesStore()
 
+const title = getQueryString('title')
+const titleName = computed(() => title ? decodeURIComponent(title) : props.marketSection?.displayname ?? '订单挂牌')
+
 const columns: Model.TableColumn[] = [
     { prop: 'goodsname', label: '商品名称/代码' },
     { prop: 'bid', label: '买价' },
@@ -117,12 +118,16 @@ const rowClick = (row: Model.QuoteGoodsListRsp) => {
 }
 
 const getMarketGoodsList = () => {
-    futuresStore.setMarketId(props.marketId)
-    const goodsCodes = futuresStore.marketGoodsList.map((e) => e.goodscode)
-    subscribe.start(...goodsCodes)
+    const marketIds = getQueryString('markets') ?? props.marketSection?.marketids
+    const ids = marketIds?.split(',')
+    if (ids) {
+        futuresStore.setMarketId(...ids.map((id) => Number(id)))
+        const goodsCodes = futuresStore.marketGoodsList.map((e) => e.goodscode)
+        subscribe.start(...goodsCodes)
+    }
 }
 
-watch(() => props.marketId, () => {
+watch(() => props.marketSection?.marketids, () => {
     subscribe.stop()
     getMarketGoodsList()
 })

+ 177 - 33
src/packages/mobile/views/home/Index.vue

@@ -1,41 +1,185 @@
 <template>
-  <LayoutHome :tabs="tabList" />
+  <div class="home g-flex">
+    <router-view v-slot="{ Component }">
+      <RouterTransition :css="cssTransition">
+        <!-- 缓存所有组件 -->
+        <keep-alive>
+          <component class="g-flex__body" :is="Component" v-bind="{ marketSection }" />
+        </keep-alive>
+      </RouterTransition>
+    </router-view>
+    <app-tabbar :data-list="tabList" :data-index="currentTab" @click="onTabClick" />
+    <app-updater :ios-update-url="iosUpdateUrl" />
+  </div>
 </template>
 
 <script lang="ts" setup>
+import { shallowRef, nextTick, watch, onMounted, onActivated, computed } from 'vue'
 import { Tabbar } from '@mobile/components/base/tabbar/types'
-import LayoutHome from '@mobile/components/layouts/home/index.vue'
-
-const tabList: Tabbar[] = [
-  {
-    name: 'home-index',
-    label: '首页',
-    icon: 'g-icon-home--line',
-    activeIcon: 'g-icon-home--fill',
-  },
-  {
-    name: 'home-ballot',
-    label: '预售中签',
-    icon: 'g-icon-presale--line',
-    activeIcon: 'g-icon-presale--fill',
-  },
-  {
-    name: 'home-transfer',
-    label: '定金转让',
-    icon: 'g-icon-transfer--line',
-    activeIcon: 'g-icon-transfer--fill',
-  },
-  {
-    name: 'home-16201',
-    label: '全款挂牌',
+import { useNavigation } from '@mobile/router/navigation'
+import { useMarketSection } from '@/business/market'
+import { useLoginStore, useFuturesStore } from '@/stores'
+import AppTabbar from '@mobile/components/base/tabbar/index.vue'
+import AppUpdater from '@mobile/components/base/updater/index.vue'
+import RouterTransition from '@mobile/components/base/router-transition/index.vue'
+
+defineProps({
+  iosUpdateUrl: String
+})
+
+const { route, routerTo } = useNavigation()
+const loginStore = useLoginStore()
+const futuresStore = useFuturesStore()
+const cssTransition = shallowRef(true) // 是否使用css动画
+const currentTab = shallowRef(0)
+const marketSection = shallowRef() // 当前选中的板块
+
+const tabIndex = computed(() => {
+  const value = window.sessionStorage.getItem('currentTab')
+  if (value) {
+    const parsedValue = JSON.parse(value)
+    if (parsedValue.name === route.name) {
+      return parsedValue.index
+    }
+  }
+  return tabList.value.findIndex((e) => e.name === route.name)
+})
+
+// 获取市场板块
+const { allMarket } = useMarketSection(() => {
+  const tab = tabList.value[tabIndex.value]
+  marketSection.value = tab?.params
+  currentTab.value = tabIndex.value
+})
+
+// 动态添加导航标签页
+const addTab = (item: Model.Marketsectionconfignew) => {
+  const tab: Tabbar = {
+    name: 'home-404',
+    label: item.displayname,
     icon: 'g-icon-listing--line',
     activeIcon: 'g-icon-listing--fill',
-  },
-  {
-    name: 'home-mine',
-    label: '我的',
-    icon: 'g-icon-mine--line',
-    activeIcon: 'g-icon-mine--fill',
+    params: item
+  }
+  switch (item.trademode) {
+    case 10:
+      tab.name = 'home-pricing'
+      tab.icon = 'g-icon-pricing--line'
+      tab.activeIcon = 'g-icon-pricing--fill'
+      break
+    case 17:
+      tab.name = 'home-spot'
+      tab.icon = 'g-icon-spot--line'
+      tab.activeIcon = 'g-icon-spot--fill'
+      break
+    case 46:
+      tab.name = 'home-swap'
+      tab.icon = 'g-icon-swap--line'
+      tab.activeIcon = 'g-icon-swap--fill'
+      break
+    case 48:
+      tab.name = 'home-presale'
+      tab.icon = 'g-icon-presale--line'
+      tab.activeIcon = 'g-icon-presale--fill'
+      break
+    case 49:
+      tab.name = 'home-transfer'
+      tab.icon = 'g-icon-transfer--line'
+      tab.activeIcon = 'g-icon-transfer--fill'
+      break
+    case 16:
+    case 50:
+      tab.name = 'home-goods'
+      tab.icon = 'g-icon-listing--line'
+      tab.activeIcon = 'g-icon-listing--fill'
+      break
+    case 51:
+      tab.name = 'home-ballot'
+      tab.icon = 'g-icon-presale--line'
+      tab.activeIcon = 'g-icon-presale--fill'
+      break
+    case 99:
+      tab.name = 'home-market'
+      tab.icon = 'g-icon-quote--line'
+      tab.activeIcon = 'g-icon-quote--fill'
+      break
+  }
+  return tab
+}
+
+// 导航标签列表
+const tabList = computed(() => {
+  const result: Tabbar[] = [
+    {
+      name: 'home-index',
+      label: '首页',
+      icon: 'g-icon-home--line',
+      activeIcon: 'g-icon-home--fill',
+    },
+    {
+      name: 'home-mine',
+      label: '我的',
+      icon: 'g-icon-mine--line',
+      activeIcon: 'g-icon-mine--fill',
+    }
+  ]
+  if (loginStore.token) {
+    allMarket.value.forEach((item, index) => {
+      const startIndex = index + 1
+      if (startIndex < 4) {
+        result.splice(startIndex, 0, addTab(item))
+      }
+    })
+  } else {
+    result.splice(1, 0, {
+      name: '#',
+      label: '交易',
+      icon: 'g-icon-quote--line',
+      activeIcon: 'g-icon-quote--fill',
+    })
+  }
+  return result
+})
+
+const onTabClick = (index: number) => {
+  const { name, params } = tabList.value[index]
+  marketSection.value = params
+  if (index === 0 || loginStore.token) {
+    // 缓存当前选中的标签位置,防止 F5 刷新页面后无法定位到当前标签
+    window.sessionStorage.setItem('currentTab', JSON.stringify({
+      index,
+      name
+    }))
+    currentTab.value = index
+    routerTo(name, true)
+  } else {
+    window.sessionStorage.removeItem('currentTab')
+    routerTo('user-login')
+  }
+}
+
+watch(() => route.name, () => {
+  if (tabIndex.value > -1) {
+    cssTransition.value = false
+    currentTab.value = tabIndex.value
+  }
+  nextTick(() => {
+    cssTransition.value = true
+  })
+})
+
+onMounted(() => {
+  currentTab.value = tabIndex.value
+})
+
+onActivated(() => {
+  // 页面显示时刷新盘面(待优化)
+  if (loginStore.token && futuresStore.goodsList.length) {
+    futuresStore.getQuoteDay()
   }
-]
-</script>
+})
+</script>
+  
+<style lang="less">
+@import './index.less';
+</style>

+ 1 - 1
src/packages/mobile/components/layouts/home/index.less → src/packages/mobile/views/home/index.less

@@ -1,4 +1,4 @@
-.app-home {
+.home {
     .app-tabbar {
         background: var(--tabbar-background) !important;
         margin-top: auto;

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

@@ -8,46 +8,17 @@
       <app-block>
         <Cell title="通知公告" value="更多" :to="{ name: 'notice-list' }" icon="volume" is-link />
       </app-block>
-      <app-block class="home-main__iconbar">
-        <ul>
-          <li @click="routerTo('goods-50101')">
-            <Iconfont label-direction="bottom" icon="g-icon-listing--line m50101">日清挂牌</Iconfont>
-          </li>
-          <li @click="routerTo('goods-50103')">
-            <Iconfont label-direction="bottom" icon="g-icon-listing--line m50103">周清挂牌</Iconfont>
-          </li>
-          <li @click="routerTo('goods-50104')">
-            <Iconfont label-direction="bottom" icon="g-icon-listing--line m50104">月清挂牌</Iconfont>
-          </li>
-          <li @click="routerTo('goods-50102')">
-            <Iconfont label-direction="bottom" icon="g-icon-listing--line m50102">中远期挂牌</Iconfont>
-          </li>
-          <!-- <li @click="switchTab('home-ballot')">
-            <Iconfont label-direction="bottom" icon="g-icon-presale--line">预售中签</Iconfont>
-          </li>
-          <li @click="switchTab('home-transfer')">
-            <Iconfont label-direction="bottom" icon="g-icon-transfer--line">定金转让</Iconfont>
-          </li> -->
-        </ul>
-        <ul>
-          <li @click="routerTo('presale-list')">
-            <Iconfont label-direction="bottom" icon="g-icon-auction--line">预售竞拍</Iconfont>
-          </li>
-          <li @click="routerTo('spot-list')">
-            <Iconfont label-direction="bottom" icon="g-icon-spot--line">现货贸易</Iconfont>
-          </li>
-          <li @click="routerTo('pricing-list')">
-            <Iconfont label-direction="bottom" icon="g-icon-pricing--line">挂牌点价</Iconfont>
-          </li>
-          <li @click="routerTo('swap-list')">
-            <Iconfont label-direction="bottom" icon="g-icon-swap--line">掉期贸易</Iconfont>
-          </li>
-        </ul>
-        <ul>
-          <li @click="routerTo('market-list')">
-            <Iconfont label-direction="bottom" icon="g-icon-quote--line">参考行情</Iconfont>
-          </li>
-        </ul>
+      <app-block class="home-main__iconbar" v-if="iconbar.length">
+        <template v-for="(list, i) in iconbar" :key="i">
+          <ul>
+            <template v-for="(item, n) in list" :key="n">
+              <li
+                @click="$router.push({ name: item.name, query: { title: encodeURIComponent(item.label), markets: item.markets } })">
+                <Iconfont label-direction="bottom" :icon="item.icon">{{ item.label }}</Iconfont>
+              </li>
+            </template>
+          </ul>
+        </template>
       </app-block>
       <app-block class="home-main__news">
         <CellGroup class="article">
@@ -63,22 +34,20 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef } from "vue";
-import { Cell, CellGroup, PullRefresh } from "vant";
-import { formatDate } from "@/filters";
-import { useNavigation } from '@mobile/router/navigation';
-import { queryImageConfigs } from "@/services/api/common";
-import { queryNewTitles } from "@/services/api/news";
+import { shallowRef, computed } from 'vue'
+import { Cell, CellGroup, PullRefresh } from 'vant'
+import { formatDate } from "@/filters"
+import { queryImageConfigs } from "@/services/api/common"
+import { queryNewTitles } from "@/services/api/news"
+import { useMarketSection } from '@/business/market'
 import { useGlobalStore } from '@/stores'
 import Banner from '@mobile/components/base/banner/index.vue'
 import Iconfont from '@/components/base/iconfont/index.vue'
 
 const globalStore = useGlobalStore()
-// const loginStore = useLoginStore();
-const { routerTo } = useNavigation();
-const refreshing = shallowRef(false); // 是否处于加载中状态
+const refreshing = shallowRef(false) // 是否处于加载中状态
 const topBanners = shallowRef<string[]>([]); // 轮播图列表
-const newsList = shallowRef<Model.NewTitlesRsp[]>([]); // 资讯列表
+const newsList = shallowRef<Model.NewTitlesRsp[]>([]) // 资讯列表
 
 // 跳转导航页面
 // const switchTab = (routeName: string) => {
@@ -89,6 +58,67 @@ const newsList = shallowRef<Model.NewTitlesRsp[]>([]); // 资讯列表
 //   }
 // }
 
+// 获取市场板块
+const { allMarket } = useMarketSection()
+
+const iconbar = computed(() => allMarket.value.reduce<{
+  name: string;
+  label: string;
+  icon: string;
+  markets?: string;
+}[][]>((pre, cur, index) => {
+  if (index > 2) {
+    const item = {
+      name: '',
+      label: cur.displayname,
+      icon: '',
+      markets: cur.marketids
+    }
+    switch (cur.trademode) {
+      case 10:
+        item.name = 'pricing-list'
+        item.icon = 'g-icon-pricing--line'
+        break
+      case 17:
+        item.name = 'spot-list'
+        item.icon = 'g-icon-spot--line'
+        break
+      case 46:
+        item.name = 'swap-list'
+        item.icon = 'g-icon-swap--line'
+        break
+      case 48:
+        item.name = 'presale-list'
+        item.icon = 'g-icon-auction--line'
+        break
+      case 49:
+        item.name = 'transfer-list'
+        item.icon = 'g-icon-transfer--line'
+        break
+      case 16:
+      case 50:
+        item.name = 'goods-list'
+        item.icon = 'g-icon-listing--line'
+        break
+      case 51:
+        item.name = 'ballot-list'
+        item.icon = 'g-icon-presale--line'
+        break
+      case 99:
+        item.name = 'market-list'
+        item.icon = 'g-icon-quote--line'
+        break
+    }
+    const i = pre.length - 1
+    if (i < 0 || pre[i].length > 3) {
+      pre.push([item])
+    } else {
+      pre[i].push(item)
+    }
+  }
+  return pre
+}, []))
+
 // 下拉刷新
 const onRefresh = () => {
   if (!topBanners.value.length) {

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

@@ -33,21 +33,15 @@
                     margin-bottom: .08rem;
 
                     &-listing--line {
-                        &.m50101 {
-                            background-color: #96b7d1;
-                        }
-
-                        &.m50102 {
-                            background-color: #2b455b;
-                        }
+                        background-color:#4e9ddb; 
+                    }
 
-                        &.m50103 {
-                            background-color: #72a2c9;
-                        }
+                    &-transfer--line {
+                        background-color: #42739b;
+                    }
 
-                        &.m50104 {
-                            background-color: #42739b;
-                        }
+                    &-presale--line {
+                        background-color: #8c8b94;
                     }
 
                     &-auction--line {

+ 1 - 1
src/packages/mobile/views/market/detail/Index.vue

@@ -19,6 +19,6 @@ const Chart = defineAsyncComponent(() => import('@mobile/components/modules/hqch
 const Tik = defineAsyncComponent(() => import('@mobile/components/modules/quote/tik/index.vue'))
 
 const { getQueryString } = useNavigation()
-const goodsCode = getQueryString('goodscode')
+const goodsCode = getQueryString('goodscode') ?? ''
 const futuresStore = useFuturesStore()
 </script>

+ 10 - 4
src/packages/mobile/views/market/list/Index.vue

@@ -1,7 +1,7 @@
 <template>
     <app-view>
         <template #header>
-            <app-navbar title="参考行情" :show-back-button="showBackButton" />
+            <app-navbar :title="titleName" :show-back-button="showBackButton" />
         </template>
         <app-list :columns="columns" :data-list="dataList" @row-click="rowClick">
             <!-- 商品/代码 -->
@@ -46,23 +46,29 @@
 </template>
 
 <script lang="ts" setup>
-import { onActivated, onUnmounted, computed } from 'vue'
+import { onActivated, onUnmounted, computed, PropType } from 'vue'
 import { parsePercent, handleNumberValue, formatDecimal } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
 import { useFuturesStore } from '@/stores'
 import quoteSocket from '@/services/websocket/quote'
 import AppList from '@mobile/components/base/list/index.vue'
 
-defineProps({
+const props = defineProps({
     showBackButton: {
         type: Boolean,
         default: false
+    },
+    marketSection: {
+        type: Object as PropType<Model.Marketsectionconfignew>
     }
 })
 
-const { router } = useNavigation()
+const { router, getQueryString } = useNavigation()
 const futuresStore = useFuturesStore()
 
+const title = getQueryString('title')
+const titleName = computed(() => title ? decodeURIComponent(title) : props.marketSection?.displayname ?? '参考行情')
+
 const dataList = computed(() => {
     const list = futuresStore.quotationList.filter((e) => e.marketid === 99201)
     return list.map((e) => ({

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

@@ -1,7 +1,7 @@
 <template>
     <app-view class="presale-list">
         <template #header>
-            <app-navbar title="预售竞拍">
+            <app-navbar :title="titleName" :show-back-button="showBackButton">
                 <template #right>
                     <Icon name="bars" size=".4rem" @click="isWaterfall = !isWaterfall" />
                 </template>
@@ -79,7 +79,7 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef } from 'vue'
+import { shallowRef, computed, PropType } from 'vue'
 import { Tag, Divider, Icon } from 'vant'
 import { formatDate, getFileUrl, getFirstImage } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
@@ -88,10 +88,23 @@ 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 props = defineProps({
+    showBackButton: {
+        type: Boolean,
+        default: false
+    },
+    marketSection: {
+        type: Object as PropType<Model.Marketsectionconfignew>
+    }
+})
+
 const isWaterfall = shallowRef(false)
-const { router, setGlobalUrlParams } = useNavigation()
+const { router, getQueryString, setGlobalUrlParams } = useNavigation()
 const bannerList = shallowRef<string[]>([])
 
+const title = getQueryString('title')
+const titleName = computed(() => title ? decodeURIComponent(title) : props.marketSection?.displayname ?? '预售竞拍')
+
 // 预售准备
 const { dataList } = useRequest(queryPresaleAuctions, {
     params: {

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

@@ -166,7 +166,7 @@ const marketPrice = computed(() => {
     const { ask = 0, bid = 0 } = quote.value ?? {}
     return formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
 })
-const goodscode = getQueryString('goodscode')
+const goodscode = getQueryString('goodscode') ?? ''
 const buyOrSell = getQueryStringToNumber('buyOrSell')
 const buildType = getQueryStringToNumber('buildType')
 const quote = futuresStore.getGoodsQuote(goodscode)

+ 16 - 3
src/packages/mobile/views/pricing/list/Index.vue

@@ -1,7 +1,7 @@
 <template>
     <app-view>
         <template #header>
-            <app-navbar title="订单点价" />
+            <app-navbar :title="titleName" :show-back-button="showBackButton" />
         </template>
         <app-list :columns="columns" :data-list="tableList" @row-click="rowClick">
             <!-- 当前价 -->
@@ -42,7 +42,7 @@
 
 <script lang="ts" setup>
 
-import { computed, onUnmounted } from 'vue'
+import { computed, onUnmounted, PropType } from 'vue'
 import { parsePercent, handleNumberValue } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
 import { useRequest } from '@/hooks/request'
@@ -52,11 +52,24 @@ import quoteSocket from '@/services/websocket/quote'
 import AppList from '@mobile/components/base/list/index.vue'
 import { BuyOrSell, BuildType } from '@/constants/order'
 
-const { router } = useNavigation()
+const props = defineProps({
+    showBackButton: {
+        type: Boolean,
+        default: false
+    },
+    marketSection: {
+        type: Object as PropType<Model.Marketsectionconfignew>
+    }
+})
+
+const { router, getQueryString } = useNavigation()
 const futuresStore = useFuturesStore()
 const userStore = useUserStore()
 const subscribe = quoteSocket.createSubscribe()
 
+const title = getQueryString('title')
+const titleName = computed(() => title ? decodeURIComponent(title) : props.marketSection?.displayname ?? '订单点价')
+
 const { dataList } = useRequest(queryQuoteGoodsList, {
     params: {
         usertype: userStore.userType ?? 0,

+ 11 - 3
src/packages/mobile/views/spot/list/Index.vue

@@ -1,7 +1,7 @@
 <template>
     <app-view class="spot-list">
         <template #header>
-            <app-navbar title="现货挂牌" :show-back-button="showBackButton">
+            <app-navbar :title="titleName" :show-back-button="showBackButton">
                 <template #right>
                     <Icon name="add" size=".4rem" @click="$router.push({ name: 'spot-add' })" />
                     <Icon name="bars" size=".4rem" @click="isWaterfall = !isWaterfall" style="margin-left: .2rem;" />
@@ -62,26 +62,34 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, onActivated } from 'vue'
+import { shallowRef, onActivated, computed, PropType } from 'vue'
 import { Tag, Icon } from 'vant'
 import { getFileUrl } from '@/filters'
+import { useNavigation } from '@mobile/router/navigation'
 import { useRequest } from '@/hooks/request'
 import { queryOrderQuote } from '@/services/api/goods'
 import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
 import Waterfall from '@mobile/components/base/waterfall/index.vue'
 
-defineProps({
+const props = defineProps({
     showBackButton: {
         type: Boolean,
         default: false
     },
+    marketSection: {
+        type: Object as PropType<Model.Marketsectionconfignew>
+    }
 })
 
+const { getQueryString } = useNavigation()
 const isWaterfall = shallowRef(false)
 const error = shallowRef(false)
 const pullRefreshRef = shallowRef()
 const dataList = shallowRef<Model.OrderQuoteRsp[]>([])
 
+const title = getQueryString('title')
+const titleName = computed(() => title ? decodeURIComponent(title) : props.marketSection?.displayname ?? '现货挂牌')
+
 const { loading, pageIndex, pageCount, run } = useRequest(queryOrderQuote, {
     manual: true,
     params: {

+ 10 - 4
src/packages/mobile/views/swap/list/Index.vue

@@ -1,7 +1,7 @@
 <template>
     <app-view>
         <template #header>
-            <app-navbar title="掉期贸易" :show-back-button="showBackButton" />
+            <app-navbar :title="titleName" :show-back-button="showBackButton" />
         </template>
         <app-list :columns="columns" :data-list="tableList" @row-click="rowClick">
             <!-- 商品/代码 -->
@@ -38,7 +38,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, onUnmounted, onActivated } from 'vue'
+import { computed, onUnmounted, onActivated, PropType } from 'vue'
 import { parsePercent, handleNumberValue, formatDecimal } from '@/filters'
 import { useRequest } from '@/hooks/request'
 import { useNavigation } from '@mobile/router/navigation'
@@ -50,19 +50,25 @@ import { showToast } from 'vant'
 import { getUserId } from '@/services/methods/user'
 import { shallowRef } from 'vue'
 
-defineProps({
+const props = defineProps({
     showBackButton: {
         type: Boolean,
         default: false
+    },
+    marketSection: {
+        type: Object as PropType<Model.Marketsectionconfignew>
     }
 })
 
-const { router, setGlobalUrlParams } = useNavigation()
+const { router, getQueryString, setGlobalUrlParams } = useNavigation()
 const futuresStore = useFuturesStore()
 const userStore = useUserStore()
 const subscribe = quoteSocket.createSubscribe()
 const canBankSign = shallowRef(false)
 
+const title = getQueryString('title')
+const titleName = computed(() => title ? decodeURIComponent(title) : props.marketSection?.displayname ?? '掉期贸易')
+
 const { dataList, run } = useRequest(queryQuoteGoodsList, {
     manual: true,
     params: {

+ 16 - 3
src/packages/mobile/views/transfer/list/Index.vue

@@ -1,7 +1,7 @@
 <template>
     <app-view>
         <template #header>
-            <app-navbar title="定金转让" :show-back-button="false" />
+            <app-navbar :title="titleName" :show-back-button="showBackButton" />
         </template>
         <app-list :columns="columns" :data-list="futuresStore.marketGoodsList" @row-click="rowClick">
             <!-- 商品名称/代码 -->
@@ -66,17 +66,30 @@
 </template>
 
 <script lang="ts" setup>
-import { onActivated, onUnmounted } from 'vue'
+import { onActivated, onUnmounted, computed, PropType } from 'vue'
 import { parsePercent, handleNumberValue, formatDecimal } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
 import { useFuturesStore } from '@/stores'
 import quoteSocket from '@/services/websocket/quote'
 import AppList from '@mobile/components/base/list/index.vue'
 
-const { router } = useNavigation()
+const props = defineProps({
+    showBackButton: {
+        type: Boolean,
+        default: false
+    },
+    marketSection: {
+        type: Object as PropType<Model.Marketsectionconfignew>
+    }
+})
+
+const { router, getQueryString } = useNavigation()
 const subscribe = quoteSocket.createSubscribe()
 const futuresStore = useFuturesStore()
 
+const title = getQueryString('title')
+const titleName = computed(() => title ? decodeURIComponent(title) : props.marketSection?.displayname ?? '定金转让')
+
 const columns: Model.TableColumn[] = [
     { prop: 'goodsname', label: '商品名称/代码' },
     { prop: 'bid', label: '买价' },

+ 1 - 1
src/packages/pc/views/footer/goods/trade/index.vue

@@ -67,7 +67,7 @@ const tableColumns = ref<Model.TableColumn[]>([
     { prop: 'charge', label: '手续费' },
     { prop: 'closepl', label: '平仓盈亏' },
     { prop: 'tradeid', label: '成交单号' },
-    { prop: 'matchaccountid', label: '成交对手' },
+    //{ prop: 'matchaccountid', label: '成交对手' },
     { prop: 'tradetime', label: '成交时间' }
 ])
 

+ 12 - 26
src/packages/pc/views/market/trade/index.vue

@@ -1,6 +1,6 @@
 <!-- 根据市场板块动态配置 -->
 <template>
-    <app-tabs class="app-tabs--primary" :data-list="tabList" prop-label="marketsectionname" @change="onTabChange">
+    <app-tabs class="app-tabs--primary" :data-list="marketSections" prop-label="marketsectionname" @change="onTabChange">
         <app-tabs class="app-tabs--primary" :data-list="marketList" :data-index="marketIndex" direction="bottom"
             prop-label="displayname" @change="onMarketChange">
             <component :is="componentMap.get(componentId)" v-if="componentId" />
@@ -9,10 +9,9 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, defineAsyncComponent, computed, onUnmounted } from 'vue'
-import { useRequest } from '@/hooks/request'
-import { getMarketSections } from '@/services/api/market'
-import { useFuturesStore, useUserStore } from '@/stores'
+import { shallowRef, defineAsyncComponent, onUnmounted } from 'vue'
+import { useMarketSection } from '@/business/market'
+import { useFuturesStore } from '@/stores'
 import AppTabs from '@/components/base/tabs/index.vue'
 import quoteSocket from '@/services/websocket/quote'
 
@@ -25,38 +24,25 @@ const componentMap = new Map<string, unknown>([
     ['tradeModel_99', defineAsyncComponent(() => import('./market/index.vue'))], // 参考行情
 ])
 
-const userStore = useUserStore()
 const futuresStore = useFuturesStore()
-const marketList = shallowRef<Model.GetMarketSectionsRsp['marketsectionconfignews']>([])
+const marketList = shallowRef<Model.MarketSectionsRsp['marketsectionconfignews']>([])
 const marketIndex = shallowRef(0)
 const componentId = shallowRef('')
 
 const subscribe = quoteSocket.createSubscribe()
 
-const { dataList } = useRequest(getMarketSections, {
-    onFinally: () => {
-        const [firstTab] = tabList.value
-        if (firstTab) {
-            onTabChange(0)
-        }
+// 获取市场板块
+const { marketSections } = useMarketSection(() => {
+    const [firstTab] = marketSections.value
+    if (firstTab) {
+        onTabChange(0)
     }
 })
 
-// 板块标签列表
-const tabList = computed(() => {
-    const ids = userStore.userData.markets.map((e) => e.marketid.toString())
-    // 过滤掉没有市场权限的板块
-    return dataList.value.filter((item) => item.marketsectionconfignews.some((e) => {
-        const arr = e.marketids.split(',')
-        e.marketids = arr.filter((id) => ids.includes(id)).join(',')
-        return e.marketids
-    }))
-})
-
 // 切换板块
 const onTabChange = (index: number) => {
-    const item = tabList.value[index]
-    marketList.value = item.marketsectionconfignews.filter((e) => e.marketids)
+    const item = marketSections.value[index]
+    marketList.value = item.marketsectionconfignews
     marketIndex.value = 0
     componentId.value = ''
     onMarketChange(0)

+ 1 - 1
src/packages/pc/views/query/trade/goods/history/index.vue

@@ -57,7 +57,7 @@ const tableColumns = shallowRef<Model.TableColumn[]>([
     { prop: 'charge', label: '手续费' },
     { prop: 'closepl', label: '平仓盈亏' },
     { prop: 'tradeid', label: '成交单号' },
-    { prop: 'matchaccountid', label: '成交对手' },
+    //{ prop: 'matchaccountid', label: '成交对手' },
     { prop: 'tradetime', label: '成交时间' },
 ])
 

+ 1 - 1
src/packages/pc/views/query/trade/goods/list/index.vue

@@ -44,7 +44,7 @@ const tableColumns = shallowRef<Model.TableColumn[]>([
     { prop: 'charge', label: '手续费' },
     { prop: 'closepl', label: '平仓盈亏' },
     { prop: 'tradeid', label: '成交单号' },
-    { prop: 'matchaccountid', label: '成交对手' },
+    //{ prop: 'matchaccountid', label: '成交对手' },
     { prop: 'tradetime', label: '成交时间' },
 ])
 </script>

+ 1 - 1
src/packages/qdhs/views/goods/detail/index.vue

@@ -39,7 +39,7 @@ import { BuyOrSell } from '@/constants/order'
 import { useFuturesStore } from '@/stores'
 
 const Price = defineAsyncComponent(() => import('@mobile/components/modules/quote/price/index.vue'))
-const Chart = defineAsyncComponent(() => import('@mobile/components/modules/quote/chart/index.vue'))
+const Chart = defineAsyncComponent(() => import('@mobile/components/modules/hqchart/index.vue'))
 const Forex = defineAsyncComponent(() => import('@mobile/components/modules/quote/forex/index.vue'))
 const Tik = defineAsyncComponent(() => import('@mobile/components/modules/quote/tik/index.vue'))
 

+ 61 - 3
src/packages/qdhs/views/home/Index.vue

@@ -1,10 +1,34 @@
 <template>
-  <LayoutHome :tabs="tabList" ios-update-url="https://itunes.apple.com/lookup?id=6468948889"/>
+  <div class="home g-flex">
+    <router-view v-slot="{ Component }">
+      <RouterTransition :css="cssTransition">
+        <!-- 缓存所有组件 -->
+        <keep-alive>
+          <component class="g-flex__body" :is="Component" />
+        </keep-alive>
+      </RouterTransition>
+    </router-view>
+    <app-tabbar :data-list="tabList" :data-index="currentTab" @click="onTabClick" />
+    <app-updater ios-update-url="https://itunes.apple.com/lookup?id=6468948889" />
+  </div>
 </template>
 
 <script lang="ts" setup>
+import { shallowRef, nextTick, watch, onMounted, onActivated, computed } from 'vue'
 import { Tabbar } from '@mobile/components/base/tabbar/types'
-import LayoutHome from '@mobile/components/layouts/home/index.vue'
+import { useNavigation } from '@mobile/router/navigation'
+import { useLoginStore, useFuturesStore } from '@/stores'
+import AppTabbar from '@mobile/components/base/tabbar/index.vue'
+import AppUpdater from '@mobile/components/base/updater/index.vue'
+import RouterTransition from '@mobile/components/base/router-transition/index.vue'
+
+const { route, routerTo } = useNavigation()
+const loginStore = useLoginStore()
+const futuresStore = useFuturesStore()
+const cssTransition = shallowRef(true) // 是否使用css动画
+const currentTab = shallowRef(0)
+
+const tabIndex = computed(() => tabList.findIndex((e) => e.name === route.name))
 
 const tabList: Tabbar[] = [
   {
@@ -32,4 +56,38 @@ const tabList: Tabbar[] = [
     activeIcon: 'g-icon-mine--fill',
   }
 ]
-</script>
+
+const onTabClick = (index: number) => {
+  const { name } = tabList[index]
+  if (index === 0 || loginStore.token) {
+    routerTo(name, true)
+  } else {
+    routerTo('user-login')
+  }
+}
+
+watch(() => route.name, () => {
+  if (tabIndex.value > -1) {
+    cssTransition.value = false
+    currentTab.value = tabIndex.value
+  }
+  nextTick(() => {
+    cssTransition.value = true
+  })
+})
+
+onMounted(() => {
+  currentTab.value = tabIndex.value
+})
+
+onActivated(() => {
+  // 页面显示时刷新盘面(待优化)
+  if (loginStore.token && futuresStore.goodsList.length) {
+    futuresStore.getQuoteDay()
+  }
+})
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 14 - 0
src/packages/qdhs/views/home/index.less

@@ -0,0 +1,14 @@
+.home {
+    .app-tabbar {
+        background: var(--tabbar-background) !important;
+        margin-top: auto;
+
+        .app-iconfont {
+            color: var(--tabbar-icon);
+
+            &.is-active {
+                color: var(--tabbar-icon-active);
+            }
+        }
+    }
+}

+ 8 - 32
src/packages/qxst/router/index.ts

@@ -1,6 +1,7 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import { useLoginStore } from '@/stores'
 import { clearPending } from '@/services/http/pending'
+import { homeRoutes, pageRoutes } from '@mobile/router/section'
 import service from '@/services'
 import Page from '@mobile/components/layouts/page/index.vue'
 import animateRouter from '@mobile/router/animateRouter'
@@ -31,31 +32,24 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: '',
         name: 'home',
-        component: () => import('../views/home/Index.vue'),
+        component: () => import('@mobile/views/home/Index.vue'),
         children: [
           {
             path: '',
             name: 'home-index',
-            component: () => import('../views/home/main/Index.vue'),
+            component: () => import('@mobile/views/home/main/Index.vue'),
             meta: {
               ignoreAuth: true,
             },
           },
           {
-            path: '50101',
-            name: 'home-50101',
-            component: () => import('@mobile/views/goods/list/Index.vue'),
-            props: {
-              marketId: 50101
-            }
-          },
-          {
             path: 'mine',
             name: 'home-mine',
             component: () => import('../views/mine/Index.vue'),
-          }
+          },
+          ...homeRoutes
         ]
-      },
+      }
     ],
   },
   {
@@ -148,25 +142,6 @@ const routes: Array<RouteRecordRaw> = [
     ],
   },
   {
-    path: '/goods',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'goods-detail',
-        component: () => import('@mobile/views/goods/detail/Index.vue'),
-        props: {
-          showMore: false
-        }
-      },
-      {
-        path: 'trade',
-        name: 'goods-trade',
-        component: () => import('@mobile/views/goods/trade/index.vue'),
-      },
-    ],
-  },
-  {
     path: '/bank',
     component: Page,
     children: [
@@ -295,7 +270,8 @@ const routes: Array<RouteRecordRaw> = [
         },
       },
     ]
-  }
+  },
+  ...pageRoutes
 ]
 
 const router = animateRouter.create({

+ 0 - 29
src/packages/qxst/views/home/Index.vue

@@ -1,29 +0,0 @@
-<template>
-  <LayoutHome :tabs="tabList" />
-</template>
-
-<script lang="ts" setup>
-import { Tabbar } from '@mobile/components/base/tabbar/types'
-import LayoutHome from '@mobile/components/layouts/home/index.vue'
-
-const tabList: Tabbar[] = [
-  {
-    name: 'home-index',
-    label: '首页',
-    icon: 'g-icon-home--line',
-    activeIcon: 'g-icon-home--fill',
-  },
-  {
-    name: 'home-50101',
-    label: '订单挂牌',
-    icon: 'g-icon-listing--line',
-    activeIcon: 'g-icon-listing--fill',
-  },
-  {
-    name: 'home-mine',
-    label: '我的',
-    icon: 'g-icon-mine--line',
-    activeIcon: 'g-icon-mine--fill',
-  }
-]
-</script>

+ 0 - 67
src/packages/qxst/views/home/main/Index.vue

@@ -1,67 +0,0 @@
-<template>
-  <app-view class="home-main">
-    <template #header>
-      <app-navbar :title="globalStore.getSystemInfo('appName')" :show-back-button="false" />
-    </template>
-    <Banner :data-list="topBanners" />
-    <PullRefresh class="home-main__container" v-model="refreshing" @refresh="onRefresh">
-      <app-block>
-        <Cell title="通知公告" value="更多" :to="{ name: 'notice-list' }" icon="volume" is-link />
-      </app-block>
-      <app-block class="home-main__news">
-        <CellGroup class="article">
-          <Cell class="home-main__titlebar" title="市场资讯" value="更多" icon="fire" :to="{ name: 'news-list' }" is-link />
-          <template v-for="(item, index) in newsList" :key="index">
-            <Cell class="article-item" :title="item.title" :value="formatDate(item.publishdate, 'MM/DD')"
-              :to="{ name: 'news-detail', query: { id: item.id } }" />
-          </template>
-        </CellGroup>
-      </app-block>
-    </PullRefresh>
-  </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from "vue";
-import { Cell, CellGroup, PullRefresh } from "vant";
-import { formatDate } from "@/filters";
-import { queryImageConfigs } from "@/services/api/common";
-import { queryNewTitles } from "@/services/api/news";
-import { useGlobalStore } from '@/stores'
-import Banner from '@mobile/components/base/banner/index.vue'
-
-const globalStore = useGlobalStore()
-const refreshing = shallowRef(false); // 是否处于加载中状态
-const topBanners = shallowRef<string[]>([]); // 轮播图列表
-const newsList = shallowRef<Model.NewTitlesRsp[]>([]); // 资讯列表
-
-// 下拉刷新
-const onRefresh = () => {
-  if (!topBanners.value.length) {
-    queryImageConfigs({
-      data: {
-        imageType: 1,
-      }
-    }).then((res) => {
-      topBanners.value = res.data.map((e) => e.imagepath)
-    })
-  }
-  // 市场资讯
-  queryNewTitles({
-    data: {
-      page: 1,
-      pagesize: 10,
-    }
-  }).then((res) => {
-    newsList.value = res.data
-  }).finally(() => {
-    refreshing.value = false
-  })
-}
-
-onRefresh()
-</script>
-
-<style lang="less">
-@import "./index.less";
-</style>

+ 0 - 89
src/packages/qxst/views/home/main/index.less

@@ -1,89 +0,0 @@
-@import '@mobile/assets/themes/base/mixin.less';
-
-.home-main {
-    &__header {
-        background: linear-gradient(var(--navbar-background), var(--navbar-background) 60%, transparent 60%);
-        padding: .2rem;
-    }
-
-    &__iconbar {
-        ul {
-            display: flex;
-            flex-wrap: wrap;
-            padding-top: .24rem;
-
-            &:last-child {
-                padding-bottom: .24rem;
-            }
-
-            li {
-                display: flex;
-                flex-direction: column;
-                align-items: center;
-                width: calc(~'100% / 4');
-                text-align: center;
-
-                .app-iconfont {
-                    &__icon {
-                        font-size: .8rem;
-                    }
-
-                    &__label {
-                        font-size: .24rem;
-                        margin-top: .1rem;
-                    }
-                }
-            }
-        }
-    }
-
-    &__titlebar {
-        .van-cell__title {
-            font-size: .32rem;
-            font-weight: bold;
-        }
-
-        .van-cell__value {
-            flex: none;
-            color: #666;
-        }
-    }
-
-    &__market {
-        .scrollbar {
-            width: 100%;
-            padding: .2rem;
-        }
-
-        .van-swipe {
-            height: 32px;
-            background-color: #f6f6f6;
-
-            ul {
-                display: flex;
-                justify-content: space-around;
-                align-items: center;
-                height: inherit;
-                font-size: .26rem;
-            }
-        }
-    }
-
-    &__news {
-        .article {
-            &-item {
-                .van-cell__title {
-                    span {
-                        .mixin-text-overflow()
-                    }
-                }
-
-                .van-cell__value {
-                    flex: initial;
-                    font-size: .24rem;
-                    margin-left: .48rem;
-                }
-            }
-        }
-    }
-}

+ 1 - 1
src/packages/sbyj/views/market/detail/index.vue

@@ -134,7 +134,7 @@ const { formData, formSubmit } = useOrder()
 const futuresStore = useFuturesStore()
 const userStore = useUserStore()
 const formRef = shallowRef<FormInstance>()
-const goodscode = getQueryString('goodscode')
+const goodscode = getQueryString('goodscode') ?? ''
 const quote = futuresStore.getGoodsQuote(goodscode)
 const qtyStep = shallowRef(1) // 数量步长
 const subscribe = quoteSocket.createSubscribe()

+ 1 - 1
src/packages/sbyj/views/order/close/index.vue

@@ -38,7 +38,7 @@
                                 <span>{{ formatDecimal(item.closeprice) }}</span>
                             </li>
                             <li>
-                                <span>终止余</span>
+                                <span>终止余</span>
                                 <span>{{ formatDecimal(item.closepl) }}</span>
                             </li>
                         </ul>

+ 19 - 75
src/packages/tc/router/index.ts

@@ -1,6 +1,7 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import { useLoginStore } from '@/stores'
 import { clearPending } from '@/services/http/pending'
+import { homeRoutes, pageRoutes } from '@mobile/router/section'
 import service from '@/services'
 import Page from '@mobile/components/layouts/page/index.vue'
 import animateRouter from '@mobile/router/animateRouter'
@@ -31,45 +32,24 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: '',
         name: 'home',
-        component: () => import('../views/home/Index.vue'),
+        component: () => import('@mobile/views/home/Index.vue'),
         children: [
           {
             path: '',
             name: 'home-index',
-            component: () => import('../views/home/main/Index.vue'),
+            component: () => import('@mobile/views/home/main/Index.vue'),
             meta: {
               ignoreAuth: true,
             },
           },
           {
-            path: 'ballot',
-            name: 'home-ballot',
-            component: () => import('@mobile/views/ballot/list/Index.vue'),
-            props: {
-              title: '新品发布'
-            }
-          },
-          {
-            path: 'transfer',
-            name: 'home-transfer',
-            component: () => import('@mobile/views/transfer/list/Index.vue'),
-          },
-          {
-            path: '16201',
-            name: 'home-16201',
-            component: () => import('@mobile/views/goods/list/Index.vue'),
-            props: {
-              title: '全款挂牌',
-              marketId: 16201
-            }
-          },
-          {
             path: 'mine',
             name: 'home-mine',
             component: () => import('../views/mine/Index.vue'),
-          }
+          },
+          ...homeRoutes
         ]
-      },
+      }
     ],
   },
   {
@@ -151,54 +131,6 @@ const routes: Array<RouteRecordRaw> = [
     ],
   },
   {
-    path: '/goods',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'goods-detail',
-        component: () => import('@mobile/views/goods/detail/Index.vue'),
-      },
-      {
-        path: 'trade',
-        name: 'goods-trade',
-        component: () => import('@mobile/views/goods/trade/index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/transfer',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'transfer-detail',
-        component: () => import('@mobile/views/transfer/detail/Index.vue'),
-      },
-      {
-        path: 'detail2',
-        name: 'transfer-detail2',
-        component: () => import('@mobile/views/transfer/detail2/index.vue'),
-      },
-      {
-        path: 'delisting',
-        name: 'transfer-delisting',
-        component: () => import('@mobile/views/transfer/delisting/Index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/ballot',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'ballot-detail',
-        component: () => import('@mobile/views/ballot/detail/Index.vue'),
-      },
-    ],
-  },
-  {
     path: '/bank',
     component: Page,
     children: [
@@ -293,6 +225,17 @@ const routes: Array<RouteRecordRaw> = [
     ],
   },
   {
+    path: '/report',
+    component: Page,
+    children: [
+      {
+        path: '',
+        name: 'report',
+        component: () => import('@mobile//views/report/index.vue'),
+      }
+    ]
+  },
+  {
     path: '/rules',
     component: Page,
     children: [
@@ -337,7 +280,8 @@ const routes: Array<RouteRecordRaw> = [
         },
       },
     ]
-  }
+  },
+  ...pageRoutes
 ]
 
 const router = animateRouter.create({

+ 0 - 41
src/packages/tc/views/home/Index.vue

@@ -1,41 +0,0 @@
-<template>
-  <LayoutHome :tabs="tabList" />
-</template>
-
-<script lang="ts" setup>
-import { Tabbar } from '@mobile/components/base/tabbar/types'
-import LayoutHome from '@mobile/components/layouts/home/index.vue'
-
-const tabList: Tabbar[] = [
-  {
-    name: 'home-index',
-    label: '首页',
-    icon: 'g-icon-home--line',
-    activeIcon: 'g-icon-home--fill',
-  },
-  {
-    name: 'home-ballot',
-    label: '新品发布',
-    icon: 'g-icon-presale--line',
-    activeIcon: 'g-icon-presale--fill',
-  },
-  {
-    name: 'home-transfer',
-    label: '定金转让',
-    icon: 'g-icon-transfer--line',
-    activeIcon: 'g-icon-transfer--fill',
-  },
-  {
-    name: 'home-16201',
-    label: '全款挂牌',
-    icon: 'g-icon-listing--line',
-    activeIcon: 'g-icon-listing--fill',
-  },
-  {
-    name: 'home-mine',
-    label: '我的',
-    icon: 'g-icon-mine--line',
-    activeIcon: 'g-icon-mine--fill',
-  }
-]
-</script>

+ 0 - 67
src/packages/tc/views/home/main/Index.vue

@@ -1,67 +0,0 @@
-<template>
-  <app-view class="home-main">
-    <template #header>
-      <app-navbar :title="globalStore.getSystemInfo('appName')" :show-back-button="false" />
-    </template>
-    <Banner :data-list="topBanners" />
-    <PullRefresh class="home-main__container" v-model="refreshing" @refresh="onRefresh">
-      <app-block>
-        <Cell title="通知公告" value="更多" :to="{ name: 'notice-list' }" icon="volume" is-link />
-      </app-block>
-      <app-block class="home-main__news">
-        <CellGroup class="article">
-          <Cell class="home-main__titlebar" title="市场资讯" value="更多" icon="fire" :to="{ name: 'news-list' }" is-link />
-          <template v-for="(item, index) in newsList" :key="index">
-            <Cell class="article-item" :title="item.title" :value="formatDate(item.publishdate, 'MM/DD')"
-              :to="{ name: 'news-detail', query: { id: item.id } }" />
-          </template>
-        </CellGroup>
-      </app-block>
-    </PullRefresh>
-  </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from "vue";
-import { Cell, CellGroup, PullRefresh } from "vant";
-import { formatDate } from "@/filters";
-import { queryImageConfigs } from "@/services/api/common";
-import { queryNewTitles } from "@/services/api/news";
-import {  useGlobalStore } from '@/stores'
-import Banner from '@mobile/components/base/banner/index.vue'
-
-const globalStore = useGlobalStore()
-const refreshing = shallowRef(false); // 是否处于加载中状态
-const topBanners = shallowRef<string[]>([]); // 轮播图列表
-const newsList = shallowRef<Model.NewTitlesRsp[]>([]); // 资讯列表
-
-// 下拉刷新
-const onRefresh = () => {
-  if (!topBanners.value.length) {
-    queryImageConfigs({
-      data: {
-        imageType: 1,
-      }
-    }).then((res) => {
-      topBanners.value = res.data.map((e) => e.imagepath)
-    })
-  }
-  // 市场资讯
-  queryNewTitles({
-    data: {
-      page: 1,
-      pagesize: 10,
-    }
-  }).then((res) => {
-    newsList.value = res.data
-  }).finally(() => {
-    refreshing.value = false
-  })
-}
-
-onRefresh()
-</script>
-
-<style lang="less">
-@import "./index.less";
-</style>

+ 0 - 123
src/packages/tc/views/home/main/index.less

@@ -1,123 +0,0 @@
-@import '@mobile/assets/themes/base/mixin.less';
-
-.home-main {
-    &__header {
-        background: linear-gradient(var(--navbar-background), var(--navbar-background) 60%, transparent 60%);
-        padding: .2rem;
-    }
-
-    &__iconbar {
-        ul {
-            display: flex;
-            flex-wrap: wrap;
-            padding-top: .24rem;
-
-            &:last-child {
-                padding-bottom: .24rem;
-            }
-
-            li {
-                display: flex;
-                flex-direction: column;
-                align-items: center;
-                width: calc(~'100% / 4');
-                text-align: center;
-
-                .g-icon {
-                    width: .72rem;
-                    height: .72rem;
-                    font-size: .44rem;
-                    color: #fff;
-                    border-radius: 50%;
-                    margin-bottom: .08rem;
-
-                    &-listing--line {
-                        &.m50101 {
-                            background-color: #72c990;
-                        }
-
-                        &.m16201 {
-                            background-color: #8272c9;
-                        }
-                    }
-
-                    &-presale--line {
-                        background-color: #9d6969;
-                    }
-
-                    &-transfer--line {
-                        background-color: #ebc413;
-                    }
-                }
-            }
-        }
-    }
-
-    &__titlebar {
-        .van-cell__title {
-            display: flex;
-            align-items: center;
-            line-height: 1;
-            font-size: .32rem;
-            font-weight: bold;
-
-            img {
-                width: .32rem;
-                height: .32rem;
-                margin-right: .1rem;
-            }
-
-            span {
-                +span {
-                    color: #999;
-                    font-size: .26rem;
-                    font-weight: normal;
-                    margin-left: .1rem;
-                }
-            }
-        }
-
-        .van-cell__value {
-            flex: none;
-            color: #666;
-        }
-    }
-
-    &__market {
-        .scrollbar {
-            width: 100%;
-            padding: .2rem;
-        }
-
-        .van-swipe {
-            height: 32px;
-            background-color: #f6f6f6;
-
-            ul {
-                display: flex;
-                justify-content: space-around;
-                align-items: center;
-                height: inherit;
-                font-size: .26rem;
-            }
-        }
-    }
-
-    &__news {
-        .article {
-            &-item {
-                .van-cell__title {
-                    span {
-                        .mixin-text-overflow()
-                    }
-                }
-
-                .van-cell__value {
-                    flex: initial;
-                    font-size: .24rem;
-                    margin-left: .48rem;
-                }
-            }
-        }
-    }
-}

+ 8 - 58
src/packages/tjmd/router/index.ts

@@ -1,6 +1,7 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import { useLoginStore } from '@/stores'
 import { clearPending } from '@/services/http/pending'
+import { homeRoutes, pageRoutes } from '@mobile/router/section'
 import service from '@/services'
 import Page from '@mobile/components/layouts/page/index.vue'
 import animateRouter from '@mobile/router/animateRouter'
@@ -31,7 +32,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: '',
         name: 'home',
-        component: () => import('../views/home/Index.vue'),
+        component: () => import('@mobile/views/home/Index.vue'),
         children: [
           {
             path: '',
@@ -42,28 +43,14 @@ const routes: Array<RouteRecordRaw> = [
             },
           },
           {
-            path: 'swap',
-            name: 'home-swap',
-            component: () => import('@mobile/views/swap/list/Index.vue'),
-          },
-          {
-            path: 'spot',
-            name: 'home-spot',
-            component: () => import('@mobile/views/spot/list/Index.vue'),
-          },
-          {
-            path: 'market',
-            name: 'home-market',
-            component: () => import('@mobile/views/market/list/Index.vue'),
-          },
-          {
             path: 'mine',
             name: 'home-mine',
             component: () => import('../views/mine/Index.vue'),
-          }
+          },
+          ...homeRoutes
         ]
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/user',
@@ -160,44 +147,6 @@ const routes: Array<RouteRecordRaw> = [
     ],
   },
   {
-    path: '/market',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'market-detail',
-        component: () => import('@mobile/views/market/detail/Index.vue'),
-      }
-    ]
-  },
-  {
-    path: '/swap',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'swap-detail',
-        component: () => import('@mobile/views/swap/detail/Index.vue'),
-      }
-    ]
-  },
-  {
-    path: '/spot',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'spot-detail',
-        component: () => import('@mobile/views/spot/detail/Index.vue'),
-      },
-      {
-        path: 'add',
-        name: 'spot-add',
-        component: () => import('@mobile/views/spot/add/index.vue'),
-      },
-    ],
-  },
-  {
     path: '/bank',
     component: Page,
     children: [
@@ -339,7 +288,8 @@ const routes: Array<RouteRecordRaw> = [
         }
       }
     ]
-  }
+  },
+  ...pageRoutes
 ]
 
 const router = animateRouter.create({

+ 0 - 41
src/packages/tjmd/views/home/Index.vue

@@ -1,41 +0,0 @@
-<template>
-  <LayoutHome :tabs="tabList" ios-update-url="" />
-</template>
-
-<script lang="ts" setup>
-import { Tabbar } from '@mobile/components/base/tabbar/types'
-import LayoutHome from '@mobile/components/layouts/home/index.vue'
-
-const tabList: Tabbar[] = [
-  {
-    name: 'home-index',
-    label: '首页',
-    icon: 'g-icon-home--line',
-    activeIcon: 'g-icon-home--fill',
-  },
-  {
-    name: 'home-swap',
-    label: '掉期交易',
-    icon: 'g-icon-swap--line',
-    activeIcon: 'g-icon-swap--fill',
-  },
-  {
-    name: 'home-spot',
-    label: '现货挂牌',
-    icon: 'g-icon-spot--line',
-    activeIcon: 'g-icon-spot--fill',
-  },
-  {
-    name: 'home-market',
-    label: '参考行情',
-    icon: 'g-icon-quote--line',
-    activeIcon: 'g-icon-quote--fill',
-  },
-  {
-    name: 'home-mine',
-    label: '我的',
-    icon: 'g-icon-mine--line',
-    activeIcon: 'g-icon-mine--fill',
-  }
-]
-</script>

+ 9 - 17
src/packages/tjmd/views/home/main/Index.vue

@@ -4,7 +4,7 @@
       <app-navbar :title="globalStore.getSystemInfo('appName')" :show-back-button="false" />
     </template>
     <Banner :data-list="topBanners" />
-    <PullRefresh class="home-main__container" v-model="refreshing" @refresh="onRefresh">
+    <div class="home-main__container">
       <app-block>
         <Cell title="通知公告" value="更多" :to="{ name: 'notice-list' }" icon="volume" is-link />
       </app-block>
@@ -32,13 +32,13 @@
         </Swipe>
         <component :is="LineChart" :goodscode="selectedGoods.refgoodscode" v-if="showChart && selectedGoods" />
       </app-block>
-    </PullRefresh>
+    </div>
   </app-view>
 </template>
 
 <script lang="ts" setup>
 import { shallowRef, defineAsyncComponent, computed, nextTick, watch } from 'vue'
-import { Cell, PullRefresh, Swipe, SwipeItem } from 'vant'
+import { Cell, Swipe, SwipeItem } from 'vant'
 import { parsePercent, handleNumberValue, formatDecimal } from '@/filters'
 import { queryQuoteGoodsList } from '@/services/api/swap'
 import { queryImageConfigs } from '@/services/api/common'
@@ -52,7 +52,6 @@ const subscribe = quoteSocket.createSubscribe()
 const globalStore = useGlobalStore()
 const userStore = useUserStore()
 const futuresStore = useFuturesStore()
-const refreshing = shallowRef(false) // 是否处于加载中状态
 const topBanners = shallowRef<string[]>([]) // 轮播图列表
 const goodsList = shallowRef<Model.QuoteGoodsListRsp[]>([]) // 掉期商品列表
 const selectedGoods = shallowRef<Model.QuoteGoodsListRsp>() // 选中的掉期商品
@@ -91,20 +90,13 @@ const onTabChange = (item: unknown) => {
   })
 }
 
-// 下拉刷新
-const onRefresh = () => {
-  if (!topBanners.value.length) {
-    queryImageConfigs({
-      data: {
-        imageType: 1,
-      }
-    }).then((res) => {
-      topBanners.value = res.data.map((e) => e.imagepath)
-    })
+queryImageConfigs({
+  data: {
+    imageType: 1,
   }
-}
-
-onRefresh()
+}).then((res) => {
+  topBanners.value = res.data.map((e) => e.imagepath)
+})
 
 watch(() => userStore.accountName, (accountName) => {
   if (accountName) {

+ 9 - 82
src/packages/zrwyt/router/index.ts

@@ -1,6 +1,7 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import { useLoginStore } from '@/stores'
 import { clearPending } from '@/services/http/pending'
+import { homeRoutes, pageRoutes } from '@mobile/router/section'
 import service from '@/services'
 import Page from '@mobile/components/layouts/page/index.vue'
 import animateRouter from '@mobile/router/animateRouter'
@@ -31,43 +32,25 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: '',
         name: 'home',
-        component: () => import('../views/home/Index.vue'),
+        component: () => import('@mobile/views/home/Index.vue'),
         children: [
           {
             path: '',
             name: 'home-index',
-            component: () => import('../views/home/main/Index.vue'),
+            component: () => import('@mobile/views/home/main/Index.vue'),
             meta: {
               ignoreAuth: true,
             },
           },
           {
-            path: 'ballot',
-            name: 'home-ballot',
-            component: () => import('@mobile/views/ballot/list/Index.vue'),
-          },
-          {
-            path: 'transfer',
-            name: 'home-transfer',
-            component: () => import('@mobile/views/transfer/list/Index.vue'),
-          },
-          {
-            path: '16201',
-            name: 'home-16201',
-            component: () => import('@mobile/views/goods/list/Index.vue'),
-            props: {
-              title: '全款挂牌',
-              marketId: 16201
-            }
-          },
-          {
             path: 'mine',
             name: 'home-mine',
             component: () => import('../views/mine/Index.vue'),
-          }
+          },
+          ...homeRoutes
         ]
-      },
-    ],
+      }
+    ]
   },
   {
     path: '/user',
@@ -164,63 +147,6 @@ const routes: Array<RouteRecordRaw> = [
     ],
   },
   {
-    path: '/goods',
-    component: Page,
-    children: [
-      {
-        path: '50101',
-        name: 'goods-50101',
-        component: () => import('@mobile/views/goods/list/Index.vue'),
-        props: {
-          marketId: 50101,
-          showBackButton: true
-        }
-      },
-      {
-        path: 'detail',
-        name: 'goods-detail',
-        component: () => import('@mobile/views/goods/detail/Index.vue'),
-      },
-      {
-        path: 'trade',
-        name: 'goods-trade',
-        component: () => import('@mobile/views/goods/trade/index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/transfer',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'transfer-detail',
-        component: () => import('@mobile/views/transfer/detail/Index.vue'),
-      },
-      {
-        path: 'detail2',
-        name: 'transfer-detail2',
-        component: () => import('@mobile/views/transfer/detail2/index.vue'),
-      },
-      {
-        path: 'delisting',
-        name: 'transfer-delisting',
-        component: () => import('@mobile/views/transfer/delisting/Index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/ballot',
-    component: Page,
-    children: [
-      {
-        path: 'detail',
-        name: 'ballot-detail',
-        component: () => import('@mobile/views/ballot/detail/Index.vue'),
-      },
-    ],
-  },
-  {
     path: '/bank',
     component: Page,
     children: [
@@ -364,7 +290,8 @@ const routes: Array<RouteRecordRaw> = [
         },
       },
     ]
-  }
+  },
+  ...pageRoutes
 ]
 
 const router = animateRouter.create({

+ 0 - 41
src/packages/zrwyt/views/home/Index.vue

@@ -1,41 +0,0 @@
-<template>
-  <LayoutHome :tabs="tabList" />
-</template>
-
-<script lang="ts" setup>
-import { Tabbar } from '@mobile/components/base/tabbar/types'
-import LayoutHome from '@mobile/components/layouts/home/index.vue'
-
-const tabList: Tabbar[] = [
-  {
-    name: 'home-index',
-    label: '首页',
-    icon: 'g-icon-home--line',
-    activeIcon: 'g-icon-home--fill',
-  },
-  // {
-  //   name: 'home-ballot',
-  //   label: '预售中签',
-  //   icon: 'g-icon-presale--line',
-  //   activeIcon: 'g-icon-presale--fill',
-  // },
-  // {
-  //   name: 'home-transfer',
-  //   label: '定金转让',
-  //   icon: 'g-icon-transfer--line',
-  //   activeIcon: 'g-icon-transfer--fill',
-  // },
-  {
-    name: 'home-16201',
-    label: '全款挂牌',
-    icon: 'g-icon-listing--line',
-    activeIcon: 'g-icon-listing--fill',
-  },
-  {
-    name: 'home-mine',
-    label: '我的',
-    icon: 'g-icon-mine--line',
-    activeIcon: 'g-icon-mine--fill',
-  }
-]
-</script>

+ 0 - 96
src/packages/zrwyt/views/home/main/Index.vue

@@ -1,96 +0,0 @@
-<template>
-  <app-view class="home-main">
-    <template #header>
-      <app-navbar :title="globalStore.getSystemInfo('appName')" :show-back-button="false" />
-    </template>
-    <Banner :data-list="topBanners" />
-    <PullRefresh class="home-main__container" v-model="refreshing" @refresh="onRefresh">
-      <app-block>
-        <Cell title="通知公告" value="更多" :to="{ name: 'notice-list' }" icon="volume" is-link />
-      </app-block>
-      <!-- <app-block class="home-main__iconbar bg">
-        <ul>
-          <li @click="switchTab('home-ballot')">
-            <Iconfont label-direction="bottom" icon="g-icon-presale--line">预售中签</Iconfont>
-          </li>
-          <li @click="switchTab('home-transfer')">
-            <Iconfont label-direction="bottom" icon="g-icon-transfer--line">定金转让</Iconfont>
-          </li>
-          <li @click="switchTab('home-16201')">
-            <Iconfont label-direction="bottom" icon="g-icon-listing--line m16201">全款挂牌</Iconfont>
-          </li>
-          <li @click="routerTo('goods-50101')">
-            <Iconfont label-direction="bottom" icon="g-icon-listing--line m50101">订单挂牌</Iconfont>
-          </li>
-        </ul>
-      </app-block> -->
-      <app-block class="home-main__news">
-        <CellGroup class="article">
-          <Cell class="home-main__titlebar" title="市场资讯" value="更多" icon="fire" :to="{ name: 'news-list' }" is-link />
-          <template v-for="(item, index) in newsList" :key="index">
-            <Cell class="article-item" :title="item.title" :value="formatDate(item.publishdate, 'MM/DD')"
-              :to="{ name: 'news-detail', query: { id: item.id } }" />
-          </template>
-        </CellGroup>
-      </app-block>
-    </PullRefresh>
-  </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from "vue";
-import { Cell, CellGroup, PullRefresh } from "vant";
-import { formatDate } from "@/filters";
-import { useNavigation } from '@mobile/router/navigation';
-import { queryImageConfigs } from "@/services/api/common";
-import { queryNewTitles } from "@/services/api/news";
-import { useLoginStore, useGlobalStore } from '@/stores'
-import Banner from '@mobile/components/base/banner/index.vue'
-import Iconfont from '@/components/base/iconfont/index.vue'
-
-const globalStore = useGlobalStore()
-const loginStore = useLoginStore();
-const { routerTo } = useNavigation();
-const refreshing = shallowRef(false); // 是否处于加载中状态
-const topBanners = shallowRef<string[]>([]); // 轮播图列表
-const newsList = shallowRef<Model.NewTitlesRsp[]>([]); // 资讯列表
-
-// 跳转导航页面
-const switchTab = (routeName: string) => {
-  if (loginStore.token) {
-    routerTo(routeName, true)
-  } else {
-    routerTo('user-login')
-  }
-}
-
-// 下拉刷新
-const onRefresh = () => {
-  if (!topBanners.value.length) {
-    queryImageConfigs({
-      data: {
-        imageType: 1,
-      }
-    }).then((res) => {
-      topBanners.value = res.data.map((e) => e.imagepath)
-    })
-  }
-  // 市场资讯
-  queryNewTitles({
-    data: {
-      page: 1,
-      pagesize: 10,
-    }
-  }).then((res) => {
-    newsList.value = res.data
-  }).finally(() => {
-    refreshing.value = false
-  })
-}
-
-onRefresh()
-</script>
-
-<style lang="less">
-@import "./index.less";
-</style>

+ 0 - 123
src/packages/zrwyt/views/home/main/index.less

@@ -1,123 +0,0 @@
-@import '@mobile/assets/themes/base/mixin.less';
-
-.home-main {
-    &__header {
-        background: linear-gradient(var(--navbar-background), var(--navbar-background) 60%, transparent 60%);
-        padding: .2rem;
-    }
-
-    &__iconbar {
-        ul {
-            display: flex;
-            flex-wrap: wrap;
-            padding-top: .24rem;
-
-            &:last-child {
-                padding-bottom: .24rem;
-            }
-
-            li {
-                display: flex;
-                flex-direction: column;
-                align-items: center;
-                width: calc(~'100% / 4');
-                text-align: center;
-
-                .g-icon {
-                    width: .72rem;
-                    height: .72rem;
-                    font-size: .44rem;
-                    color: #fff;
-                    border-radius: 50%;
-                    margin-bottom: .08rem;
-
-                    &-listing--line {
-                        &.m50101 {
-                            background-color: #72c990;
-                        }
-
-                        &.m16201 {
-                            background-color: #8272c9;
-                        }
-                    }
-
-                    &-presale--line {
-                        background-color: #9d6969;
-                    }
-
-                    &-transfer--line {
-                        background-color: #ebc413;
-                    }
-                }
-            }
-        }
-    }
-
-    &__titlebar {
-        .van-cell__title {
-            display: flex;
-            align-items: center;
-            line-height: 1;
-            font-size: .32rem;
-            font-weight: bold;
-
-            img {
-                width: .32rem;
-                height: .32rem;
-                margin-right: .1rem;
-            }
-
-            span {
-                +span {
-                    color: #999;
-                    font-size: .26rem;
-                    font-weight: normal;
-                    margin-left: .1rem;
-                }
-            }
-        }
-
-        .van-cell__value {
-            flex: none;
-            color: #666;
-        }
-    }
-
-    &__market {
-        .scrollbar {
-            width: 100%;
-            padding: .2rem;
-        }
-
-        .van-swipe {
-            height: 32px;
-            background-color: #f6f6f6;
-
-            ul {
-                display: flex;
-                justify-content: space-around;
-                align-items: center;
-                height: inherit;
-                font-size: .26rem;
-            }
-        }
-    }
-
-    &__news {
-        .article {
-            &-item {
-                .van-cell__title {
-                    span {
-                        .mixin-text-overflow()
-                    }
-                }
-
-                .van-cell__value {
-                    flex: initial;
-                    font-size: .24rem;
-                    margin-left: .48rem;
-                }
-            }
-        }
-    }
-}

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

@@ -65,7 +65,7 @@ export function queryHistoryTikDatas(config: RequestConfig<Model.HistoryTikDatas
  * 查询新板块设置
  */
 export function getMarketSections(config: RequestConfig = {}) {
-    return http.commonRequest<Model.GetMarketSectionsRsp[]>({
+    return http.commonRequest<Model.MarketSectionsRsp[]>({
         url: '/Market/GetMarketSections',
         params: config.data,
     })

+ 1 - 1
src/types/model/market.d.ts

@@ -142,7 +142,7 @@ declare namespace Model {
     }
 
     /** 查询新板块设置 响应 */
-    interface GetMarketSectionsRsp {
+    interface MarketSectionsRsp {
         createtime: string; // 创建时间
         creatorid: number; // 创建人ID
         creatorsrc: number; // 创建人来源 - 1:管理端 2:终端 3:交易