li.shaoyi il y a 1 an
Parent
commit
cb3d6579f9

+ 27 - 0
oem/quote/androidPrivacy.json

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

+ 17 - 0
oem/quote/config/appconfig.json

@@ -0,0 +1,17 @@
+{
+  "appId": "cn.muchinfo.quote",
+  "appName": "行情",
+  "version": "1.0.0",
+  "versionCode": "100000",
+  "apiUrl": "http://192.168.31.171:8080/cfg?key=test_171",
+  "tradeChannel": "ws",
+  "modules": [
+    "register",
+    "delivery"
+  ],
+  "quotationPropertys": [
+    "holdvolume"
+  ],
+  "forcedPasswordChange": true,
+  "riskType": 1
+}

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

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

BIN
oem/quote/favicon.ico


BIN
oem/quote/logo/logo-horizontal.png


+ 303 - 0
oem/quote/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",

+ 7 - 0
script/oem.env.json

@@ -13,6 +13,13 @@
         "VUE_APP_API_BETA": "http://103.40.249.126:18280/cfg?key=mtp_20"
     },
     {
+        "VUE_APP_ENV": "quote",
+        "VUE_APP_NAME": "行情",
+        "VUE_APP_ROOT": "src/packages/quote/",
+        "VUE_APP_OEM": "oem/quote/",
+        "VUE_APP_TRADE_CHANNEL": "ws"
+    },
+    {
         "VUE_APP_ENV": "qxst",
         "VUE_APP_NAME": "贵茶数字化",
         "VUE_APP_ROOT": "src/packages/qxst/",

+ 6 - 0
src/packages/quote/App.vue

@@ -0,0 +1,6 @@
+<template>
+  <router-view />
+</template>
+
+<script lang="ts" setup>
+</script>

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


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


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


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


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


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


+ 10 - 0
src/packages/quote/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;
+}

+ 76 - 0
src/packages/quote/assets/themes/default/default.less

@@ -0,0 +1,76 @@
+:root {
+    /* 字体大小规范 */
+    --font-x-large: 18px;
+    --font-large: 16px;
+    --font-medium: 14px;
+    --font-small: 12px;
+    --font-x-small: 10px;
+
+    /* 颜色规范 */
+    --color-default: #384048;
+    --color-primary: #243862;
+    --color-secondary: #04c786;
+    --color-info: #999;
+    --color-border: #eee;
+    --color-up: #ff2b2b;
+    --color-down: #04c786;
+
+    /* 导航栏 */
+    --navbar-height: 44px;
+    --navbar-color: #fff;
+    --navbar-background: var(--color-primary);
+    --navbar-backbutton-color: #fff;
+
+    /* 标签栏 */
+    --tabbar-background: #243862;
+    --tabbar-icon: #fff;
+    --tabbar-icon-active: #f7dc51;
+
+    /* 内容边距 */
+    --content-inset: 12px;
+
+    /* Vant-Button */
+    --van-button-border-width: 0;
+    --van-button-primary-background: var(--color-primary);
+    --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;
+            }
+        }
+    }
+}
+
+.van-cell {
+    &.nowrap &__title {
+        flex: none;
+    }
+}

+ 487 - 0
src/packages/quote/assets/themes/global/global.less

@@ -0,0 +1,487 @@
+[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;
+
+    .goods {
+        background-color: #fff;
+        border-radius: 6px;
+        overflow: hidden;
+
+        &-image {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            min-height: 120px;
+            font-size: 0;
+        }
+
+        &-info {
+            padding: 10px;
+
+            &__title {
+                font-size: 13px;
+                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: 14px;
+                }
+
+                .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;
+            }
+        }
+
+        .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% / 4');
+        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/quote/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/quote/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';

+ 23 - 0
src/packages/quote/index.html

@@ -0,0 +1,23 @@
+<!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">
+  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+  <title>
+    <%= htmlWebpackPlugin.options.title %>
+  </title>
+</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>
+  <!-- built files will be auto injected -->
+</body>
+
+</html>

+ 23 - 0
src/packages/quote/main.ts

@@ -0,0 +1,23 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import directives from '@/directives' // 自定义指令集
+import ElementPlus from 'element-plus'
+import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
+import * as ElementIcons from '@element-plus/icons-vue'
+import 'hqchart/src/jscommon/umychart.resource/font/iconfont.css'
+import 'element-plus/dist/index.css'
+import './assets/themes/style.less' // 主题样式
+
+const app = createApp(App)
+app.use(router)
+app.use(directives)
+app.use(ElementPlus, {
+    locale: zhCn,
+})
+app.mount('#app')
+
+// 注册全局图标
+for (const [key, value] of Object.entries(ElementIcons)) {
+    app.component(key, value)
+}

+ 7 - 0
src/packages/quote/postcss.config.js

@@ -0,0 +1,7 @@
+module.exports = {
+    plugins: {
+        'postcss-px-to-viewport': {
+            viewportWidth: 1920,
+        },
+    },
+}

+ 25 - 0
src/packages/quote/router/index.ts

@@ -0,0 +1,25 @@
+import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
+import animateRouter from '@mobile/router/animateRouter'
+
+const routes: Array<RouteRecordRaw> = [
+  {
+    path: '/:pathMatch(.*)*',
+    name: 'error',
+    component: () => import('@mobile/views/error/404.vue'),
+    meta: {
+      ignoreAuth: true,
+    },
+  },
+  {
+    path: '/',
+    name: 'quote',
+    component: () => import('../views/quote/index.vue')
+  }
+]
+
+const router = animateRouter.create({
+  history: createWebHashHistory(),
+  routes,
+})
+
+export default router

+ 61 - 0
src/packages/quote/views/quote/index.less

@@ -0,0 +1,61 @@
+.quote {
+    min-height: 100%;
+    color: #fff;
+    background-color: #222;
+
+    &-header {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 20px 60px;
+
+        &__logo {
+            img {
+                height: 64px;
+            }
+        }
+
+        &__time {
+            display: flex;
+            gap: 20px;
+            font-size: 24px;
+        }
+    }
+
+    &-table {
+        width: 100%;
+        th {
+            color: #999;
+            text-align: left;
+            font-size: 28px;
+            border-top: 1px solid #999;
+            padding: 20px;
+
+            &:first-child{
+                padding-left: 60px;
+            }
+        }
+
+        tbody {
+            tr {
+                &:nth-child(odd) {
+                    background-color: #000;
+                }
+            }
+
+            td {
+                height: 100px;
+                font-size: 36px;
+                padding: 20px;
+
+                &:first-child{
+                    padding-left: 60px;
+                }
+
+                span {
+                    display: block;
+                }
+            }
+        }
+    }
+}

+ 178 - 0
src/packages/quote/views/quote/index.vue

@@ -0,0 +1,178 @@
+<template>
+    <div class="quote">
+        <div class="quote-header">
+            <div class="quote-header__logo">
+                <img :src="'./logo/logo-horizontal.png'" />
+            </div>
+            <div class="quote-header__time">
+                <span>
+                    {{ serverTime?.format('YYYY/MM/DD HH:mm:ss') }}
+                </span>
+                <span v-if="market">
+                    {{ [2, 6].includes(market.runstatus) ? getRunStatusName(market.runstatus) : '未开盘' }}
+                </span>
+            </div>
+        </div>
+        <table class="quote-table" cellspacing="0" cellpadding="0">
+            <thead>
+                <tr>
+                    <th>商品</th>
+                    <th>回购</th>
+                    <th>销售</th>
+                    <th>高</th>
+                    <th>低</th>
+                </tr>
+            </thead>
+            <tbody>
+                <tr v-for="(item, index) in touristTradeGoodsList" :key="index">
+                    <td>{{ item.goodsname }}</td>
+                    <td :class="item.bidColor">
+                        {{ handleNumberValue(formatDecimal(item.bid, item.decimalplace)) }}
+                    </td>
+                    <td :class="item.askColor">
+                        {{ handleNumberValue(formatDecimal(item.ask, item.decimalplace)) }}
+                    </td>
+                    <td :class="item.highestColor">
+                        {{ handleNumberValue(formatDecimal(item.highest, item.decimalplace)) }}
+                    </td>
+                    <td :class="item.lowestColor">
+                        {{ handleNumberValue(formatDecimal(item.lowest, item.decimalplace)) }}
+                    </td>
+                </tr>
+            </tbody>
+            <thead>
+                <tr>
+                    <th class="title" colspan="5">参考商品</th>
+                </tr>
+            </thead>
+            <tbody>
+                <tr v-for="(item, index) in touristRefGoodsList" :key="index">
+                    <td>{{ item.goodsname }}</td>
+                    <td :class="item.bidColor">
+                        {{ handleNumberValue(formatDecimal(item.bid, item.decimalplace)) }}
+                    </td>
+                    <td :class="item.askColor">
+                        {{ handleNumberValue(formatDecimal(item.ask, item.decimalplace)) }}
+                    </td>
+                    <td :class="item.highestColor">
+                        {{ handleNumberValue(formatDecimal(item.highest, item.decimalplace)) }}
+                    </td>
+                    <td :class="item.lowestColor">
+                        {{ handleNumberValue(formatDecimal(item.lowest, item.decimalplace)) }}
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, computed, onActivated, onDeactivated, ref, onMounted, onUnmounted } from 'vue'
+import moment, { Moment } from 'moment'
+import { getServerTime } from '@/services/api/common'
+import { handleNumberValue, formatDecimal } from '@/filters'
+import { queryTouristGoods, queryTouristQuoteDay } from '@/services/api/goods'
+import { useEnumStore, useFuturesStore } from '@/stores'
+import { timerTask } from '@/utils/timer'
+import { useRequest } from '@/hooks/request'
+import { getRunStatusName } from '@/constants/market'
+import { queryMarketRun } from '@/services/api/market'
+import quoteSocket from '@/services/websocket/quote'
+import service from '@/services'
+
+const enumStore = useEnumStore()
+const futuresStore = useFuturesStore()
+const subscribe = quoteSocket.createSubscribe()
+
+// 订阅的商品代码
+const subscribeData = shallowRef<string[]>([])
+// 系统时间
+const serverTime = ref<Moment>()
+
+service.onReady().then(() => {
+    enumStore.getAllEnumList()
+    
+    // 获取游客商品列表
+    queryTouristGoods().then((res) => {
+        futuresStore.goodsList = res.data
+        subscribeData.value = res.data.map((e) => e.goodscode)
+
+        // 获取游客商品盘面
+        queryTouristQuoteDay({
+            data: {
+                goodsCodes: subscribeData.value.join(',')
+            }
+        }).then((res) => {
+            subscribeData.value.forEach((goodscode) => {
+                const item = res.data.find((e) => e.goodscode === goodscode)
+                futuresStore.updateQuotation(item ?? { goodscode })
+            })
+            subscribe.start(...subscribeData.value)
+
+            const [firstMarket] = touristTradeGoodsList.value
+            if (firstMarket) {
+                /// 获取市场运行情况
+                marketRun({
+                    marketID: firstMarket.marketid
+                })
+            }
+        })
+    })
+
+    // 校验服务器时间
+    const checkServerTime = () => {
+        getServerTime().then((res) => {
+            serverTime.value = moment.parseZone(res.data)
+            // 每1分钟同步一次服务器时间
+            timerTask.setTimeout(() => {
+                checkServerTime()
+            }, 60 * 1000, 'getServerTime')
+        })
+    }
+
+    checkServerTime()
+})
+
+
+const { data: market, run: marketRun } = useRequest(queryMarketRun, {
+    manual: true,
+    onSuccess: (res) => {
+        market.value = res.data[0]
+        // 每1分钟轮询刷新
+        timerTask.setTimeout(() => marketRun(), 60 * 1000, 'getMarketRun')
+    }
+})
+
+
+// 构建游客交易商品
+const touristTradeGoodsList = computed(() => {
+    const list = futuresStore.getGoodsListByTradeMode(52)
+    return list.sort((a, b) => a.goodsorder.localeCompare(b.goodsorder))
+})
+
+// 构建游客参考行情商品
+const touristRefGoodsList = computed(() => {
+    const list = futuresStore.getGoodsListByTradeMode(99, 97)
+    return list.sort((a, b) => a.goodsorder.localeCompare(b.goodsorder))
+})
+
+onMounted(() => {
+    serverTime.value = moment(new Date())
+    timerTask.setInterval(() => {
+        serverTime.value = moment(serverTime.value).add(1000, 'ms')
+    }, 1000, 'refreshTime')
+})
+
+onActivated(() => subscribeData.value.length && subscribe.start(...subscribeData.value))
+onDeactivated(() => subscribe.stop())
+
+onUnmounted(() => {
+    timerTask.clearInterval('refreshTime')
+    timerTask.clearTimeout('getServerTime')
+    timerTask.clearTimeout('getMarketRun')
+})
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 3 - 3
src/packages/sbyj/views/order/list/components/supplement-deposit/index.vue

@@ -3,7 +3,7 @@
     <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal" :refresh="refresh">
         <app-view class="g-form">
             <template #header>
-                <app-navbar title="补充金" @back="closed" />
+                <app-navbar title="补充金" @back="closed" />
             </template>
             <Form ref="formRef" class="g-form__container" @submit="onSubmit">
                 <CellGroup inset>
@@ -26,7 +26,7 @@
                         </template>
                     </Field>
                     <Field name="RestockDeposit" :rules="formRules.RestockDeposit"
-                        :label="orderType === 1 ? '补充订金' : '退返订金'">
+                        :label="orderType === 1 ? '补充定金' : '退返定金'">
                         <template #input>
                             <Stepper v-if="orderType === 1" v-model="supplementDepositReq.RestockDeposit" theme="round"
                                 button-size="22" :auto-fixed="false" />
@@ -71,7 +71,7 @@ const orderType = shallowRef(1) // 1-补充 2-退返
 // 表单验证规则
 const formRules: { [key: string]: FieldRule[] } = {
     RestockDeposit: [{
-        message: '请输入定金额',
+        message: '请输入定金额',
         validator: (val) => {
             if (val) {
                 if (orderType.value === 2) {

+ 1 - 1
src/stores/index.ts

@@ -1,7 +1,7 @@
 export { useEnumStore } from './modules/enum'
 export { useLoginStore } from './modules/login'
-export { useUserStore } from './modules/user'
 export { useGlobalStore } from './modules/global'
+export { useUserStore } from './modules/user'
 export { useMenuStore } from './modules/menu'
 export { useAccountStore } from './modules/account'
 export { useFuturesStore } from './modules/futures'