li.shaoyi 1 vuosi sitten
vanhempi
commit
524b491cf4
32 muutettua tiedostoa jossa 2916 lisäystä ja 1 poistoa
  1. 27 0
      oem/tss/androidPrivacy.json
  2. 14 0
      oem/tss/config/appconfig.json
  3. 1 0
      oem/tss/config/columns.json
  4. 670 0
      oem/tss/config/router.json
  5. 303 0
      oem/tss/manifest.json
  6. 1 1
      public/config/appconfig.json
  7. 14 0
      script/oem.env.json
  8. 54 0
      src/packages/tss/App.vue
  9. BIN
      src/packages/tss/assets/images/avatar.jpg
  10. BIN
      src/packages/tss/assets/images/avatar.png
  11. BIN
      src/packages/tss/assets/images/block-bg.png
  12. BIN
      src/packages/tss/assets/images/certification.png
  13. BIN
      src/packages/tss/assets/images/guide-1.png
  14. BIN
      src/packages/tss/assets/images/guide-2.png
  15. BIN
      src/packages/tss/assets/images/login-logo.png
  16. 10 0
      src/packages/tss/assets/themes/dark/dark.less
  17. 70 0
      src/packages/tss/assets/themes/default/default.less
  18. 593 0
      src/packages/tss/assets/themes/global/global.less
  19. 6 0
      src/packages/tss/assets/themes/light/light.less
  20. 5 0
      src/packages/tss/assets/themes/style.less
  21. 71 0
      src/packages/tss/index.html
  22. 35 0
      src/packages/tss/main.ts
  23. 10 0
      src/packages/tss/postcss.config.js
  24. 333 0
      src/packages/tss/router/index.ts
  25. 99 0
      src/packages/tss/views/boot/Index.vue
  26. 19 0
      src/packages/tss/views/boot/index.less
  27. 226 0
      src/packages/tss/views/mine/Index.vue
  28. 168 0
      src/packages/tss/views/mine/index.less
  29. 49 0
      src/packages/tss/views/order/delivery/Index.vue
  30. 66 0
      src/packages/tss/views/order/list/Index.vue
  31. 59 0
      src/packages/tss/views/order/position/Index.vue
  32. 13 0
      src/packages/tss/views/user/login/Index.vue

+ 27 - 0
oem/tss/androidPrivacy.json

@@ -0,0 +1,27 @@
+{
+    "version" : "1",
+    "prompt" : "template",
+    "title" : "隐私政策",
+    "message" : "  请你务必审慎阅读、充分理解“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"http://8.130.107.247:8070/gzys_register/html/yszc.htm\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
+    "buttonAccept" : "同意并接受",
+    "buttonRefuse" : "拒绝",
+    "hrefLoader" : "system|default",
+    "second" : {
+        "title" : "确认提示",
+        "message" : "  进入应用前,你需先同意<a href=\"http://8.130.107.247:8070/gzys_register/html/yszc.htm\">《隐私政策》</a>,否则将退出应用。",
+        "buttonAccept" : "同意并继续",
+        "buttonRefuse" : "退出应用"
+    },
+    "disagreeMode" : {
+        "support" : false,
+        "loadNativePlugins" : false,
+        "visitorEntry" : true,
+        "showAlways" : true
+    },
+    "styles" : {
+        "borderRadius" : "5px",
+        "buttonAccept" : {
+            "color" : "#ee0a24"
+        }
+    }
+}

+ 14 - 0
oem/tss/config/appconfig.json

@@ -0,0 +1,14 @@
+{
+  "appId": "cn.muchinfo.tss",
+  "appName": "泰商所",
+  "version": "1.0.0",
+  "versionCode": "100000",
+  "apiUrl": "http://192.168.31.204:8080/cfg?key=test_204",
+  "tradeChannel": "ws",
+  "modules": [
+    "register"
+  ],
+  "quotationPropertys": [
+    "holdvolume"
+  ]
+}

+ 1 - 0
oem/tss/config/columns.json

@@ -0,0 +1 @@
+[]

+ 670 - 0
oem/tss/config/router.json

@@ -0,0 +1,670 @@
+[
+    {
+        "authType": 2,
+        "sort": 0,
+        "title": "pcroute.bottom.title",
+        "code": "bottom",
+        "children": [
+            {
+                "authType": 2,
+                "sort": 4,
+                "title": "pcroute.bottom.bottom_pricing",
+                "code": "bottom_pricing",
+                "component": "views/footer/index.vue",
+                "children": [
+                    {
+                        "authType": 2,
+                        "sort": 1,
+                        "title": "pcroute.bottom.bottom_pricing_position",
+                        "code": "bottom_pricing_position",
+                        "component": "views/footer/pricing/position/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 2,
+                        "title": "pcroute.bottom.bottom_pricing_detail",
+                        "code": "bottom_pricing_detail",
+                        "component": "views/footer/pricing/detail/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 2,
+                        "title": "pcroute.bottom.bottom_pricing_order",
+                        "code": "bottom_pricing_order",
+                        "component": "views/footer/pricing/order/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 3,
+                        "title": "pcroute.bottom.bottom_pricing_trade",
+                        "code": "bottom_pricing_trade",
+                        "component": "views/footer/pricing/trade/index.vue"
+                    }
+                ]
+            },
+            {
+                "authType": 2,
+                "sort": 2,
+                "title": "pcroute.bottom.bottom_presell",
+                "code": "bottom_presell",
+                "component": "views/footer/index.vue",
+                "children": [
+                    {
+                        "authType": 2,
+                        "sort": 1,
+                        "title": "pcroute.bottom.bottom_presell_presellposition",
+                        "code": "bottom_presell_presellposition",
+                        "component": "views/footer/presell/presellposition/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 2,
+                        "title": "pcroute.bottom.bottom_presell_transferposition",
+                        "code": "bottom_presell_transferposition",
+                        "component": "views/footer/presell/transferposition/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 3,
+                        "title": "pcroute.bottom.bottom_presell_transferorder",
+                        "code": "bottom_presell_transferorder",
+                        "component": "views/footer/presell/transferorder/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 4,
+                        "title": "pcroute.bottom.bottom_presell_transfertrader",
+                        "code": "bottom_presell_transfertrader",
+                        "component": "views/footer/presell/transfertrader/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 5,
+                        "title": "pcroute.bottom.bottom_presell_onlinedelivery",
+                        "code": "bottom_presell_onlinedelivery",
+                        "component": "views/footer/presell/onlinedelivery/index.vue"
+                    }
+                ]
+            },
+            {
+                "authType": 2,
+                "sort": 3,
+                "title": "pcroute.bottom.bottom_spot",
+                "code": "bottom_spot",
+                "component": "views/footer/index.vue",
+                "children": [
+                    {
+                        "authType": 2,
+                        "sort": 1,
+                        "title": "pcroute.bottom.bottom_spot_position",
+                        "code": "bottom_spot_position",
+                        "component": "views/footer/spot/position/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 2,
+                        "title": "pcroute.bottom.bottom_spot_order",
+                        "code": "bottom_spot_order",
+                        "component": "views/footer/spot/order/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 3,
+                        "title": "pcroute.bottom.bottom_spot_trade",
+                        "code": "bottom_spot_trade",
+                        "component": "views/footer/spot/trade/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 4,
+                        "title": "pcroute.bottom.bottom_spot_pickup",
+                        "code": "bottom_spot_pickup",
+                        "component": "views/footer/spot/pickup/index.vue"
+                    }
+                ]
+            },
+            {
+                "authType": 2,
+                "sort": 6,
+                "title": "pcroute.bottom.bottom_performance",
+                "code": "bottom_performance",
+                "component": "views/footer/index.vue",
+                "children": [
+                    {
+                        "authType": 2,
+                        "sort": 1,
+                        "title": "pcroute.bottom.bottom_performance_buy",
+                        "code": "bottom_performance_buy",
+                        "component": "views/footer/performance/buy/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 2,
+                        "title": "pcroute.bottom.bottom_performance_sell",
+                        "code": "bottom_performance_sell",
+                        "component": "views/footer/performance/sell/index.vue"
+                    }
+                ]
+            },
+            {
+                "authType": 2,
+                "sort": 8,
+                "title": "pcroute.bottom.bottom_capital",
+                "code": "bottom_capital",
+                "component": "views/footer/index.vue",
+                "children": [
+                    {
+                        "authType": 2,
+                        "sort": 1,
+                        "title": "pcroute.bottom.bottom_capital_summary",
+                        "code": "bottom_capital_summary",
+                        "component": "views/footer/capital/summary/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 2,
+                        "title": "pcroute.bottom.bottom_capital_statement",
+                        "code": "bottom_capital_statement",
+                        "component": "views/footer/capital/statement/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 3,
+                        "title": "pcroute.bottom.bottom_capital_inoutapply",
+                        "code": "bottom_capital_inoutapply",
+                        "component": "views/footer/capital/inoutapply/index.vue"
+                    }
+                ]
+            }
+        ]
+    },
+    {
+        "authType": 1,
+        "sort": 1,
+        "title": "pcroute.market.title",
+        "code": "market",
+        "url": "/market",
+        "urlType": 1,
+        "component": "Page",
+        "icon": "TrendCharts",
+        "children": [
+            {
+                "authType": 1,
+                "sort": 1,
+                "title": "pcroute.market.market_trade",
+                "code": "market_trade",
+                "url": "trade",
+                "urlType": 1,
+                "component": "views/market/trade/index.vue"
+            }
+        ]
+    },
+    {
+        "authType": 1,
+        "sort": 2,
+        "title": "pcroute.query.title",
+        "code": "query",
+        "url": "/query",
+        "urlType": 1,
+        "component": "Page",
+        "icon": "TrendCharts",
+        "children": [
+            {
+                "authType": 1,
+                "sort": 1,
+                "title": "pcroute.query.query_order",
+                "code": "query_order",
+                "url": "order",
+                "urlType": 1,
+                "component": "Main",
+                "children": [
+                    {
+                        "authType": 1,
+                        "sort": 1,
+                        "title": "pcroute.query.query_order_goods",
+                        "code": "query_order_goods",
+                        "url": "goods",
+                        "urlType": 1,
+                        "component": "views/query/order/goods/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_order_goods_list",
+                                "code": "query_order_goods_list",
+                                "component": "views/query/order/goods/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_order_goods_history",
+                                "code": "query_order_goods_history",
+                                "component": "views/query/order/goods/history/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 2,
+                        "title": "pcroute.query.query_order_presell",
+                        "code": "query_order_presell",
+                        "url": "presell",
+                        "urlType": 1,
+                        "component": "views/query/order/presell/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_order_presell__list",
+                                "code": "query_order_presell__list",
+                                "component": "views/query/order/presell/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_order_presell_history",
+                                "code": "query_order_presell_history",
+                                "component": "views/query/order/presell/history/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 3,
+                                "title": "pcroute.query.query_order_presell_transferlist",
+                                "code": "query_order_presell_transferlist",
+                                "component": "views/query/order/presell/transferlist/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 4,
+                                "title": "pcroute.query.query_order_presell_transferhistory",
+                                "code": "query_order_presell_transferhistory",
+                                "component": "views/query/order/presell/transferhistory/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 3,
+                        "title": "pcroute.query.query_order_spot",
+                        "code": "query_order_spot",
+                        "url": "spot",
+                        "urlType": 1,
+                        "component": "views/query/order/spot/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_order_spot_list",
+                                "code": "query_order_spot_list",
+                                "component": "views/query/order/spot/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_order_spot_history",
+                                "code": "query_order_spot_history",
+                                "component": "views/query/order/spot/history/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 4,
+                        "title": "pcroute.query.query_order_pricing",
+                        "code": "query_order_pricing",
+                        "url": "pricing",
+                        "urlType": 1,
+                        "component": "views/query/order/pricing/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_order_pricing_list",
+                                "code": "query_order_pricing_list",
+                                "component": "views/query/order/pricing/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_order_pricing_history",
+                                "code": "query_order_pricing_history",
+                                "component": "views/query/order/pricing/history/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 5,
+                        "title": "pcroute.query.query_order_swap",
+                        "code": "query_order_swap",
+                        "url": "swap",
+                        "urlType": 1,
+                        "component": "views/query/order/swap/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_order_swap_list",
+                                "code": "query_order_swap_list",
+                                "component": "views/query/order/swap/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_order_swap_history",
+                                "code": "query_order_swap_history",
+                                "component": "views/query/order/swap/history/index.vue"
+                            }
+                        ]
+                    }
+                ]
+            },
+            {
+                "authType": 1,
+                "sort": 2,
+                "title": "pcroute.query.query_trade",
+                "code": "query_trade",
+                "url": "trade",
+                "urlType": 1,
+                "component": "Main",
+                "children": [
+                    {
+                        "authType": 1,
+                        "sort": 1,
+                        "title": "pcroute.query.query_trade_goods",
+                        "code": "query_trade_goods",
+                        "url": "goods",
+                        "urlType": 1,
+                        "component": "views/query/trade/goods/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_trade_goods_list",
+                                "code": "query_trade_goods_list",
+                                "component": "views/query/trade/goods/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_trade_goods_history",
+                                "code": "query_trade_goods_history",
+                                "component": "views/query/trade/goods/history/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 2,
+                        "title": "pcroute.query.query_trade_presell",
+                        "code": "query_trade_presell",
+                        "url": "presell",
+                        "urlType": 1,
+                        "component": "views/query/trade/presell/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_trade_presell_list",
+                                "code": "query_trade_presell_list",
+                                "component": "views/query/trade/presell/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_trade_presell_history",
+                                "code": "query_trade_presell_history",
+                                "component": "views/query/trade/presell/history/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 3,
+                        "title": "pcroute.query.query_trade_spot",
+                        "code": "query_trade_spot",
+                        "url": "spot",
+                        "urlType": 1,
+                        "component": "views/query/trade/spot/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_trade_spot_list",
+                                "code": "query_trade_spot_list",
+                                "component": "views/query/trade/spot/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_trade_spot_history",
+                                "code": "query_trade_spot_history",
+                                "component": "views/query/trade/spot/history/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 4,
+                        "title": "pcroute.query.query_trade_pricing",
+                        "code": "query_trade_pricing",
+                        "url": "pricing",
+                        "urlType": 1,
+                        "component": "views/query/trade/pricing/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_trade_pricing_list",
+                                "code": "query_trade_pricing_list",
+                                "component": "views/query/trade/pricing/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_trade_pricing_history",
+                                "code": "query_trade_pricing_history",
+                                "component": "views/query/trade/pricing/history/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 5,
+                        "title": "pcroute.query.query_trade_swap",
+                        "code": "query_trade_swap",
+                        "url": "swap",
+                        "urlType": 1,
+                        "component": "views/query/trade/swap/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_trade_swap_list",
+                                "code": "query_trade_swap_list",
+                                "component": "views/query/trade/swap/list/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_trade_swap_history",
+                                "code": "query_trade_swap_history",
+                                "component": "views/query/trade/swap/history/index.vue"
+                            }
+                        ]
+                    }
+                ]
+            },
+            {
+                "authType": 1,
+                "sort": 3,
+                "title": "pcroute.query.query_capital",
+                "code": "query_capital",
+                "url": "capital",
+                "urlType": 1,
+                "component": "views/query/capital/index.vue",
+                "children": [
+                    {
+                        "authType": 2,
+                        "sort": 1,
+                        "title": "pcroute.query.query_capital_list",
+                        "code": "query_capital_list",
+                        "component": "views/query/capital/list/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 2,
+                        "title": "pcroute.query.query_capital_history",
+                        "code": "query_capital_history",
+                        "component": "views/query/capital/history/index.vue"
+                    }
+                ]
+            },
+            {
+                "authType": 1,
+                "sort": 4,
+                "title": "pcroute.query.query_presell",
+                "code": "query_presell",
+                "url": "presell",
+                "urlType": 1,
+                "component": "Main",
+                "children": [
+                    {
+                        "authType": 1,
+                        "sort": 1,
+                        "title": "pcroute.query.query_presell_onlinedelivery",
+                        "code": "query_presell_onlinedelivery",
+                        "url": "buy",
+                        "urlType": 1,
+                        "component": "views/query/presell/onlinedelivery/index.vue"
+                    }
+                ]
+            },
+            {
+                "authType": 1,
+                "sort": 5,
+                "title": "pcroute.query.query_performance",
+                "code": "query_performance",
+                "url": "performance",
+                "urlType": 1,
+                "component": "Main",
+                "children": [
+                    {
+                        "authType": 1,
+                        "sort": 1,
+                        "title": "pcroute.query.query_performance_buy",
+                        "code": "query_performance_buy",
+                        "url": "buy",
+                        "urlType": 1,
+                        "component": "views/query/performance/buy/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_performance_buy_running",
+                                "code": "query_performance_buy_running",
+                                "component": "views/query/performance/buy/running/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_performance_buy_all",
+                                "code": "query_performance_buy_all",
+                                "component": "views/query/performance/buy/all/index.vue"
+                            }
+                        ]
+                    },
+                    {
+                        "authType": 1,
+                        "sort": 2,
+                        "title": "pcroute.query.query_performance_sell",
+                        "code": "query_performance_sell",
+                        "url": "sell",
+                        "urlType": 1,
+                        "component": "views/query/performance/sell/index.vue",
+                        "children": [
+                            {
+                                "authType": 2,
+                                "sort": 1,
+                                "title": "pcroute.query.query_performance_sell_running",
+                                "code": "query_performance_sell_running",
+                                "component": "views/query/performance/sell/running/index.vue"
+                            },
+                            {
+                                "authType": 2,
+                                "sort": 2,
+                                "title": "pcroute.query.query_performance_sell_all",
+                                "code": "query_performance_sell_all",
+                                "component": "views/query/performance/sell/all/index.vue"
+                            }
+                        ]
+                    }
+                ]
+            },
+            {
+                "authType": 1,
+                "sort": 6,
+                "title": "pcroute.query.query_inoutapply",
+                "code": "query_inoutapply",
+                "url": "inoutapply",
+                "urlType": 1,
+                "component": "views/query/inoutapply/index.vue",
+                "children": [
+                    {
+                        "authType": 2,
+                        "sort": 1,
+                        "title": "pcroute.query.query_inoutapply_list",
+                        "code": "query_inoutapply_list",
+                        "component": "views/query/inoutapply/list/index.vue"
+                    },
+                    {
+                        "authType": 2,
+                        "sort": 1,
+                        "title": "pcroute.query.query_inoutapply_history",
+                        "code": "query_inoutapply_history",
+                        "component": "views/query/inoutapply/history/index.vue"
+                    }
+                ]
+            }
+        ]
+    },
+    {
+        "authType": 1,
+        "sort": 3,
+        "title": "pcroute.account.title",
+        "code": "account",
+        "url": "/account",
+        "urlType": 1,
+        "component": "Page",
+        "icon": "TrendCharts",
+        "children": [
+            {
+                "authType": 1,
+                "sort": 1,
+                "title": "pcroute.account.account_sign",
+                "code": "account_sign",
+                "url": "sign",
+                "urlType": 1,
+                "component": "views/account/sign/index.vue"
+            },
+            {
+                "authType": 1,
+                "sort": 4,
+                "title": "pcroute.account.account_address",
+                "code": "account_address",
+                "url": "address",
+                "urlType": 1,
+                "component": "views/account/address/index.vue"
+            },
+            {
+                "authType": 1,
+                "sort": 5,
+                "title": "pcroute.account.account_receipt",
+                "code": "account_receipt",
+                "url": "receipt",
+                "urlType": 1,
+                "component": "views/account/receipt/index.vue"
+            }
+        ]
+    }
+]

+ 303 - 0
oem/tss/manifest.json

@@ -0,0 +1,303 @@
+{
+    "@platforms" : [ "android", "iPhone", "iPad" ],
+    "id" : "H5A27263D",
+    /*应用的标识*/
+    "name" : "贵茶数字化",
+    /*应用名称,程序桌面图标名称*/
+    "version" : {
+        "name" : "1.0.0",
+        /*应用版本名称*/
+        "code" : 100000
+    },
+    "description" : "",
+    /*应用描述信息*/
+    "icons" : {
+        "72" : "icon.png"
+    },
+    "launch_path" : "index.html",
+    /*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/
+    "developer" : {
+        "name" : "",
+        /*开发者名称*/
+        "email" : "",
+        /*开发者邮箱地址*/
+        "url" : "" /*开发者个人主页地址*/
+    },
+    "permissions" : {
+        "Accelerometer" : {
+            "description" : "访问加速度感应器"
+        },
+        "Audio" : {
+            "description" : "访问麦克风"
+        },
+        "Cache" : {
+            "description" : "管理应用缓存"
+        },
+        "Camera" : {
+            "description" : "访问摄像头"
+        },
+        "Console" : {
+            "description" : "跟踪调试输出日志"
+        },
+        "Device" : {
+            "description" : "访问设备信息"
+        },
+        "Downloader" : {
+            "description" : "文件下载管理"
+        },
+        "Events" : {
+            "description" : "应用扩展事件"
+        },
+        "File" : {
+            "description" : "访问本地文件系统"
+        },
+        "Gallery" : {
+            "description" : "访问系统相册"
+        },
+        "Invocation" : {
+            "description" : "使用Native.js能力"
+        },
+        "Orientation" : {
+            "description" : "访问方向感应器"
+        },
+        "Proximity" : {
+            "description" : "访问距离感应器"
+        },
+        "Storage" : {
+            "description" : "管理应用本地数据"
+        },
+        "Uploader" : {
+            "description" : "管理文件上传任务"
+        },
+        "Runtime" : {
+            "description" : "访问运行期环境"
+        },
+        "XMLHttpRequest" : {
+            "description" : "跨域网络访问"
+        },
+        "Zip" : {
+            "description" : "文件压缩与解压缩"
+        },
+        "Barcode" : {
+            "description" : "管理二维码扫描插件"
+        },
+        "Webview" : {
+            "description" : "窗口管理"
+        },
+        "NativeUI" : {
+            "description" : "原生UI控件"
+        },
+        "Navigator" : {
+            "description" : "浏览器信息"
+        },
+        "NativeObj" : {
+            "description" : "原生对象"
+        },
+        "Share" : {}
+    },
+    "plus" : {
+        "modules" : {
+            "Barcode" : {},
+            "Camera" : {},
+            "Gallery" : {},
+            "Share" : {}
+        },
+        "statusbar" : {
+            "immersed" : true /*沉浸式状态栏。*/
+        },
+        "splashscreen" : {
+            "autoclose" : true,
+            /*是否自动关闭程序启动界面,true表示应用加载应用入口页面后自动关闭;false则需调plus.navigator.closeSplashscreen()关闭*/
+            "waiting" : true /*是否在程序启动界面显示等待雪花,true表示显示,false表示不显示。*/
+        },
+        "popGesture" : "close",
+        /*设置应用默认侧滑返回关闭Webview窗口,"none"为无侧滑返回功能,"hide"为侧滑隐藏Webview窗口。参考http://ask.dcloud.net.cn/article/102*/
+        "runmode" : "liberate",
+        /*应用的首次启动运行模式,可取liberate或normal,liberate模式在第一次启动时将解压应用资源(Android平台File API才可正常访问_www目录)*/
+        "signature" : "Sk9JTiBVUyBtYWlsdG86aHIyMDEzQGRjbG91ZC5pbw==",
+        /*可选,保留给应用签名,暂不使用*/
+        "distribute" : {
+            "apple" : {
+                "appid" : "",
+                /*iOS应用标识,苹果开发网站申请的appid,如io.dcloud.HelloH5*/
+                "mobileprovision" : "",
+                /*iOS应用打包配置文件*/
+                "password" : "",
+                /*iOS应用打包个人证书导入密码*/
+                "p12" : "",
+                /*iOS应用打包个人证书,打包配置文件关联的个人证书*/
+                "devices" : "universal",
+                /*iOS应用支持的设备类型,可取值iphone/ipad/universal*/
+                "frameworks" : [], /*调用Native.js调用原生Objective-c API需要引用的FrameWork,如需调用GameCenter,则添加"GameKit.framework"*/
+                "idfa" : false,
+                "privacyDescription" : {
+                    "NSCameraUsageDescription" : "访问您的相册用来上传您的图像用来设置头像!",
+                    "NSPhotoLibraryAddUsageDescription" : "访问您的相册保存图像用来设置头像!",
+                    "NSPhotoLibraryUsageDescription" : "访问您的摄像头用来拍照上传您的图像用来设置头像!"
+                }
+            },
+            "google" : {
+                "packagename" : "",
+                /*Android应用包名,如io.dcloud.HelloH5*/
+                "keystore" : "",
+                /*Android应用打包使用的密钥库文件*/
+                "password" : "",
+                /*Android应用打包使用密钥库中证书的密码*/
+                "aliasname" : "",
+                /*Android应用打包使用密钥库中证书的别名*/
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.BIND_INPUT_METHOD\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>"
+                ],
+                "abiFilters" : [ "arm64-v8a" ],
+                "autoSdkPermissions" : false,
+                "minSdkVersion" : 26
+            },
+            /*使用Native.js调用原生安卓API需要使用到的系统权限*/
+            "orientation" : [ "portrait-primary" ],
+            /*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/
+            "icons" : {
+                "ios" : {
+                    "prerendered" : true,
+                    /*应用图标是否已经高亮处理,在iOS6及以下设备上有效*/
+                    "auto" : "",
+                    /*应用图标,分辨率:512x512,用于自动生成各种尺寸程序图标*/
+                    "iphone" : {
+                        "normal" : "",
+                        /*iPhone3/3GS程序图标,分辨率:57x57*/
+                        "retina" : "",
+                        /*iPhone4程序图标,分辨率:114x114*/
+                        "retina7" : "",
+                        /*iPhone4S/5/6程序图标,分辨率:120x120*/
+                        "retina8" : "",
+                        /*iPhone6 Plus程序图标,分辨率:180x180*/
+                        "spotlight-normal" : "",
+                        /*iPhone3/3GS Spotlight搜索程序图标,分辨率:29x29*/
+                        "spotlight-retina" : "",
+                        /*iPhone4 Spotlight搜索程序图标,分辨率:58x58*/
+                        "spotlight-retina7" : "",
+                        /*iPhone4S/5/6 Spotlight搜索程序图标,分辨率:80x80*/
+                        "settings-normal" : "",
+                        /*iPhone4设置页面程序图标,分辨率:29x29*/
+                        "settings-retina" : "",
+                        /*iPhone4S/5/6设置页面程序图标,分辨率:58x58*/
+                        "settings-retina8" : "", /*iPhone6Plus设置页面程序图标,分辨率:87x87*/
+                        "app@2x" : "app/icons/120x120.png",
+                        "app@3x" : "app/icons/180x180.png",
+                        "notification@2x" : "app/icons/40x40.png",
+                        "notification@3x" : "app/icons/60x60.png",
+                        "settings@2x" : "app/icons/58x58.png",
+                        "settings@3x" : "app/icons/87x87.png",
+                        "spotlight@2x" : "app/icons/80x80.png",
+                        "spotlight@3x" : "app/icons/120x120.png"
+                    },
+                    "ipad" : {
+                        "normal" : "",
+                        /*iPad普通屏幕程序图标,分辨率:72x72*/
+                        "retina" : "",
+                        /*iPad高分屏程序图标,分辨率:144x144*/
+                        "normal7" : "",
+                        /*iPad iOS7程序图标,分辨率:76x76*/
+                        "retina7" : "",
+                        /*iPad iOS7高分屏程序图标,分辨率:152x152*/
+                        "spotlight-normal" : "",
+                        /*iPad Spotlight搜索程序图标,分辨率:50x50*/
+                        "spotlight-retina" : "",
+                        /*iPad高分屏Spotlight搜索程序图标,分辨率:100x100*/
+                        "spotlight-normal7" : "",
+                        /*iPad iOS7 Spotlight搜索程序图标,分辨率:40x40*/
+                        "spotlight-retina7" : "",
+                        /*iPad iOS7高分屏Spotlight搜索程序图标,分辨率:80x80*/
+                        "settings-normal" : "",
+                        /*iPad设置页面程序图标,分辨率:29x29*/
+                        "settings-retina" : "", /*iPad高分屏设置页面程序图标,分辨率:58x58*/
+                        "app" : "app/icons/76x76.png",
+                        "app@2x" : "app/icons/152x152.png",
+                        "notification" : "app/icons/20x20.png",
+                        "notification@2x" : "app/icons/40x40.png",
+                        "proapp@2x" : "app/icons/167x167.png",
+                        "settings" : "app/icons/29x29.png",
+                        "settings@2x" : "app/icons/58x58.png",
+                        "spotlight" : "app/icons/40x40.png",
+                        "spotlight@2x" : "app/icons/80x80.png"
+                    },
+                    "appstore" : "app/icons/1024x1024.png"
+                },
+                "android" : {
+                    "mdpi" : "",
+                    /*普通屏程序图标,分辨率:48x48*/
+                    "ldpi" : "",
+                    /*大屏程序图标,分辨率:48x48*/
+                    "hdpi" : "app/icons/72x72.png",
+                    /*高分屏程序图标,分辨率:72x72*/
+                    "xhdpi" : "app/icons/96x96.png",
+                    /*720P高分屏程序图标,分辨率:96x96*/
+                    "xxhdpi" : "app/icons/144x144.png", /*1080P 高分屏程序图标,分辨率:144x144*/
+                    "xxxhdpi" : "app/icons/192x192.png"
+                }
+            },
+            "splashscreen" : {
+                "ios" : {
+                    "iphone" : {
+                        "default" : "",
+                        /*iPhone3启动图片选,分辨率:320x480*/
+                        "retina35" : "",
+                        /*3.5英寸设备(iPhone4)启动图片,分辨率:640x960*/
+                        "retina40" : "",
+                        /*4.0 英寸设备(iPhone5/iPhone5s)启动图片,分辨率:640x1136*/
+                        "retina47" : "",
+                        /*4.7 英寸设备(iPhone6)启动图片,分辨率:750x1334*/
+                        "retina55" : "",
+                        /*5.5 英寸设备(iPhone6 Plus)启动图片,分辨率:1242x2208*/
+                        "retina55l" : "" /*5.5 英寸设备(iPhone6 Plus)横屏启动图片,分辨率:2208x1242*/
+                    },
+                    "ipad" : {
+                        "portrait" : "",
+                        /*iPad竖屏启动图片,分辨率:768x1004*/
+                        "portrait-retina" : "",
+                        /*iPad高分屏竖屏图片,分辨率:1536x2008*/
+                        "landscape" : "",
+                        /*iPad横屏启动图片,分辨率:1024x748*/
+                        "landscape-retina" : "",
+                        /*iPad高分屏横屏启动图片,分辨率:2048x1496*/
+                        "portrait7" : "",
+                        /*iPad iOS7竖屏启动图片,分辨率:768x1024*/
+                        "portrait-retina7" : "",
+                        /*iPad iOS7高分屏竖屏图片,分辨率:1536x2048*/
+                        "landscape7" : "",
+                        /*iPad iOS7横屏启动图片,分辨率:1024x768*/
+                        "landscape-retina7" : "" /*iPad iOS7高分屏横屏启动图片,分辨率:2048x1536*/
+                    },
+                    "storyboard" : "../ios/CustomStoryborad.zip"
+                },
+                "android" : {
+                    "mdpi" : "",
+                    /*普通屏启动图片,分辨率:240x282*/
+                    "ldpi" : "",
+                    /*大屏启动图片,分辨率:320x442*/
+                    "hdpi" : "app/splashscreen/480x853.png",
+                    /*高分屏启动图片,分辨率:480x762*/
+                    "xhdpi" : "app/splashscreen/720x1280.png",
+                    /*720P高分屏启动图片,分辨率:720x1242*/
+                    "xxhdpi" : "app/splashscreen/1080x1920.png" /*1080P高分屏启动图片,分辨率:1080x1882*/
+                },
+                "androidStyle" : "default",
+                "iosStyle" : "common",
+                "useOriginalMsgbox" : true
+            },
+            "plugins" : {
+                "ad" : {},
+                "geolocation" : {},
+                "share" : {}
+            },
+            "ios" : {
+                "dSYMs" : false
+            }
+        }
+    },
+    "screenOrientation" : [ "portrait-primary" ]
+}

+ 1 - 1
public/config/appconfig.json

@@ -1,6 +1,6 @@
 {
   "appId": "cn.muchinfo.demo",
-  "appName": "行情",
+  "appName": "多元世纪",
   "appTitle": "多元世纪交易中心",
   "version": "1.0.8",
   "versionCode": "10008",

+ 14 - 0
script/oem.env.json

@@ -204,5 +204,19 @@
         "VUE_APP_ROOT": "src/packages/pc/",
         "VUE_APP_OEM": "oem/nhgj/",
         "VUE_APP_TRADE_CHANNEL": "ws"
+    },
+    {
+        "VUE_APP_ENV": "tss",
+        "VUE_APP_NAME": "泰商所",
+        "VUE_APP_ROOT": "src/packages/tss/",
+        "VUE_APP_OEM": "oem/tss/",
+        "VUE_APP_TRADE_CHANNEL": "ws"
+    },
+    {
+        "VUE_APP_ENV": "tss@pc",
+        "VUE_APP_NAME": "泰商所",
+        "VUE_APP_ROOT": "src/packages/pc/",
+        "VUE_APP_OEM": "oem/tss/",
+        "VUE_APP_TRADE_CHANNEL": "ws"
     }
 ]

+ 54 - 0
src/packages/tss/App.vue

@@ -0,0 +1,54 @@
+<template>
+  <router-view />
+  <Notify v-model:show="notify.show" :title="notify.title" :content="notify.content" />
+</template>
+
+<script lang="ts" setup>
+import { reactive } from 'vue'
+import { useNavigation } from '@mobile/router/navigation'
+import { dialog } from '@/utils/vant'
+import { useLogin } from '@/business/login'
+import eventBus from '@/services/bus'
+import Notify from '@mobile/components/base/notify/index.vue'
+
+const { userLogout } = useLogin()
+const { backHome } = useNavigation()
+
+const notify = reactive({
+  show: false,
+  title: '',
+  content: ''
+})
+
+// 接收用户登出通知
+eventBus.$on('LogoutNotify', (msg) => {
+  userLogout(() => {
+    if (msg) {
+      dialog({
+        message: msg as string,
+        confirmButtonText: '确定'
+      }).then(() => {
+        backHome()
+      })
+    } else {
+      backHome()
+    }
+  })
+})
+
+// 接收风控通知
+eventBus.$on('RiskToWebNtf', (msg, type) => {
+  const res = msg as { title: string, content: string }
+  if (type === 1) {
+    notify.title = res.title
+    notify.content = res.content
+    notify.show = true
+  } else {
+    dialog({
+      title: res.title,
+      message: res.content,
+      confirmButtonText: '确定'
+    })
+  }
+})
+</script>

BIN
src/packages/tss/assets/images/avatar.jpg


BIN
src/packages/tss/assets/images/avatar.png


BIN
src/packages/tss/assets/images/block-bg.png


BIN
src/packages/tss/assets/images/certification.png


BIN
src/packages/tss/assets/images/guide-1.png


BIN
src/packages/tss/assets/images/guide-2.png


BIN
src/packages/tss/assets/images/login-logo.png


+ 10 - 0
src/packages/tss/assets/themes/dark/dark.less

@@ -0,0 +1,10 @@
+[theme='dark'] {
+    /* 导航栏 */
+    --navbar-color     : #fff;
+    --navbar-background: #333;
+
+    /* 标签栏 */
+    --tabbar-background : #333;
+    --tabbar-icon       : #fff;
+    --tabbar-icon-active: #dc143c;
+}

+ 70 - 0
src/packages/tss/assets/themes/default/default.less

@@ -0,0 +1,70 @@
+:root {
+    /* 字体大小规范 */
+    --font-x-large: 18px;
+    --font-large: 16px;
+    --font-medium: 14px;
+    --font-small: 12px;
+    --font-x-small: 10px;
+
+    /* 颜色规范 */
+    --color-default: #384048;
+    --color-primary: #409EFF;
+    --color-secondary: #04c786;
+    --color-info: #999;
+    --color-border: #eee;
+    --color-up: #ff2b2b;
+    --color-down: #04c786;
+
+    /* 导航栏 */
+    --navbar-height: 44px;
+    --navbar-color: #fff;
+    --navbar-background: #C30D23;
+    --navbar-backbutton-color: #fff;
+
+    /* 标签栏 */
+    --tabbar-background: #fff;
+    --tabbar-icon: #999;
+    --tabbar-icon-active: #c30d23;
+
+    /* 内容边距 */
+    --content-inset: 12px;
+
+    /* Vant-Button */
+    --van-button-border-width: 0;
+    --van-button-primary-background: #1e78b9;
+    --van-button-danger-background: #d82d42;
+
+    /* Vant-Checkbox */
+    --van-checkbox-checked-icon-color: #DD364A !important;
+
+    /* Vant-Tabs */
+    --van-tabs-bottom-bar-color: #DD364A;
+
+    --van-dialog-confirm-button-text-color: #DD364A;
+
+    .app-tabs {
+        .tabs {
+            flex-wrap: wrap;
+
+            &-item {
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                color: #626675;
+                cursor: pointer;
+                border-radius: 2px;
+                background-color: #f0f0f1;
+                padding: 4px 8px;
+
+                &:not(:first-child) {
+                    margin-left: 5px;
+                }
+
+                &.is-active {
+                    color: #222;
+                    font-weight: bold;
+                }
+            }
+        }
+    }
+}

+ 593 - 0
src/packages/tss/assets/themes/global/global.less

@@ -0,0 +1,593 @@
+[class*='g-image'] {
+    position: relative;
+    object-fit: cover;
+    overflow: hidden;
+
+    &:before {
+        content: '';
+        position: absolute;
+        left: 0;
+        top: 0;
+        width: 100%;
+        height: 100%;
+        background: #fff url("../../images/avatar.png") no-repeat center;
+        background-size: cover;
+    }
+}
+
+.g-price {
+    &-normal {
+        color: #333333;
+    }
+
+    &-up {
+        color: #ff3333;
+    }
+
+    &-down {
+        color: #0baf1f;
+    }
+}
+
+.g-risk {
+    &-green {
+        color: #0baf1f;
+    }
+
+    &-red {
+        color: #ff3333;
+    }
+
+    &-orange {
+        color: orange;
+    }
+
+    &-yellow {
+        color: #ebce12;
+    }
+}
+
+.g-form {
+    &__container {
+        display: flex;
+        flex-direction: column;
+        padding-bottom: 16px;
+
+        /* 父元素的第一个子元素 */
+        .van-cell-group--inset:first-of-type {
+            margin-top: 16px;
+        }
+
+        /* 相邻兄弟元素 */
+        .van-cell-group--inset+.van-cell-group--inset {
+            margin-top: 12px;
+        }
+
+        .van-field {
+            &__right-icon {
+                align-self: normal;
+            }
+
+            .van-stepper {
+                display: flex;
+                align-items: center;
+                width: 100%;
+
+                &__input {
+                    flex: 1;
+                }
+            }
+        }
+    }
+
+    &__footer {
+        display: flex;
+        align-items: center;
+
+        &:empty {
+            display: none;
+        }
+
+        &.inset {
+            gap: 10px;
+            padding: 10px 16px;
+        }
+    }
+}
+
+.g-flex {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+
+    &--row {
+        flex-direction: row;
+    }
+
+    &__body {
+        flex: 1;
+        overflow-y: auto;
+        -webkit-overflow-scrolling: touch;
+    }
+
+    &__footer {
+        margin-top: auto;
+    }
+}
+
+.g-color {
+    &--up {
+        color: var(--color-up);
+    }
+
+    &--down {
+        color: var(--color-down);
+    }
+}
+
+.g-block {
+    &--bg {
+        background: #fff url('../../images/block-bg.png') no-repeat center bottom;
+        background-size: 100%;
+    }
+}
+
+/* 导航列表 */
+.g-navmenu {
+    .app-iconfont {
+        height: 100%;
+
+        .g-icon {
+            width: 18px;
+            height: 18px;
+            font-size: 18px;
+        }
+
+        &__label {
+            font-size: 13px;
+            margin-left: 12px
+        }
+    }
+}
+
+/* 商品列表 */
+.g-goods-list {
+    padding: 10px;
+
+    .list {
+        padding: 10px 10px 0 10px;
+
+        &-item {
+            display: flex;
+            border-radius: 10px;
+            height: 110px;
+            overflow: hidden;
+            background-color: #fff;
+            padding: 10px;
+
+            &:not(:last-child) {
+                margin-bottom: 10px;
+            }
+
+            .img {
+                position: relative;
+                border-radius: 8px;
+                overflow: hidden;
+
+                &.mask::after {
+                    content: '已结束';
+                    position: absolute;
+                    top: 0;
+                    left: 0;
+                    display: flex;
+                    justify-content: center;
+                    align-items: center;
+                    width: 100%;
+                    height: 100%;
+                    font-size: 12px;
+                    color: #fff;
+                    background-color: rgba(0, 0, 0, .5);
+                }
+
+                img {
+                    width: 90px;
+                    height: 90px;
+                    object-fit: cover;
+                }
+            }
+
+            .info {
+                flex: 1;
+                display: flex;
+                flex-direction: column;
+                margin-left: 15px;
+
+                .title {
+                    color: #333;
+                    font-size: 15px;
+                }
+
+                .desc {
+                    display: flex;
+                    flex-direction: column;
+                    color: #666;
+                    font-size: 12px;
+                    margin-top: auto;
+                }
+
+                .price {
+                    color: var(--van-tag-danger-color);
+                    margin-top: 8px;
+
+                    .buyprice,
+                    .sellprice {
+                        padding-bottom: 1px;
+                    }
+                }
+            }
+        }
+    }
+}
+
+.g-goods-waterfall {
+    padding: 10px;
+
+    .goods {
+        background-color: #fff;
+        border-radius: 8px;
+        overflow: hidden;
+
+        &-image {
+            position: relative;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            min-height: 120px;
+            font-size: 0;
+            border-radius: 8px;
+            overflow: hidden;
+
+            &.mask::after {
+                content: '已结束';
+                position: absolute;
+                top: 0;
+                left: 0;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                width: 100%;
+                height: 100%;
+                font-size: 14px;
+                color: #fff;
+                background-color: rgba(0, 0, 0, .5);
+            }
+        }
+
+        &-info {
+            padding: 10px;
+
+            &__title {
+                font-size: 13px;
+                margin-bottom: 5px;
+            }
+
+            &__desc {
+                font-size: 12px;
+                color: #999;
+                margin-bottom: 5px;
+            }
+
+            &__price {
+                color: #f2270c;
+
+                .unit {
+                    font-size: 12px;
+                }
+
+                .integer {
+                    font-size: 15px;
+                }
+            }
+        }
+    }
+}
+
+/* 订单列表 */
+.g-order-list {
+    padding: 10px;
+    padding-bottom: 0;
+
+    &__box {
+        &:not(:first-child) {
+            margin-top: 10px;
+        }
+
+        background-color: #fff;
+        border-radius: 8px;
+        padding: 12px;
+
+    }
+
+    &__titlebar {
+        display: flex;
+        justify-content: space-between;
+        margin-bottom: 10px;
+
+        .left {
+            h4 {
+                font-weight: bold;
+            }
+
+            span {
+                font-size: 12px;
+                color: #999;
+            }
+        }
+
+        .right {
+            font-size: 12px;
+            color: #999;
+        }
+    }
+
+    &__content {
+        font-size: 12px;
+
+        ul {
+            display: flex;
+            flex-wrap: wrap;
+            justify-content: space-between;
+
+            li {
+                display: flex;
+                justify-content: space-between;
+                line-height: 24px;
+                width: calc(~"50% - 12px");
+
+                span {
+                    &:first-child {
+                        color: #999;
+                        white-space: nowrap;
+                        padding-right: 12px;
+                    }
+                }
+            }
+        }
+    }
+
+    &__btnbar {
+        display: flex;
+        justify-content: flex-end;
+        gap: 8px;
+        margin-top: 10px;
+
+        .van-button {
+            width: 80px;
+            border-width: 1px;
+        }
+    }
+}
+
+.g-detail {
+    &__buy {
+        background-color: #fff;
+
+        .topic {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            color: #fff;
+            background-image: linear-gradient(to right, #ee0a24, #ff6034);
+            padding: 10px 12px;
+
+            &-left {
+                .price-text {
+                    font-size: 12px;
+                }
+
+                .price-integer {
+                    font-size: 22px;
+                }
+            }
+
+            &-right {
+                display: flex;
+                flex-direction: column;
+                font-size: 12px;
+            }
+        }
+
+        .title {
+            font-size: 15px;
+            font-weight: bold;
+            line-height: 24px;
+            padding: 12px;
+            padding-bottom: 0;
+
+            .van-tag {
+                font-weight: normal;
+            }
+
+            span {
+                margin-right: 5px;
+            }
+        }
+
+        .desc {
+            padding: 0 12px;
+        }
+
+        .qty {
+            font-size: 12px;
+            color: #999;
+            padding: 5px 12px 0 12px;
+        }
+
+        .info {
+            background-color: #fff;
+            padding: 10px;
+
+            ul {
+                display: flex;
+                flex-wrap: wrap;
+                font-size: 13px;
+
+                li {
+                    display: flex;
+                    justify-content: space-between;
+                    width: 50%;
+                    padding: 4px 12px;
+
+                    span {
+                        &:first-child {
+                            color: #999;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    &__desc {
+        background-color: #fff;
+        margin-top: 12px;
+    }
+
+    &__footer {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        height: 44px;
+        background-color: #fff;
+
+        .price {
+            padding-left: 16px;
+
+            &-text,
+            &-unit {
+                font-size: 12px;
+            }
+
+            &-unit {
+                color: #f2270c;
+            }
+
+            &-integer {
+                font-size: 16px;
+                color: #f2270c;
+            }
+        }
+
+        .submit {
+            align-self: stretch;
+            display: flex;
+            margin-left: auto;
+
+            &-button {
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                height: 100%;
+                min-width: 100px;
+                font-weight: bold;
+                color: #fff;
+                padding: 0 24px;
+
+                &.warning {
+                    background-image: linear-gradient(to right, #ffd01e, #ff8917);
+                    background-color: #ff8a17;
+                }
+
+                &.danger {
+                    background-image: linear-gradient(to right, #ff6034, #ee0a24);
+                    background-color: #ee270a;
+                }
+            }
+        }
+    }
+}
+
+.g-qty-group {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+
+    &__stepper {
+        display: flex;
+        align-items: center;
+        gap: 5px;
+        width: 100%;
+
+        .van-stepper {
+            flex: 1;
+            display: flex;
+
+            &__input {
+                flex: 1;
+            }
+        }
+    }
+
+    .van-radio-group {
+        display: flex;
+        flex-wrap: wrap;
+        width: 100%;
+        margin-top: 10px;
+    }
+
+    .van-radio {
+        width: calc(~'100% / 3');
+        padding: 2px;
+        margin-right: 0;
+
+        .van-radio__icon {
+            display: none;
+        }
+
+        &__label {
+            display: block;
+            width: 100%;
+            font-size: 12px;
+            text-align: center;
+            color: #666;
+            border: 1px solid #e5e5e5;
+            border-radius: 4px;
+            padding: 2px;
+            margin-left: 0;
+        }
+
+        &[aria-checked="true"] {
+            .van-radio__label {
+                color: var(--van-radio-checked-icon-color);
+                border-color: var(--van-radio-checked-icon-color);
+            }
+        }
+    }
+}
+
+.van {
+    &-dialog {
+        &__message {
+            font-size: 14px;
+            line-height: 22px;
+        }
+    }
+
+    &-tabs {
+        &--list {
+            display: flex;
+            flex-direction: column;
+            height: 100%;
+        }
+
+        &--list &__content {
+            flex: 1;
+            overflow-y: auto;
+
+            .van-tab__panel {
+                height: 100%;
+            }
+        }
+    }
+}

+ 6 - 0
src/packages/tss/assets/themes/light/light.less

@@ -0,0 +1,6 @@
+[theme='light'] {
+    /* 导航栏 */
+    --navbar-color           : #333;
+    --navbar-background      : #fff;
+    --navbar-backbutton-color: #666;
+}

+ 5 - 0
src/packages/tss/assets/themes/style.less

@@ -0,0 +1,5 @@
+@import '@mobile/assets/themes/base/reset.less';
+@import './global/global.less';
+@import './default/default.less';
+@import './light/light.less';
+@import './dark/dark.less';

+ 71 - 0
src/packages/tss/index.html

@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="zh-cn">
+
+<head>
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport"
+    content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no,viewport-fit=cover">
+  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+  <title>
+    <%= htmlWebpackPlugin.options.title %>
+  </title>
+  <style>
+    @keyframes app-load {
+      0% {
+        opacity: 1;
+      }
+
+      100% {
+        opacity: 0;
+      }
+    }
+
+    .app-load {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      gap: 5px;
+      height: 100vh;
+    }
+
+    .app-load span {
+      display: inline-block;
+      width: 8px;
+      height: 8px;
+      border-radius: 50%;
+      background: #ccc;
+      opacity: 0;
+      animation: app-load 600ms ease infinite;
+    }
+
+    .app-load span:nth-child(1) {
+      animation-delay: 100ms;
+    }
+
+    .app-load span:nth-child(2) {
+      animation-delay: 200ms;
+    }
+
+    .app-load span:nth-child(3) {
+      animation-delay: 300ms;
+    }
+  </style>
+</head>
+
+<body>
+  <noscript>
+    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
+        Please enable it to continue.</strong>
+  </noscript>
+  <div id="app" class="app">
+    <div class="app-load">
+      <span></span>
+      <span></span>
+      <span></span>
+    </div>
+  </div>
+  <!-- built files will be auto injected -->
+</body>
+
+</html>

+ 35 - 0
src/packages/tss/main.ts

@@ -0,0 +1,35 @@
+import 'core-js'
+import 'regenerator-runtime/runtime'
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import directives from '@/directives' // 自定义指令集
+//import 'default-passive-events'
+import '@/utils/h5plus' // 加载html5+
+import 'hqchart/src/jscommon/umychart.resource/font/iconfont.css'
+import layouts from '@mobile/components/layouts' // 全局布局组件
+import 'vant/lib/index.css'
+import VXETable from 'vxe-table'
+import 'vxe-table/lib/style.css'
+import './assets/themes/style.less' // 主题样式
+// import { timerInterceptor } from '@/utils/timer'
+import { i18n } from '@/stores'
+// import Vconsole from 'vconsole'
+// new Vconsole()
+
+const app = createApp(App)
+app.use(i18n)
+app.use(router)
+app.use(directives)
+app.use(VXETable)
+app.use(layouts)
+app.mount('#app')
+
+// 等待 html 加载完成
+// document.addEventListener('DOMContentLoaded', () => {
+//     const { screenAdapter } = useGlobalStore()
+//     // 适配客户端
+//     screenAdapter(true)
+//     // 监听窗口大小变化
+//     window.addEventListener('resize', timerInterceptor.setDebounce(() => screenAdapter(true)))
+// }, false)

+ 10 - 0
src/packages/tss/postcss.config.js

@@ -0,0 +1,10 @@
+module.exports = {
+    plugins: {
+        'postcss-px-to-viewport': {
+            viewportWidth: 375,
+            landscape: true, // 是否处理横屏情况
+            landscapeUnit: 'vw', // 横屏时使用的单位
+            landscapeWidth: 844, // 横屏时使用的视口宽度
+        },
+    },
+}

+ 333 - 0
src/packages/tss/router/index.ts

@@ -0,0 +1,333 @@
+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'
+
+const loginStore = useLoginStore()
+
+const routes: Array<RouteRecordRaw> = [
+  {
+    path: '/:pathMatch(.*)*',
+    name: 'error',
+    component: () => import('@mobile/views/error/404.vue'),
+    meta: {
+      ignoreAuth: true,
+    },
+  },
+  {
+    path: '/boot',
+    name: 'boot',
+    component: () => import('../views/boot/Index.vue'),
+    meta: {
+      ignoreAuth: true,
+    },
+  },
+  {
+    path: '/',
+    component: Page,
+    children: [
+      {
+        path: '',
+        name: 'home',
+        component: () => import('@mobile/views/home/Index.vue'),
+        props: {
+          iosUpdateUrl: 'https://itunes.apple.com/lookup?id=6483808619'
+        },
+        children: [
+          {
+            path: '',
+            name: 'home-index',
+            component: () => import('@mobile/views/home/main/Index.vue'),
+            meta: {
+              ignoreAuth: true,
+            },
+          },
+          {
+            path: 'mine',
+            name: 'home-mine',
+            component: () => import('../views/mine/Index.vue'),
+          },
+          ...homeRoutes
+        ]
+      }
+    ]
+  },
+  {
+    path: '/user',
+    component: Page,
+    children: [
+      {
+        path: 'login',
+        name: 'user-login',
+        component: () => import('../views/user/login/Index.vue'),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+      {
+        path: 'register',
+        name: 'user-register',
+        component: () => import('@mobile/views/user/register/Index.vue'),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+      {
+        path: 'forget',
+        name: 'user-forget',
+        component: () => import('@mobile/views/user/forget/Index.vue'),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+      {
+        path: 'cancel',
+        name: 'user-cancel',
+        component: () => import('@mobile/views/user/cancel/Index.vue'),
+      },
+      {
+        path: 'password',
+        name: 'user-password',
+        component: () => import('@mobile/views/user/password/Index.vue'),
+      },
+      {
+        path: 'avatar',
+        name: 'user-avatar',
+        component: () => import('@mobile/views/user/avatar/Index.vue'),
+      },
+    ],
+  },
+  {
+    path: '/report',
+    component: Page,
+    children: [
+      {
+        path: '',
+        name: 'report',
+        component: () => import('@mobile/views/report/index.vue'),
+      }
+    ]
+  },
+  {
+    path: '/account',
+    component: Page,
+    children: [
+      {
+        path: 'certification',
+        name: 'account-certification',
+        component: () => import('@mobile/views/account/certification/Index.vue'),
+      },
+      {
+        path: 'authresult',
+        name: 'account-authresult',
+        component: () => import('@mobile/views/account/authresult/Index.vue'),
+      }
+    ],
+  },
+  {
+    path: '/news',
+    component: Page,
+    children: [
+      {
+        path: '',
+        name: 'news-list',
+        component: () => import('@mobile/views/news/list/Index.vue'),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+      {
+        path: 'detail',
+        name: 'news-detail',
+        component: () => import('@mobile/views/news/detail/Index.vue'),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+    ],
+  },
+  {
+    path: '/bank',
+    component: Page,
+    children: [
+      {
+        path: 'wallet',
+        name: 'bank-wallet',
+        component: () => import('@mobile/views/bank/wallet/Index.vue'),
+      },
+      {
+        path: 'sign',
+        name: 'bank-sign',
+        component: () => import('@mobile/views/bank/sign/Index.vue'),
+      },
+      {
+        path: 'capital',
+        name: 'bank-capital',
+        component: () => import('@mobile/views/bank/capital/index.vue'),
+      }
+    ],
+  },
+  {
+    path: '/order',
+    component: Page,
+    children: [
+      {
+        path: 'list',
+        name: 'order-list',
+        component: () => import('../views/order/list/Index.vue'),
+      },
+      {
+        path: 'position',
+        name: 'order-position',
+        component: () => import('../views/order/position/Index.vue'),
+      },
+      {
+        path: 'delivery',
+        name: 'order-delivery',
+        component: () => import('../views/order/delivery/Index.vue'),
+      },
+      {
+        path: 'performance',
+        name: 'order-performance',
+        component: () => import('@mobile/views/order/performance/Index.vue'),
+      }
+    ]
+  },
+  {
+    path: '/mine',
+    component: Page,
+    children: [
+      {
+        path: 'address',
+        name: 'mine-address',
+        component: () => import('@mobile/views/mine/address/Index.vue'),
+      },
+      {
+        path: 'invoice',
+        name: 'mine-invoice',
+        component: () => import('@mobile/views/mine/invoice/Index.vue'),
+      },
+      {
+        path: 'profile',
+        name: 'mine-profile',
+        component: () => import('@mobile/views/mine/profile/Index.vue'),
+      },
+      {
+        path: 'setting',
+        name: 'mine-setting',
+        component: () => import('@mobile/views/mine/setting/Index.vue'),
+      },
+      {
+        path: 'wechat',
+        name: 'mine-wechat',
+        component: () => import('@mobile/views/mine/wechat/Index.vue'),
+      },
+      {
+        path: 'email',
+        name: 'mine-email',
+        component: () => import('@mobile/views/mine/email/Index.vue'),
+      }
+    ],
+  },
+  {
+    path: '/notice',
+    component: Page,
+    children: [
+      {
+        path: '',
+        name: 'notice-list',
+        component: () => import('@mobile/views/notice/list/index.vue'),
+      },
+    ],
+  },
+  {
+    path: '/rules',
+    component: Page,
+    children: [
+      {
+        path: "zcxy",
+        name: "rules-zcxy",
+        component: () => import("@mobile/views/rules/zcxy/Index.vue"),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+      {
+        path: "yhkhfxgzs",
+        name: "rules-yhkhfxgzs",
+        component: () => import("@mobile/views/rules/fxgzs/Index.vue"),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+      {
+        path: "yszc",
+        name: "rules-yszc",
+        component: () => import("@mobile/views/rules/yszc/Index.vue"),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+      {
+        path: "gywm",
+        name: "rules-gywm",
+        component: () => import("@mobile/views/rules/gywm/Index.vue"),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+      {
+        path: "fwrx",
+        name: "rules-fwrx",
+        component: () => import("@mobile/views/rules/fwrx/Index.vue"),
+        meta: {
+          ignoreAuth: true,
+        },
+      },
+    ]
+  },
+  ...pageRoutes
+]
+
+const router = animateRouter.create({
+  history: createWebHashHistory(),
+  routes,
+})
+
+// 路由跳转拦截
+router.beforeEach((to, from, next) => {
+  clearPending()
+  // 判断服务是否加载完成
+  if (service.isReady) {
+    if (to.meta.ignoreAuth || loginStore.token) {
+      next()
+    } else {
+      if (to.matched.some((e) => e.name === 'home')) {
+        // 如果是主页导航页面,强制跳转到首页
+        next({
+          name: 'home-index',
+          replace: true,
+        })
+      } else {
+        next({
+          name: 'user-login',
+          query: { redirect: to.fullPath },
+        })
+      }
+    }
+  } else {
+    if (to.name === 'boot' || to.name === 'user-login') {
+      next()
+    } else {
+      next({
+        name: 'boot',
+        query: { redirect: to.fullPath },
+      })
+    }
+  }
+})
+
+export default router

+ 99 - 0
src/packages/tss/views/boot/Index.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="boot" :style="`background-image: url(${'./app/splashscreen/1080x1920.png'});`">
+    <Swipe class="boot__guide" :loop="false" v-if="state.showGuide">
+      <SwipeItem>
+        <img :src="'./app/splashscreen/1080x1920.png'" />
+      </SwipeItem>
+      <SwipeItem>
+        <img src="../../assets/images/guide-1.png" />
+      </SwipeItem>
+      <SwipeItem>
+        <img src="../../assets/images/guide-2.png" @click="skip(init())" />
+      </SwipeItem>
+    </Swipe>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { reactive, onUnmounted } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
+import { Swipe, SwipeItem } from 'vant'
+import { showLoading, dialog } from '@/utils/vant'
+import { useLogin } from '@/business/login'
+import service from '@/services'
+import plus from '@/utils/h5plus'
+
+const { logining, initBaseData } = useLogin()
+const route = useRoute()
+const router = useRouter()
+const countdown = 1  // 倒计时秒数
+
+const state = reactive({
+  showGuide: false,
+  //showGuide: (!plus.hasPlus() || localStorage.getItem('muchinfo_app_showguide') === 'false') ? false : true, // 是否显示引导页
+  second: countdown, // 剩余秒数
+  currentRate: 100, // 当前进度
+  rate: 100, // 目标进度
+})
+
+const init = () => initBaseData(true) // 初始化数据
+const onLoad = state.showGuide ? Promise.resolve() : init()
+
+// 倒计时
+const timer = window.setInterval(() => {
+  state.second--
+  state.rate = (100 / countdown) * state.second
+  if (state.second <= 0) {
+    clearInterval(timer)
+    // 判断是否首次打开应用
+    if (!state.showGuide) {
+      skip(onLoad)
+    }
+  }
+}, 1000)
+
+// 跳过广告
+const skip = (promise: Promise<void>) => {
+  clearInterval(timer)
+  const toast = logining.value ? showLoading() : undefined
+
+  promise.then(() => {
+    localStorage.setItem('muchinfo_app_showguide', 'false')
+    const redirect = route.query.redirect
+    if (redirect) {
+      router.replace(redirect.toString())
+    } else {
+      router.replace({ name: 'home-index' })
+    }
+  }).catch((err) => {
+    if (service.isReady) {
+      router.replace({ name: 'home-index' })
+    } else {
+      tryInit(err)
+    }
+  }).finally(() => {
+    toast?.close()
+  })
+}
+
+// 初始化失败重试
+const tryInit = (message: string) => {
+  dialog({
+    message,
+    showCancelButton: plus.hasPlus(),
+    cancelButtonText: '退出',
+    confirmButtonText: '重试'
+  }).then(() => {
+    skip(init())
+  }).catch(() => {
+    plus.quit()
+  })
+}
+
+plus.setFullSreen()
+onUnmounted(() => plus.exitFullSreen())
+</script>
+
+<style lang="less" scoped>
+@import './index.less';
+</style>

+ 19 - 0
src/packages/tss/views/boot/index.less

@@ -0,0 +1,19 @@
+.boot {
+    height: 100vh;
+    background-color: #fff;
+    background-repeat: no-repeat;
+    background-position: center top;
+    background-size: cover;
+    overflow: hidden;
+
+    &__guide {
+        width: 100%;
+        height: 100%;
+
+        img {
+            width: 100%;
+            height: 100%;
+            object-fit: contain;
+        }
+    }
+}

+ 226 - 0
src/packages/tss/views/mine/Index.vue

@@ -0,0 +1,226 @@
+<template>
+    <app-view class="mine">
+        <template #header>
+            <app-navbar :title="$t('mine.title')" :show-back-button="false" @ready="onReady" />
+        </template>
+        <div ref="headerRef" class="mine-header">
+            <div class="mine-header__wrapper">
+                <div class="profile">
+                    <div class="profile-user">
+                        <div class="profile-user__avatar" @click="routerTo('user-avatar')">
+                            <img class="g-image--avatar" :src="userStore.userAvatar" />
+                        </div>
+                        <div class="profile-user__info">
+                            <div class="top">
+                                <span>{{ userStore.customerName }}</span>
+                                <Icon name="checked" color="var(--van-tag-success-color)"
+                                    v-if="authStatus === AuthStatus.Certified" />
+                                <Icon name="warning" color="var(--van-tag-warning-color)" v-else />
+                            </div>
+                            <div class="bottom">{{ loginStore.loginId }}</div>
+                        </div>
+                    </div>
+                    <div class="profile-account">
+                        <span>{{ $t('mine.normal') }}</span>
+                        <span>{{ currentAccount.accountid ?? 0 }}</span>
+                    </div>
+                </div>
+                <div class="bank">
+                    <ul>
+                        <li>
+                            <span>{{ $t('mine.balance') }}</span>
+                            <span>{{ currentAccount.currentbalance?.toFixed(2) }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('mine.netWorth') }}</span>
+                            <span>{{ currentAccount.hazardValue?.toFixed(2) }}</span>
+                        </li>
+                    </ul>
+                    <ul>
+                        <li>
+                            <span>{{ $t('mine.freezeMargin') }}</span>
+                            <span>{{ currentAccount.freezeMargin?.toFixed(2) }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('mine.usedMargin') }}</span>
+                            <span>{{ currentAccount.usedmargin?.toFixed(2) }}</span>
+                        </li>
+                    </ul>
+                    <ul>
+                        <li>
+                            <span>{{ $t('mine.availableFunds') }}</span>
+                            <span>{{ currentAccount.avaiableMoney?.toFixed(2) }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('mine.riskRate') }}</span>
+                            <span :class="currentAccount.hazardRatioColor">
+                                {{ parsePercent(currentAccount.hazardRatio) }}
+                            </span>
+                        </li>
+                    </ul>
+                </div>
+                <div class="button">
+                    <Button type="danger" size="small" round @click="doInOutMoney('0')">{{ $t('mine.cashin') }}</Button>
+                    <Button size="small" round @click="doInOutMoney('1')">{{ $t('mine.cashout') }}</Button>
+                </div>
+            </div>
+        </div>
+        <app-block class="mine-iconbar">
+            <ul>
+                <li @click="routerTo('order-position')">
+                    <Iconfont label-direction="bottom" icon="g-icon-position--line">{{ $t('mine.myposition') }}</Iconfont>
+                </li>
+                <li @click="routerTo('order-list')">
+                    <Iconfont label-direction="bottom" icon="g-icon-order--line">{{ $t('mine.myorder') }}</Iconfont>
+                </li>
+                <li @click="routerTo('order-delivery')">
+                    <Iconfont label-direction="bottom" icon="g-icon-delivery--line">{{ $t('mine.delivery') }}</Iconfont>
+                </li>
+                <li @click="routerTo('order-performance')">
+                    <Iconfont label-direction="bottom" icon="g-icon-performance--line">{{ $t('mine.performance') }}</Iconfont>
+                </li>
+            </ul>
+        </app-block>
+        <app-block class="g-navmenu">
+            <CellGroup>
+                <Cell is-link :to="{ name: 'bank-capital' }">
+                    <template #title>
+                        <Iconfont icon="g-icon-capital">{{ $t('mine.fundsinfo') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'account-authresult' }" v-if="authStatus === AuthStatus.Submitted">
+                    <template #title>
+                        <Iconfont icon="g-icon-certification">{{ $t('mine.authentication') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'account-certification' }" v-else-if="authStatus !== AuthStatus.Certified">
+                    <template #title>
+                        <Iconfont icon="g-icon-certification">{{ $t('mine.authentication') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'bank-sign' }" v-if="authStatus === AuthStatus.Certified">
+                    <template #title>
+                        <Iconfont icon="g-icon-sign">{{ $t('mine.banksign') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'mine-profile' }">
+                    <template #title>
+                        <Iconfont icon="g-icon-profile">{{ $t('mine.personalinformation') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'rules-zcxy' }">
+                    <template #title>
+                        <Iconfont icon="g-icon-zcxy">{{ $t('rules.zcxy') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'rules-yszc' }">
+                    <template #title>
+                        <Iconfont icon="g-icon-yszc">{{ $t('rules.yszc') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'rules-fwrx' }">
+                    <template #title>
+                        <Iconfont icon="g-icon-fwrx">{{ $t('rules.fwrx') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'mine-setting' }">
+                    <template #title>
+                        <Iconfont icon="g-icon-setting">{{ $t('mine.settings') }}</Iconfont>
+                    </template>
+                </Cell>
+                <Cell is-link :to="{ name: 'rules-gywm' }">
+                    <template #title>
+                        <Iconfont icon="g-icon-gywm">{{ $t('mine.aboutus') }}</Iconfont>
+                    </template>
+                </Cell>
+            </CellGroup>
+        </app-block>
+        <div class="mine-footer">
+            <Button class="button-logout" type="danger" size="small" round @click="userLogout">{{ $t('common.logout') }}</Button>
+        </div>
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, onActivated, computed } from 'vue'
+import { Cell, CellGroup, Button, Icon } from 'vant'
+import { fullloading, dialog } from '@/utils/vant'
+import { parsePercent } from '@/filters'
+import { useNavigation } from '@mobile/router/navigation'
+import { AuthStatus } from '@/constants/account'
+import { queryBankAccountSign } from '@/services/api/bank'
+import { useLoginStore, useAccountStore, useUserStore,  } from '@/stores'
+import eventBus from '@/services/bus'
+import Iconfont from '@/components/base/iconfont/index.vue'
+import { i18n } from '@/stores'
+
+const { global: { t } } = i18n
+const { router, routerTo } = useNavigation()
+const loginStore = useLoginStore()
+const userStore = useUserStore()
+const accountStore = useAccountStore()
+const { currentAccount } = accountStore.$toRefs()
+
+const headerRef = shallowRef<HTMLDivElement>()
+const authStatus = computed(() => userStore.userAccount.hasauth) // 实名认证状态
+
+const onReady = (el: HTMLDivElement) => {
+    // 设置背景图位置
+    headerRef.value?.style.setProperty('background-position', `0 -${el.clientHeight}px`)
+}
+
+/// 进行出入金操作判断
+const doInOutMoney = (tab: string) => {
+    if (authStatus.value === AuthStatus.Certified) {
+        fullloading((hideLoading) => {
+            queryBankAccountSign().then((res) => {
+                hideLoading()
+                const { signstatus } = res.data[0] ?? {}
+                /// 只有已签约的情况下才可以进行出入金
+                if (signstatus && signstatus === 4) {
+                    router.push({ name: 'bank-wallet', query: { tab } })
+                } else {
+                    dialog({
+                        message: t('banksign.tips1'),
+                        showCancelButton: true,
+                        confirmButtonText: t('banksign.tips2')
+                    }).then(() => {
+                        router.push({ name: 'bank-sign' })
+                    })
+                }
+            }).catch(() => {
+                hideLoading(t('common.loadingfailed'), 'fail')
+            })
+        }, t('common.loading'))
+    } else {
+        dialog({
+            message: t('banksign.tips3'),
+            showCancelButton: true,
+            confirmButtonText: t('banksign.tips4')
+        }).then(() => {
+            router.push({ name: 'account-certification' })
+        })
+    }
+}
+
+const userLogout = () => {
+    dialog({
+        message: t('banksign.tips5'),
+        showCancelButton: true
+    }).then(() => {
+        loginStore.clearAutoLoginData()
+        eventBus.$emit('LogoutNotify')
+    })
+}
+
+onActivated(() => {
+    if (authStatus.value !== AuthStatus.Certified) {
+        userStore.getUserData()
+    }
+    accountStore.getAccountList()
+})
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 168 - 0
src/packages/tss/views/mine/index.less

@@ -0,0 +1,168 @@
+@import '@mobile/assets/themes/base/mixin.less';
+
+.mine {
+    @backgroundImage: linear-gradient(var(--navbar-background), var(--navbar-background) 150px, transparent 150px);
+
+    .app-navbar {
+        background-image: @backgroundImage;
+
+        &__wrapper {
+            color: #fff;
+            background-color: transparent;
+        }
+    }
+
+    &-header {
+        color: #000;
+        background-color: #fff;
+        background-image: @backgroundImage;
+        padding: 0 18px;
+
+        &__wrapper {
+            background-color: #fff;
+            border-top-left-radius: 10px;
+            border-top-right-radius: 10px;
+            padding: 12px;
+        }
+
+        .profile {
+            display: flex;
+
+            &-user {
+                flex: 1;
+                display: flex;
+                align-items: center;
+
+                .g-image--avatar {
+                    width: 40px;
+                    height: 40px;
+                    border-radius: 50%;
+                    font-size: 0;
+                    margin-right: 8px;
+                }
+
+                &__info {
+                    flex: 1;
+                    padding-right: 16px;
+
+                    .top {
+                        display: flex;
+                        align-items: center;
+                        font-size: 12px;
+                        color: #A1B1C5;
+
+                        span {
+                            .mixin-text-overflow()
+                        }
+
+                        .van-icon {
+                            line-height: normal;
+                            margin-left: 2px;
+                        }
+                    }
+
+                    .bottom {
+                        line-height: 20px;
+                        font-size: 15px;
+                        font-weight: bold;
+                    }
+                }
+            }
+
+            &-account {
+                display: flex;
+                flex-direction: column;
+                justify-content: center;
+
+                span {
+                    line-height: 20px;
+
+                    &:first-child {
+                        font-size: 12px;
+                        color: #46D63C;
+
+                        &::before {
+                            content: '资金账户';
+                            color: #A1B1C5;
+                            margin-right: 6px;
+                        }
+                    }
+
+                    &:last-child {
+                        font-size: 15px;
+                        font-weight: bold;
+                    }
+                }
+            }
+        }
+
+        .bank {
+            display: flex;
+            justify-content: space-around;
+            padding: 18px 0;
+
+            ul {
+                li {
+                    display: flex;
+                    flex-direction: column;
+                    padding-bottom: 5px;
+                    
+                    span {
+                        line-height: 20px;
+
+                        &:first-child {
+                            font-size: 12px;
+                            color: #A1B1C5;
+                        }
+
+                        &:last-child {
+                            font-size: 15px;
+                            font-weight: bold;
+                        }
+                    }
+                    
+                }
+            }
+        }
+
+        .button {
+            display: flex;
+            justify-content: space-around;
+
+            .van-button {
+                width: 140px;
+                box-shadow: 0 3px 7px 0 #e0e2e8;
+            }
+        }
+    }
+
+    &-iconbar {
+        ul {
+            display: flex;
+            background-color: #fff;
+            padding: 12px;
+
+            li {
+                flex: 1;
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+
+                .g-icon {
+                    font-size: 28px;
+                    margin-bottom: 2px;
+                }
+            }
+        }
+    }
+
+    &-footer {
+        text-align: center;
+        padding: 10px 0;
+
+        .button-logout {
+            width: 50%;
+            border: 0;
+        }
+    }
+}

+ 49 - 0
src/packages/tss/views/order/delivery/Index.vue

@@ -0,0 +1,49 @@
+<template>
+    <app-view>
+        <template #header>
+            <app-navbar :title="$t('delivery.title')">
+                <template #right v-if="selectedComponent.history">
+                    <div class="button-more" @click="openComponent(selectedComponent.name)">
+                        <span>{{ $t('common.more') }}</span>
+                    </div>
+                </template>
+            </app-navbar>
+        </template>
+        <Tabs class="van-tabs--list" v-model:active="active" :swipe-threshold="4">
+            <template v-for="(item, index) in components" :key="index">
+                <Tab :title="item.title" :name="index">
+                    <component :is="item.component" />
+                </Tab>
+            </template>
+        </Tabs>
+        <component ref="componentRef" :is="selectedComponent.history" @closed="closeComponent"
+            v-if="componentId && selectedComponent.history" />
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, defineAsyncComponent, computed } from 'vue'
+import { Tab, Tabs } from 'vant'
+import { useComponent } from '@/hooks/component'
+import { i18n } from '@/stores'
+
+const { global: { t } } = i18n
+
+const components = [
+    {
+        name: 'goodsorder',
+        title: t('delivery.online.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/delivery/components/online/list/Index.vue')),
+        history: defineAsyncComponent(() => import('@mobile/views/order/delivery/components/online/history/Index.vue')),
+    },
+    {
+        name: 'listingorder',
+        title: t('delivery.spot.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/delivery/components/spot/list/Index.vue')),
+    }
+]
+
+const active = shallowRef(0)
+const selectedComponent = computed(() => components[active.value])
+const { componentRef, componentId, openComponent, closeComponent } = useComponent()
+</script>

+ 66 - 0
src/packages/tss/views/order/list/Index.vue

@@ -0,0 +1,66 @@
+<template>
+    <app-view>
+        <template #header>
+            <app-navbar :title="$t('order.title')">
+                <template #right v-if="selectedComponent.history">
+                    <div class="button-more" @click="openComponent(selectedComponent.name)">
+                        <span>{{ $t('common.more') }}</span>
+                    </div>
+                </template>
+            </app-navbar>
+        </template>
+        <Tabs class="van-tabs--list" v-model:active="active" :swipe-threshold="4">
+            <template v-for="(item, index) in components" :key="index">
+                <Tab :title="item.title" :name="index">
+                    <component :is="item.component" />
+                </Tab>
+            </template>
+        </Tabs>
+        <component ref="componentRef" :is="selectedComponent.history" @closed="closeComponent"
+            v-if="componentId && selectedComponent.history" />
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, defineAsyncComponent, computed } from 'vue'
+import { Tab, Tabs } from 'vant'
+import { useComponent } from '@/hooks/component'
+import { i18n } from '@/stores'
+
+const { global: { t } } = i18n
+
+const components = [
+    {
+        name: 'pricingorder',
+        title: t('order.pricingorder.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/list/components/pricingorder/list/Index.vue')),
+    },
+    {
+        name: 'pricingtrade',
+        title: t('order.pricingtrade.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/list/components/pricingtrade/list/Index.vue')),
+    },
+    {
+        name: 'presale',
+        title: t('order.presale.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/list/components/presale/list/Index.vue')),
+        history: defineAsyncComponent(() => import('@mobile/views/order/list/components/presale/history/index.vue')),
+    },
+    {
+        name: 'transferorder',
+        title: t('order.transferorder.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/list/components/transferorder/list/Index.vue')),
+        history: defineAsyncComponent(() => import('@mobile/views/order/list/components/transferorder/history/index.vue')),
+    },
+    {
+        name: 'transfertrade',
+        title: t('order.transfertrade.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/list/components/transfertrade/list/Index.vue')),
+        history: defineAsyncComponent(() => import('@mobile/views/order/list/components/transfertrade/history/index.vue')),
+    },
+]
+
+const active = shallowRef(0)
+const selectedComponent = computed(() => components[active.value])
+const { componentRef, componentId, openComponent, closeComponent } = useComponent()
+</script>

+ 59 - 0
src/packages/tss/views/order/position/Index.vue

@@ -0,0 +1,59 @@
+<template>
+    <app-view>
+        <template #header>
+            <app-navbar :title="$t('position.title')">
+                <template #right v-if="selectedComponent.detail">
+                    <div class="button-more" @click="openComponent(selectedComponent.name)">
+                        <span>{{ $t('position.holddetail') }}</span>
+                    </div>
+                </template>
+            </app-navbar>
+        </template>
+        <Tabs class="van-tabs--list" v-model:active="active" :swipe-threshold="4">
+            <template v-for="(item, index) in components" :key="index">
+                <Tab :title="item.title" :name="index">
+                    <component :is="item.component" />
+                </Tab>
+            </template>
+        </Tabs>
+        <component ref="componentRef" :is="selectedComponent.detail" @closed="closeComponent"
+            v-if="componentId && selectedComponent.detail" />
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, computed, defineAsyncComponent } from 'vue'
+import { Tab, Tabs } from 'vant'
+import { useComponent } from '@/hooks/component'
+import { i18n } from '@/stores'
+
+const { global: { t } } = i18n
+
+const components = [
+    {
+        name: 'pricing',
+        title: t('position.pricing.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/list/Index.vue')),
+        detail: defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/detail/Index.vue')),
+    },
+    {
+        name: 'spot',
+        title: t('position.spot.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/position/components/spot/list/Index.vue')),
+    },
+    {
+        name: 'presale',
+        title: t('position.presale.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/position/components/presale/list/Index.vue')),
+    },
+    {
+        name: 'transfer',
+        title: t('position.transfer.title'),
+        component: defineAsyncComponent(() => import('@mobile/views/order/position/components/transfer/list/Index.vue')),
+    }
+]
+
+const active = shallowRef(0)
+const selectedComponent = computed(() => components[active.value])
+const { componentRef, componentId, openComponent, closeComponent } = useComponent()
+</script>

+ 13 - 0
src/packages/tss/views/user/login/Index.vue

@@ -0,0 +1,13 @@
+<template>
+  <AppLogin :logo-src="logoImage" />
+</template>
+
+<script lang="ts" setup>
+import { onMounted, onUnmounted } from 'vue'
+import plus from '@/utils/h5plus'
+import AppLogin from '@mobile/components/layouts/login/index.vue'
+import logoImage from '../../../assets/images/login-logo.png'
+
+onMounted(() => plus.setStatusBarStyle('dark'))
+onUnmounted(() => plus.setStatusBarStyle('light'))
+</script>