li.shaoyi 2 tahun lalu
induk
melakukan
2f10155341
100 mengubah file dengan 134 tambahan dan 5130 penghapusan
  1. 19 0
      src/filters/index.ts
  2. 1 1
      src/packages/gstj/App.vue
  3. TEMPAT SAMPAH
      src/packages/gstj/assets/app_logo/1024x1024.png
  4. 0 1
      src/packages/gstj/assets/iconfont/iconfont.js
  5. TEMPAT SAMPAH
      src/packages/gstj/assets/images/boot-1080p.png
  6. TEMPAT SAMPAH
      src/packages/gstj/assets/images/boot-480p.png
  7. TEMPAT SAMPAH
      src/packages/gstj/assets/images/boot-720p.png
  8. 0 357
      src/packages/gstj/assets/themes/global/global.css
  9. 59 0
      src/packages/gstj/assets/themes/global/global.less
  10. 0 14
      src/packages/gstj/components/base/banner/index.less
  11. 0 46
      src/packages/gstj/components/base/banner/index.vue
  12. 0 62
      src/packages/gstj/components/base/html-container/index.vue
  13. 0 12
      src/packages/gstj/components/base/html-panel/index.less
  14. 0 42
      src/packages/gstj/components/base/html-panel/index.vue
  15. 0 17
      src/packages/gstj/components/base/iconfont/index.less
  16. 0 64
      src/packages/gstj/components/base/iconfont/index.vue
  17. 0 71
      src/packages/gstj/components/base/list/index.less
  18. 0 59
      src/packages/gstj/components/base/list/index.vue
  19. 0 40
      src/packages/gstj/components/base/popup/index.less
  20. 0 45
      src/packages/gstj/components/base/popup/index.vue
  21. 0 4
      src/packages/gstj/components/base/pull-refresh/index.less
  22. 0 114
      src/packages/gstj/components/base/pull-refresh/index.vue
  23. 0 10
      src/packages/gstj/components/base/qrcode-scan/index.less
  24. 0 79
      src/packages/gstj/components/base/qrcode-scan/index.vue
  25. 0 13
      src/packages/gstj/components/base/region/index.less
  26. 0 103
      src/packages/gstj/components/base/region/index.vue
  27. 0 39
      src/packages/gstj/components/base/router-transition/index.backup.less
  28. 0 83
      src/packages/gstj/components/base/router-transition/index.less
  29. 0 18
      src/packages/gstj/components/base/router-transition/index.vue
  30. 0 13
      src/packages/gstj/components/base/select/index.less
  31. 0 96
      src/packages/gstj/components/base/select/index.vue
  32. 0 47
      src/packages/gstj/components/base/tabbar/index.less
  33. 0 69
      src/packages/gstj/components/base/tabbar/index.vue
  34. 0 7
      src/packages/gstj/components/base/tabbar/types.ts
  35. 0 28
      src/packages/gstj/components/base/table/index.less
  36. 0 72
      src/packages/gstj/components/base/table/index.vue
  37. 0 8
      src/packages/gstj/components/base/table/types.ts
  38. 0 43
      src/packages/gstj/components/base/uploader/index.vue
  39. 0 12
      src/packages/gstj/components/base/waterfall/index.less
  40. 0 112
      src/packages/gstj/components/base/waterfall/index.vue
  41. 0 27
      src/packages/gstj/components/layouts/block/index.less
  42. 0 14
      src/packages/gstj/components/layouts/block/index.vue
  43. 0 1
      src/packages/gstj/components/layouts/footer/index.less
  44. 0 12
      src/packages/gstj/components/layouts/footer/index.vue
  45. 0 25
      src/packages/gstj/components/layouts/form/index.vue
  46. 0 30
      src/packages/gstj/components/layouts/index.ts
  47. 0 23
      src/packages/gstj/components/layouts/navback/index.less
  48. 0 30
      src/packages/gstj/components/layouts/navback/index.vue
  49. 0 70
      src/packages/gstj/components/layouts/navbar/index.less
  50. 0 75
      src/packages/gstj/components/layouts/navbar/index.vue
  51. 0 6
      src/packages/gstj/components/layouts/page/index.less
  52. 0 46
      src/packages/gstj/components/layouts/page/index.vue
  53. 0 19
      src/packages/gstj/components/layouts/scroll-view/index.less
  54. 0 120
      src/packages/gstj/components/layouts/scroll-view/index.vue
  55. 0 25
      src/packages/gstj/components/layouts/statusbar/index.vue
  56. 0 24
      src/packages/gstj/components/layouts/view/index.less
  57. 0 38
      src/packages/gstj/components/layouts/view/index.vue
  58. 0 30
      src/packages/gstj/components/modules/contact/index.vue
  59. 0 158
      src/packages/gstj/components/modules/delivery/index.vue
  60. 0 77
      src/packages/gstj/components/modules/delivery/warehouse-receipt.vue
  61. 0 3
      src/packages/gstj/components/modules/echarts-line/index.less
  62. 0 55
      src/packages/gstj/components/modules/echarts-line/index.vue
  63. 0 8
      src/packages/gstj/components/modules/pdf/index.vue
  64. 0 19
      src/packages/gstj/components/modules/performance/index.less
  65. 0 52
      src/packages/gstj/components/modules/performance/index.vue
  66. 0 46
      src/packages/gstj/components/modules/performance/list/index.less
  67. 0 75
      src/packages/gstj/components/modules/performance/list/index.vue
  68. 0 17
      src/packages/gstj/components/modules/quote/chart/index.less
  69. 0 110
      src/packages/gstj/components/modules/quote/chart/index.vue
  70. 0 45
      src/packages/gstj/components/modules/quote/chart/kline/index.less
  71. 0 114
      src/packages/gstj/components/modules/quote/chart/kline/index.vue
  72. 0 33
      src/packages/gstj/components/modules/quote/chart/timeline/index.less
  73. 0 36
      src/packages/gstj/components/modules/quote/chart/timeline/index.vue
  74. 0 42
      src/packages/gstj/components/modules/quote/forex/index.less
  75. 0 176
      src/packages/gstj/components/modules/quote/forex/index.vue
  76. 0 23
      src/packages/gstj/components/modules/quote/index.vue
  77. 0 90
      src/packages/gstj/components/modules/quote/price/index.less
  78. 0 108
      src/packages/gstj/components/modules/quote/price/index.vue
  79. 0 3
      src/packages/gstj/components/modules/quote/tik/index.less
  80. 0 94
      src/packages/gstj/components/modules/quote/tik/index.vue
  81. 0 30
      src/packages/gstj/components/modules/receipt/index.vue
  82. 0 20
      src/packages/gstj/components/modules/register-code/index.less
  83. 0 63
      src/packages/gstj/components/modules/register-code/index.vue
  84. 2 2
      src/packages/gstj/main.ts
  85. 0 159
      src/packages/gstj/router/animateRouter.ts
  86. 48 127
      src/packages/gstj/router/index.ts
  87. 0 129
      src/packages/gstj/router/navigation.ts
  88. 0 96
      src/packages/gstj/views/account/certification/Index.vue
  89. 0 71
      src/packages/gstj/views/bank/sign/Index.vue
  90. 0 131
      src/packages/gstj/views/bank/sign/components/edit/Index.vue
  91. 0 19
      src/packages/gstj/views/bank/sign/index.less
  92. 0 78
      src/packages/gstj/views/bank/statement/Index.vue
  93. 0 70
      src/packages/gstj/views/bank/statement/history/Index.vue
  94. 0 27
      src/packages/gstj/views/bank/wallet/Index.vue
  95. 0 143
      src/packages/gstj/views/bank/wallet/components/deposit/Index.vue
  96. 0 35
      src/packages/gstj/views/bank/wallet/components/deposit/index.less
  97. 0 105
      src/packages/gstj/views/bank/wallet/components/withdraw/Index.vue
  98. 0 22
      src/packages/gstj/views/bank/wallet/components/withdraw/index.less
  99. 2 2
      src/packages/gstj/views/boot/Index.vue
  100. 3 1
      src/packages/gstj/views/boot/index.less

+ 19 - 0
src/filters/index.ts

@@ -236,4 +236,23 @@ export function encryptDesMobile(mobile: string) {
 export function getEncryptMobile(mobile: string) {
     const encryptMobile = encryptDesMobile(mobile)
     return encryptMobile.replace(new RegExp('\\+', 'g'), '*').replace(new RegExp('\\/', 'g'), '-').replace(new RegExp('\\=', 'g'), '.')
+}
+
+/**
+ * 版本号转数值
+ * @param value 
+ * @returns 
+ */
+export function versionToNumber(value: number | string) {
+    if (value) {
+        const num = value.toString().split(/\D/)
+        // 版本号位数
+        const place = ['', '0', '00', '000', '0000', '00000', '000000'].reverse()
+        for (let i = 0; i < num.length; i++) {
+            const len = num[i].length
+            num[i] = place[len] + num[i]
+        }
+        return +num.join('')
+    }
+    return 0
 }

+ 1 - 1
src/packages/gstj/App.vue

@@ -3,7 +3,7 @@
 </template>
 
 <script lang="ts" setup>
-import { useNavigation } from './router/navigation'
+import { useNavigation } from '@mobile/router/navigation'
 import { dialog } from '@/utils/vant'
 import { useLogin } from '@/business/login'
 import eventBus from '@/services/bus'

TEMPAT SAMPAH
src/packages/gstj/assets/app_logo/1024x1024.png


File diff ditekan karena terlalu besar
+ 0 - 1
src/packages/gstj/assets/iconfont/iconfont.js


TEMPAT SAMPAH
src/packages/gstj/assets/images/boot-1080p.png


TEMPAT SAMPAH
src/packages/gstj/assets/images/boot-480p.png


TEMPAT SAMPAH
src/packages/gstj/assets/images/boot-720p.png


+ 0 - 357
src/packages/gstj/assets/themes/global/global.css

@@ -1,357 +0,0 @@
-[class*='g-image'] {
-  position: relative;
-  object-fit: cover;
-  overflow: hidden;
-}
-[class*='g-image']: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-up {
-  color: #ff3333;
-}
-.g-price-normal {
-  color: #333333;
-}
-.g-price-down {
-  color: #0baf1f;
-}
-.g-form__container {
-  display: flex;
-  flex-direction: column;
-  padding-bottom: 0.32rem;
-  /* 父元素的第一个子元素 */
-  /* 相邻兄弟元素 */
-}
-.g-form__container .van-cell-group--inset:first-of-type {
-  margin-top: 0.32rem;
-}
-.g-form__container .van-cell-group--inset + .van-cell-group--inset {
-  margin-top: 0.24rem;
-}
-.g-form__container .van-field .van-stepper {
-  display: flex;
-  align-items: center;
-  width: 100%;
-}
-.g-form__container .van-field .van-stepper__input {
-  flex: 1;
-}
-.g-form__footer {
-  display: flex;
-  align-items: center;
-}
-.g-form__footer:empty {
-  display: none;
-}
-.g-form__footer.inset {
-  gap: 0.2rem;
-  padding: 0.2rem 0.32rem;
-}
-.g-flex {
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-}
-.g-flex--row {
-  flex-direction: row;
-}
-.g-flex__body {
-  flex: 1;
-  overflow-y: auto;
-  -webkit-overflow-scrolling: touch;
-}
-.g-flex__footer {
-  margin-top: auto;
-}
-.g-color--up {
-  color: var(--color-up);
-}
-.g-color--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-navmenu .app-iconfont__icon {
-  font-size: 0.32rem;
-  margin-right: 0.24rem;
-}
-/* 商品列表 */
-.g-goods-list {
-  padding: 0.2rem;
-}
-.g-goods-list .list {
-  padding: 0.2rem 0.2rem 0 0.2rem;
-}
-.g-goods-list .list-item {
-  display: flex;
-  align-items: center;
-  border-radius: 0.1rem;
-  overflow: hidden;
-  padding: 0.2rem;
-}
-.g-goods-list .list-item:not(:last-child) {
-  margin-bottom: 0.2rem;
-}
-.g-goods-list .list-item .img:first-child {
-  display: flex;
-  align-items: center;
-}
-.g-goods-list .list-item .img:first-child img {
-  width: 1.8rem;
-  height: 1.8rem;
-  object-fit: cover;
-  border-radius: 0.16rem;
-  margin-right: 0.3rem;
-}
-.g-goods-list .list-item .img:last-child .van-button {
-  width: 1.3rem;
-  height: 0.5rem;
-}
-.g-goods-list .list-item .info {
-  flex: 1;
-}
-.g-goods-list .list-item .info .title {
-  color: #333;
-  font-size: 0.3rem;
-}
-.g-goods-list .list-item .info .desc {
-  color: #666;
-  font-size: 0.24rem;
-  padding: 0.1rem 0;
-}
-.g-goods-list .list-item .info .price .buyprice,
-.g-goods-list .list-item .info .price .sellprice {
-  padding-bottom: 0.02rem;
-}
-.g-goods-waterfall {
-  padding: 0.2rem;
-}
-.g-goods-waterfall .goods {
-  background-color: #fff;
-  border-radius: 0.12rem;
-  overflow: hidden;
-}
-.g-goods-waterfall .goods-image {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  min-height: 2.4rem;
-  font-size: 0;
-}
-.g-goods-waterfall .goods-info {
-  padding: 0.2rem;
-}
-.g-goods-waterfall .goods-info__title {
-  font-size: 0.26rem;
-  margin-bottom: 0.1rem;
-}
-.g-goods-waterfall .goods-info__desc {
-  font-size: 0.24rem;
-  color: #999;
-  margin-bottom: 0.1rem;
-}
-.g-goods-waterfall .goods-info__price {
-  color: #f2270c;
-}
-.g-goods-waterfall .goods-info__price .unit {
-  font-size: 0.24rem;
-}
-.g-goods-waterfall .goods-info__price .integer {
-  font-size: 0.3rem;
-}
-/* 订单列表 */
-.g-order-list {
-  padding: 0.2rem;
-  padding-bottom: 0;
-}
-.g-order-list__box {
-  background-color: #fff;
-  border-radius: 0.16rem;
-  padding: 0.24rem;
-}
-.g-order-list__box:not(:first-child) {
-  margin-top: 0.2rem;
-}
-.g-order-list__titlebar {
-  display: flex;
-  justify-content: space-between;
-  margin-bottom: 0.2rem;
-}
-.g-order-list__titlebar .left h4 {
-  font-weight: bold;
-}
-.g-order-list__titlebar .left span {
-  font-size: 0.24rem;
-  color: #999;
-}
-.g-order-list__titlebar .right {
-  font-size: 0.24rem;
-  color: #999;
-}
-.g-order-list__content {
-  font-size: 0.24rem;
-}
-.g-order-list__content ul {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: space-between;
-}
-.g-order-list__content ul li {
-  display: flex;
-  justify-content: space-between;
-  line-height: 0.4rem;
-  width: calc(50% - .24rem);
-}
-.g-order-list__content ul li span:first-child {
-  color: #999;
-  white-space: nowrap;
-  padding-right: 0.24rem;
-}
-.g-order-list__btnbar {
-  display: flex;
-  justify-content: flex-end;
-  gap: 0.16rem;
-  margin-top: 0.2rem;
-}
-.g-order-list__btnbar .van-button {
-  width: 1.6rem;
-  border-width: 1px;
-}
-.g-detail__buy {
-  background-color: #fff;
-}
-.g-detail__buy .topic {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  color: #fff;
-  background-image: linear-gradient(to right, #ee0a24, #ff6034);
-  padding: 0.2rem 0.24rem;
-}
-.g-detail__buy .topic-left .price-text {
-  font-size: 0.24rem;
-}
-.g-detail__buy .topic-left .price-integer {
-  font-size: 0.44rem;
-}
-.g-detail__buy .topic-right {
-  display: flex;
-  flex-direction: column;
-  font-size: 0.24rem;
-}
-.g-detail__buy .title {
-  font-size: 0.3rem;
-  font-weight: bold;
-  line-height: 0.48rem;
-  padding: 0.24rem;
-  padding-bottom: 0;
-}
-.g-detail__buy .title .van-tag {
-  font-weight: normal;
-}
-.g-detail__buy .title span {
-  margin-right: 0.1rem;
-}
-.g-detail__buy .desc {
-  padding: 0 0.24rem;
-}
-.g-detail__buy .qty {
-  font-size: 0.24rem;
-  color: #999;
-  padding: 0.1rem 0.24rem 0 0.24rem;
-}
-.g-detail__buy .info {
-  background-color: #fff;
-  padding: 0.2rem;
-}
-.g-detail__buy .info ul {
-  display: flex;
-  flex-wrap: wrap;
-  font-size: 0.26rem;
-}
-.g-detail__buy .info ul li {
-  display: flex;
-  justify-content: space-between;
-  width: 50%;
-  padding: 0.08rem 0.24rem;
-}
-.g-detail__buy .info ul li span:first-child {
-  color: #999;
-}
-.g-detail__desc {
-  background-color: #fff;
-  margin-top: 0.24rem;
-}
-.g-detail__footer {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  height: 0.88rem;
-  background-color: #fff;
-}
-.g-detail__footer .price {
-  padding-left: 0.32rem;
-}
-.g-detail__footer .price-text,
-.g-detail__footer .price-unit {
-  font-size: 0.24rem;
-}
-.g-detail__footer .price-unit {
-  color: #f2270c;
-}
-.g-detail__footer .price-integer {
-  font-size: 0.32rem;
-  color: #f2270c;
-}
-.g-detail__footer .submit {
-  align-self: stretch;
-  display: flex;
-  margin-left: auto;
-}
-.g-detail__footer .submit-button {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  height: 100%;
-  min-width: 2rem;
-  font-weight: bold;
-  color: #fff;
-  padding: 0 0.48rem;
-}
-.g-detail__footer .submit-button.warning {
-  background-image: linear-gradient(to right, #ffd01e, #ff8917);
-  background-color: #ff8a17;
-}
-.g-detail__footer .submit-button.danger {
-  background-image: linear-gradient(to right, #ff6034, #ee0a24);
-  background-color: #ee270a;
-}
-.van-dialog__message {
-  font-size: 0.28rem;
-  line-height: 0.44rem;
-}
-.van-tabs--list {
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-}
-.van-tabs--list .van-tabs__content {
-  flex: 1;
-  overflow-y: auto;
-}
-.van-tabs--list .van-tabs__content .van-tab__panel {
-  height: 100%;
-}

+ 59 - 0
src/packages/gstj/assets/themes/global/global.less

@@ -446,6 +446,65 @@
     }
 }
 
+.g-qty-group {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+
+    &__stepper {
+        display: flex;
+        align-items: center;
+        gap: .1rem;
+        width: 100%;
+
+        .van-stepper {
+            flex: 1;
+            display: flex;
+
+            &__input {
+                flex: 1;
+            }
+        }
+    }
+
+    .van-radio-group {
+        display: flex;
+        flex-wrap: wrap;
+        width: 100%;
+        margin-top: .2rem;
+    }
+
+    .van-radio {
+        width: calc(~'100% / 3');
+        padding: .04rem;
+        margin-right: 0;
+
+        .van-radio__icon {
+            display: none;
+        }
+
+        &__label {
+            display: block;
+            width: 100%;
+            font-size: .24rem;
+            text-align: center;
+            color: #666;
+            border: 1px solid #e5e5e5;
+            border-radius: .08rem;
+            padding: .04rem;
+            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 {

+ 0 - 14
src/packages/gstj/components/base/banner/index.less

@@ -1,14 +0,0 @@
-.app-banner {
-    background-color: #ddd;
-
-    .van-swipe {
-        &-item {
-            font-size: 0;
-
-            img {
-                width: 100%;
-                height: 100%;
-            }
-        }
-    }
-}

+ 0 - 46
src/packages/gstj/components/base/banner/index.vue

@@ -1,46 +0,0 @@
-<template>
-    <div class="app-banner" :style="`min-height: ${swipeHeight};`">
-        <Swipe :autoplay="5000" indicator-color="white" lazy-render>
-            <SwipeItem v-for="(src, index) in dataList" :key="index" :style="`height: ${swipeHeight};`">
-                <slot :src="src">
-                    <img :src="getFileUrl(src)" @click="onClick(index)" />
-                </slot>
-            </SwipeItem>
-        </Swipe>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { PropType, computed } from 'vue'
-import { Swipe, SwipeItem } from 'vant'
-import { getFileUrl } from '@/filters'
-
-const props = defineProps({
-    //数据列表
-    dataList: {
-        type: Array as PropType<string[]>,
-        default: () => ([])
-    },
-    height: {
-        type: [Number, String],
-        default: 180,
-    }
-})
-
-const emit = defineEmits(['click'])
-
-const swipeHeight = computed(() => {
-    if (typeof props.height === 'number') {
-        return props.height + 'px'
-    }
-    return props.height
-})
-
-const onClick = (index: number) => {
-    emit('click', index)
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 62
src/packages/gstj/components/base/html-container/index.vue

@@ -1,62 +0,0 @@
-<template>
-    <div ref="htmlRef" v-html="context"></div>
-</template>
-  
-<script lang="ts" setup>
-import { shallowRef, onMounted, onUnmounted } from 'vue'
-import plus from '@/utils/h5plus'
-import PhotoSwipeLightbox, { SlideData } from 'photoswipe/lightbox'
-import 'photoswipe/style.css'
-
-defineProps({
-    context: {
-        type: String,
-        default: ''
-    }
-})
-
-let lightbox: PhotoSwipeLightbox = null
-const htmlRef = shallowRef<HTMLElement>()
-
-onMounted(() => {
-    const el = htmlRef.value
-    if (el) {
-        el.querySelectorAll('a').forEach((e) => {
-            const href = e.href
-            e.onclick = () => plus.openURL(href)
-            e.removeAttribute('href')
-        })
-
-        if (!lightbox) {
-            lightbox = new PhotoSwipeLightbox({
-                gallery: el,
-                children: 'img',
-                pswpModule: () => import('photoswipe'),
-            })
-
-            // https://photoswipe.com/data-sources/#custom-html-markup
-            lightbox.addFilter('domItemData', (itemData: SlideData, el: HTMLImageElement) => {
-                if (el) {
-                    itemData.src = el.src
-                    itemData.w = el.naturalWidth
-                    itemData.h = el.naturalHeight
-                    itemData.msrc = el.src
-                }
-                return itemData
-            })
-
-            lightbox.on('beforeOpen', () => plus.hideStatusBar())
-            lightbox.on('close', () => plus.showStatusBar())
-            lightbox.init()
-        }
-    }
-})
-
-onUnmounted(() => {
-    if (lightbox) {
-        lightbox.destroy()
-        lightbox = null
-    }
-})
-</script>
-  

+ 0 - 12
src/packages/gstj/components/base/html-panel/index.less

@@ -1,12 +0,0 @@
-.app-html {
-    display: flex;
-    flex-direction: column;
-    height: 100%;
-    padding: .2rem;
-
-    iframe {
-        flex: 1;
-        background-color: #fff;
-        border: 0;
-    }
-}

+ 0 - 42
src/packages/gstj/components/base/html-panel/index.vue

@@ -1,42 +0,0 @@
-<template>
-    <div class="app-html">
-        <iframe ref="iframeRef" :src="url" v-if="show" />
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from 'vue'
-//import http from '@/services/http'
-
-defineProps({
-    url: {
-        type: String,
-        required: true
-    },
-})
-
-const iframeRef = shallowRef<HTMLIFrameElement>()
-const show = shallowRef(false)
-
-setTimeout(() => {
-    show.value = true
-}, 200)
-
-// ios 不支持请求本地文件
-// http.request<string>({
-//     url: props.url,
-//     method: 'get',
-//     responseEncoding: 'utf-8'
-// }).then((res) => {
-//     const iframe = iframeRef.value?.contentWindow
-//     if (iframe) {
-//         iframe.document.open()
-//         iframe.document.write(res)
-//         iframe.document.close()
-//     }
-// })
-</script>
-
-<style lang="less" scoped>
-@import './index.less';
-</style>

+ 0 - 17
src/packages/gstj/components/base/iconfont/index.less

@@ -1,17 +0,0 @@
-.app-iconfont {
-    display        : inline-flex;
-    justify-content: center;
-    align-items    : center;
-
-    &__icon {
-        width         : 1em;
-        height        : 1em;
-        vertical-align: -0.15em;
-        fill          : currentColor;
-        overflow      : hidden;
-    }
-
-    &__label {
-        line-height: 1;
-    }
-}

+ 0 - 64
src/packages/gstj/components/base/iconfont/index.vue

@@ -1,64 +0,0 @@
-<template>
-    <div ref="iconfontRef" class="app-iconfont">
-        <svg :class="['app-iconfont__icon', active && 'is-active']" aria-hidden="true" :style="iconStyles">
-            <use :xlink:href="activeIconName" :fill="activeColor" v-if="active" />
-            <use :xlink:href="iconName" :fill="color" v-else />
-        </svg>
-        <span class="app-iconfont__label">
-            <slot></slot>
-        </span>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, computed, PropType, onMounted } from 'vue'
-
-const props = defineProps({
-    icon: {
-        type: String,
-        required: true
-    },
-    color: String,
-    size: String,
-    active: Boolean,
-    activeIcon: String,
-    activeColor: String,
-    // 标签方向
-    labelDirection: {
-        type: String as PropType<'left' | 'right' | 'top' | 'bottom'>,
-        default: 'right',
-    },
-})
-
-const iconfontRef = shallowRef<HTMLDivElement>()
-const iconName = computed(() => '#' + props.icon)
-const activeIconName = computed(() => '#' + (props.activeIcon ?? props.icon))
-
-const iconStyles = computed(() => ({
-    fontSize: props.size
-}))
-
-onMounted(() => {
-    const el = iconfontRef.value
-    if (el) {
-        switch (props.labelDirection) {
-            case 'left': {
-                el.style.setProperty('flex-direction', 'row-reverse')
-                break
-            }
-            case 'top': {
-                el.style.setProperty('flex-direction', 'column-reverse')
-                break
-            }
-            case 'bottom': {
-                el.style.setProperty('flex-direction', 'column')
-                break
-            }
-        }
-    }
-})
-</script>
-
-<style lang="less" scoped>
-@import './index.less';
-</style>

+ 0 - 71
src/packages/gstj/components/base/list/index.less

@@ -1,71 +0,0 @@
-.app-list {
-    min-width: 100%;
-    background-color: #fff;
-    overflow-x: auto;
-    padding: 0 .32rem;
-
-    &__table {
-        width: 100%;
-        text-align: center;
-
-        th {
-            font-size: .24rem;
-            font-weight: normal;
-            color: #999;
-            white-space: nowrap;
-        }
-
-        td {
-            white-space: nowrap;
-        }
-    }
-
-    &__row {
-        position: relative;
-
-        &::after {
-            content: '';
-            position: absolute;
-            bottom: 0;
-            right: 0;
-            left: 0;
-            pointer-events: none;
-            border-bottom: 1px solid #eee;
-            transform: scaleY(.5);
-        }
-    }
-
-    &__column {
-        padding: .12rem .16rem;
-    }
-
-    &__header &__column {
-        padding: 0 .16rem;
-    }
-
-    &__column:first-child &__cell {
-        align-items: flex-start;
-        padding-left: 0;
-    }
-
-    &__column:last-child &__cell {
-        align-items: flex-end;
-        padding-right: 0;
-    }
-
-    &__cell {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        min-height: .72rem;
-
-        .text-small {
-            font-size: .24rem;
-            color: #999;
-        }
-    }
-
-    &__body &__cell {
-        font-size: .28rem;
-    }
-}

+ 0 - 59
src/packages/gstj/components/base/list/index.vue

@@ -1,59 +0,0 @@
-<template>
-    <div class="app-list">
-        <table class="app-list__table" cellspacing="0" cellpadding="0">
-            <!-- <colgroup>
-                <col :width="colWidth" v-for="i in columns.length" :key="i" />
-            </colgroup> -->
-            <thead class="app-list__header" v-if="showHeader">
-                <tr class="app-list__row">
-                    <th class="app-list__column" v-for="(column, i) in columns" :key="i">
-                        <div class="app-list__cell">{{ column.label }}</div>
-                    </th>
-                </tr>
-            </thead>
-            <tbody class="app-list__body">
-                <template v-for="(row, i) in dataList" :key="i">
-                    <tr class="app-list__row" @click="rowClick(row, i)">
-                        <td class="app-list__column" :class="column.className" v-for="(column, n) in columns"
-                            :key="i + n.toString()">
-                            <div class="app-list__cell">
-                                <slot :name="column.prop" :value="row[column.prop]" :row="row">{{ row[column.prop] }}
-                                </slot>
-                            </div>
-                        </td>
-                    </tr>
-                </template>
-            </tbody>
-        </table>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { PropType } from 'vue'
-
-defineProps({
-    dataList: {
-        type: Array,
-        required: true,
-    },
-    columns: {
-        type: Array as PropType<Model.TableColumn[]>,
-        required: true,
-    },
-    showHeader: {
-        type: Boolean,
-        default: true
-    }
-})
-
-const emit = defineEmits(['rowClick'])
-//const colWidth = computed(() => (100 / props.columns.length) + '%')
-
-const rowClick = (row: unknown, index: number) => {
-    emit('rowClick', row, index)
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 40
src/packages/gstj/components/base/popup/index.less

@@ -1,40 +0,0 @@
-.app-popup {
-    .app-modal__container {
-        min-height: 50%;
-        border-radius: var(--van-popup-round-border-radius, .28rem) var(--van-popup-round-border-radius, .28rem) 0 0;
-        overflow: hidden;
-    }
-
-    .app-view {
-        background-color: #fff;
-    }
-
-    &__header {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        background-color: #fff;
-        padding: .32rem;
-        padding-bottom: 0;
-
-        .title {
-            font-size: .32rem;
-            font-weight: bold;
-        }
-    }
-
-    &__container {
-        background-color: #fff;
-
-        padding: .2rem;
-    }
-
-    &__footer {
-        background-color: #fff;
-        padding-top: .48rem;
-
-        &:empty {
-            display: none;
-        }
-    }
-}

+ 0 - 45
src/packages/gstj/components/base/popup/index.vue

@@ -1,45 +0,0 @@
-<template>
-    <app-modal class="app-popup" :show="show" direction="bottom" width="100%" @mask="closed">
-        <app-view class="g-form">
-            <template #header>
-                <slot name="header">
-                    <div class="app-popup__header">
-                        <div class="title">{{ title }}</div>
-                        <Icon name="close" size=".36rem" @click="closed" />
-                    </div>
-                </slot>
-            </template>
-            <div class="app-popup__container">
-                <slot></slot>
-            </div>
-            <template #footer>
-                <div class="g-form__footer app-popup__footer inset">
-                    <slot name="footer"></slot>
-                </div>
-            </template>
-        </app-view>
-    </app-modal>
-</template>
-
-<script lang="ts" setup>
-import { Icon } from 'vant'
-import AppModal from '@/components/base/modal/index.vue'
-
-defineProps({
-    show: {
-        type: Boolean,
-        default: false
-    },
-    title: String
-})
-
-const emit = defineEmits(['update:show'])
-
-const closed = () => {
-    emit('update:show', false)
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 4
src/packages/gstj/components/base/pull-refresh/index.less

@@ -1,4 +0,0 @@
-.app-pull-refresh {
-    height: 100%;
-    overflow-y: auto;
-}

+ 0 - 114
src/packages/gstj/components/base/pull-refresh/index.vue

@@ -1,114 +0,0 @@
-<template>
-    <PullRefresh class="app-pull-refresh" v-model="refreshing" @refresh="onRefresh">
-        <slot name="header"></slot>
-        <List ref="listRef" v-model:loading="showLoading" v-model:error="showError" :finished="finished" @load="onLoad">
-            <slot></slot>
-            <template #finished>
-                <span>{{ finishedText }}</span>
-            </template>
-            <template #error>
-                <span>{{ errorText }}</span>
-            </template>
-        </List>
-        <slot name="footer"></slot>
-    </PullRefresh>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, computed, nextTick, watch } from 'vue'
-import { List, PullRefresh, ListInstance } from 'vant'
-
-const props = defineProps({
-    loading: {
-        type: Boolean,
-        default: false,
-    },
-    pageIndex: {
-        type: Number,
-        default: 1,
-    },
-    pageCount: {
-        type: Number,
-        default: 1,
-    },
-    error: {
-        type: Boolean,
-        default: false,
-    },
-    finishedText: {
-        type: String,
-        default: '没有更多了',
-    },
-    errorText: {
-        type: String,
-        default: '请求失败,点击重新加载',
-    }
-})
-
-const emit = defineEmits(['update:loading', 'update:pageIndex', 'update:error', 'refresh'])
-const listRef = shallowRef<ListInstance>()
-const refreshing = shallowRef(false) // 是否处于下拉加载状态
-const finished = shallowRef(false) // 是否已加载完成所有数据
-const currentPage = shallowRef(props.pageIndex)
-
-const showLoading = computed({
-    get: () => props.loading,
-    set: (val) => emit('update:loading', val)
-})
-
-const showError = computed({
-    get: () => props.error,
-    set: (val) => emit('update:error', val)
-})
-
-// 上拉加载
-const onLoad = () => {
-    showLoading.value = false
-    if (refreshing.value) {
-        currentPage.value = 1
-    }
-    nextTick(() => {
-        if (currentPage.value <= props.pageCount) {
-            emit('refresh')
-        } else {
-            refreshing.value = false
-            finished.value = true
-        }
-    })
-}
-
-// 下拉刷新
-const onRefresh = () => {
-    // 下拉刷新过程中,可能会触发上拉加载,导致发送两次请求,所以先将 finished 设为 true,完成后再设为 false
-    finished.value = true
-    onLoad()
-}
-
-watch(showLoading, (status) => {
-    if (!status) {
-        finished.value = false
-        if (refreshing.value) {
-            refreshing.value = false
-        }
-        if (!showError.value) {
-            currentPage.value++
-        }
-    }
-})
-
-watch(currentPage, (val) => {
-    emit('update:pageIndex', val)
-})
-
-// 暴露组件属性给父组件调用
-defineExpose({
-    refresh: () => {
-        currentPage.value = 1
-        onRefresh()
-    },
-})
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 10
src/packages/gstj/components/base/qrcode-scan/index.less

@@ -1,10 +0,0 @@
-.app-qrcode-scan {
-    &__camera {
-        position: fixed;
-        bottom  : 0;
-        left    : 0;
-        z-index : 1000;
-        width   : 100vw;
-        height  : 30vh;
-    }
-}

+ 0 - 79
src/packages/gstj/components/base/qrcode-scan/index.vue

@@ -1,79 +0,0 @@
-<template>
-    <div class="app-qrcode-scan">
-        <div @click="scan">
-            <slot>
-                <Button type="primary">扫一扫</Button>
-            </slot>
-        </div>
-        <div id="camera" class="app-qrcode-scan__camera"></div>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { onMounted, shallowRef } from 'vue'
-import { Button, showFailToast } from 'vant'
-import { Html5Qrcode } from 'html5-qrcode'
-import plus from '@/utils/h5plus'
-
-const emit = defineEmits(['success'])
-const html5QrCode = shallowRef<Html5Qrcode>()
-const showCamera = shallowRef(false)
-
-const scan = () => {
-    plus.onPlusReady((plus) => {
-        const barcode = plus.barcode.create('barcode', [plus.barcode.QR], {
-            background: '#fff',
-            frameColor: '#07c160',
-            scanbarColor: '#07c160',
-            top: '100px',
-            left: '0px',
-            width: '100%',
-            height: '580px',
-            position: 'static'
-        });
-        barcode.onmarked = (type: any, result: any) => {
-            console.log('扫码成功', type, result)
-            emit('success', result)
-            barcode.close()
-        }
-        barcode.onerror = (err: any) => {
-            console.log('扫码失败', err)
-            showFailToast('扫码失败')
-        }
-        plus.webview.currentWebview().append(barcode);//必要的
-    })
-}
-
-const onScan = () => {
-    Html5Qrcode.getCameras().then(devices => {
-        if (devices && devices.length) {
-            html5QrCode.value?.start(
-                {
-                    facingMode: 'environment'
-                },
-                {
-                    fps: 10,
-                    qrbox: { width: 250, height: 250 }
-                },
-                (decodedText) => {
-                    emit('success', decodedText)
-                },
-                (err) => {
-                    console.log('html5QrCode', err)
-                }).catch(() => {
-                    showFailToast('获取设备信息失败')
-                })
-        }
-    }).catch(() => {
-        showFailToast('您需要授予相机访问权限')
-    })
-}
-
-onMounted(() => {
-    html5QrCode.value = new Html5Qrcode('camera')
-})
-</script>
-
-<style lang="less" scoped>
-@import './index.less';
-</style>

+ 0 - 13
src/packages/gstj/components/base/region/index.less

@@ -1,13 +0,0 @@
-.app-region {
-    flex       : 1;
-    display    : flex;
-    align-items: center;
-
-    &__input {
-        flex: 1;
-    }
-
-    input {
-        width: 100%;
-    }
-}

+ 0 - 103
src/packages/gstj/components/base/region/index.vue

@@ -1,103 +0,0 @@
-<template>
-    <div class="app-region" @click="onClick">
-        <slot :label="inputValue">
-            <input class="app-region__input" v-model="inputValue" :placeholder="placeholder" readonly />
-        </slot>
-        <Popup v-model:show="show" position="bottom" teleport="body" round>
-            <Cascader :title="title" v-model="selectedValue" :options="options" @close="show = false" @change="onChange"
-                @finish="onFinish" />
-        </Popup>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, computed, watch } from 'vue'
-import { Popup, Cascader, CascaderOption } from 'vant'
-import axios from 'axios'
-
-const props = defineProps({
-    modelValue: {
-        type: [String, Number],
-        default: 0
-    },
-    label: {
-        type: String,
-    },
-    title: {
-        type: String,
-        default: '请选择地区'
-    },
-    readonly: {
-        type: Boolean,
-        default: false
-    },
-    placeholder: {
-        type: String,
-        default: '请选择'
-    },
-})
-
-const emit = defineEmits(['update:modelValue', 'update:label', 'change', 'finish'])
-const show = shallowRef(false) // 是否弹出选择器
-const inputValue = shallowRef(props.label)
-const options = shallowRef<CascaderOption[]>([])
-
-// 选中的值
-const selectedValue = computed({
-    get: () => props.modelValue,
-    set: (val) => emit('update:modelValue', val)
-})
-
-const onClick = () => {
-    if (!props.readonly) {
-        show.value = true
-    }
-}
-
-// 选中项变化时触发
-const onChange = ({ value }: { value: string | number }) => {
-    emit('change', value)
-}
-
-// 全部选项选择完毕后触发
-const onFinish = ({ selectedOptions }: { selectedOptions: CascaderOption[] }) => {
-    const selection = selectedOptions.map((e) => e.value)
-    show.value = false
-    inputValue.value = selectedOptions.map((option) => option.text).join(' ')
-
-    emit('update:modelValue', [...selection].pop())
-    emit('update:label', inputValue.value)
-    emit('finish', selection)
-}
-
-// 扁平列表树形化
-const arrayToTree = (list: Model.Region[]) => {
-    const getChildren = (parent?: string) => {
-        const result: CascaderOption[] = []
-        list.forEach((e) => {
-            if (e.parentcode === parent) {
-                const children = getChildren(e.divisioncode)
-                result.push({
-                    text: e.divisionname,
-                    value: e.autoid,
-                    children: children.length ? children : undefined,
-                })
-            }
-        })
-        return result
-    }
-    return getChildren('0086')
-}
-
-watch(() => props.label, (val) => {
-    inputValue.value = val
-})
-
-axios('./config/address.json').then((res) => {
-    options.value = arrayToTree(res.data)
-})
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 39
src/packages/gstj/components/base/router-transition/index.backup.less

@@ -1,39 +0,0 @@
-/* 动画时长 */
-@transition-duration: 220ms;
-
-/* 无过渡效果 */
-.delay-enter-active,
-.delay-leave-active {
-    transition-duration: @transition-duration;
-}
-
-.route-in-enter-active,
-.route-in-leave-active,
-.route-out-enter-active,
-.route-out-leave-active {
-    pointer-events: none;
-    position: absolute;
-    transition-property: transform;
-    transition-duration: @transition-duration;
-    background-color: #fff;
-}
-
-.route-in-enter-from {
-    z-index: 1;
-    transform: translate3d(100%, 0, 0);
-}
-
-.route-out-enter-from {
-    z-index: 1;
-    transform: translate3d(-100%, 0, 0);
-}
-
-.route-out-leave-active {
-    transform: translate3d(100%, 0, 0);
-    transition-timing-function: ease-in;
-}
-
-.route-in-leave-active {
-    transform: translate3d(-100%, 0, 0);
-    transition-timing-function: ease-in;
-}

+ 0 - 83
src/packages/gstj/components/base/router-transition/index.less

@@ -1,83 +0,0 @@
-/* 动画时长 */
-@transition-duration: 220ms;
-
-/* 无过渡效果 */
-.delay-enter-active,
-.delay-leave-active {
-    transition-duration: @transition-duration;
-}
-
-.route-in-leave-from,
-.route-in-enter-from,
-.route-out-enter-from,
-.route-out-enter-from {
-    will-change: transform, opacity;
-}
-
-.route-in-leave-to,
-.route-in-enter-active,
-.route-out-leave-active,
-.route-out-enter-to {
-    pointer-events: none;
-    transition: transform @transition-duration;
-}
-
-.route-in-leave-from {
-    &::after {
-        content: '';
-        opacity: 0;
-    }
-}
-
-.route-in-leave-to {
-    &::after {
-        content: '';
-        position: absolute;
-        z-index: 100;
-        top: 0;
-        left: 0;
-        width: 100vw;
-        height: 100vh;
-        background-color: rgba(0, 0, 0, .5);
-        opacity: 1;
-        transition: opacity @transition-duration;
-    }
-}
-
-.route-in-enter-from {
-    transform: translate3d(100%, 0, 0);
-}
-
-.route-in-enter-active {
-    position: absolute;
-    z-index: 1000;
-    top: 0;
-}
-
-.route-out-leave-active {
-    position: absolute;
-    z-index: 1000;
-    transform: translate3d(100%, 0, 0);
-}
-
-.route-out-enter-from {
-    &::after {
-        content: '';
-        opacity: 1;
-    }
-}
-
-.route-out-enter-to {
-    &::after {
-        content: '';
-        position: absolute;
-        z-index: 100;
-        top: 0;
-        left: 0;
-        width: 100vw;
-        height: 100vh;
-        background-color: rgba(0, 0, 0, .5);
-        opacity: 0;
-        transition: opacity @transition-duration;
-    }
-}

+ 0 - 18
src/packages/gstj/components/base/router-transition/index.vue

@@ -1,18 +0,0 @@
-<template>
-    <transition :name="transitionName">
-        <slot></slot>
-    </transition>
-</template>
-  
-<script lang="ts" setup>
-defineProps({
-    transitionName: {
-        type: String,
-        default: 'delay'
-    }
-})
-</script>
-  
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 13
src/packages/gstj/components/base/select/index.less

@@ -1,13 +0,0 @@
-.app-select {
-    flex       : 1;
-    display    : flex;
-    align-items: center;
-
-    &__input {
-        flex: 1;
-    }
-
-    input {
-        width: 100%;
-    }
-}

+ 0 - 96
src/packages/gstj/components/base/select/index.vue

@@ -1,96 +0,0 @@
-<template>
-    <div class="app-select" @click="onClick">
-        <slot :label="inputValue">
-            <input class="'app-select__input'" v-model="inputValue" :placeholder="placeholder" readonly />
-        </slot>
-        <Popup v-model:show="show" position="bottom" teleport="body" round>
-            <Picker :columns="columns" @cancel="onCancel" @confirm="onConfirm" />
-        </Popup>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, computed, PropType, watch } from 'vue'
-import { Popup, Picker, PickerConfirmEventParams, FieldInstance } from 'vant'
-
-const props = defineProps({
-    modelValue: {
-        type: [Number, String]
-    },
-    options: {
-        type: Array,
-        default: () => ([])
-    },
-    optionProps: {
-        type: Object as PropType<{ label?: string; value?: string; }>,
-        default: () => ({
-            label: 'label',
-            value: 'value'
-        })
-    },
-    readonly: {
-        type: Boolean,
-        default: false
-    },
-    placeholder: {
-        type: String,
-        default: '请选择'
-    },
-})
-
-const emit = defineEmits(['update:show', 'update:modelValue', 'confirm'])
-const fieldRef = shallowRef<FieldInstance>()
-const show = shallowRef(false) // 是否弹出选择器
-const selectedIndex = shallowRef(-1)
-
-const columns = computed(() => {
-    if (props.options) {
-        return props.options.map((e) => ({
-            text: e[props.optionProps.label],
-            value: e[props.optionProps.value],
-        }))
-    }
-    return []
-})
-
-// 当前输入框的值
-const inputValue = computed(() => {
-    const item = props.options[selectedIndex.value]
-    if (item) {
-        return item[props.optionProps.label] ?? ''
-    }
-    return ''
-})
-
-const onClick = () => {
-    if (!props.readonly) {
-        show.value = true
-    }
-}
-
-const onCancel = () => {
-    show.value = false
-}
-
-const onConfirm = ({ selectedIndexes: [index], selectedValues: [value] }: PickerConfirmEventParams) => {
-    show.value = false
-    if (selectedIndex.value !== index) {
-        // 更新当前选中的值
-        selectedIndex.value = index
-        fieldRef.value?.validate()
-
-        emit('update:modelValue', value)
-        emit('confirm', value, index)
-    }
-}
-
-watch(() => [props.modelValue, props.options], ([value, items]) => {
-    selectedIndex.value = items.findIndex((e) => e[props.optionProps.value]?.toString() === value?.toString())
-}, {
-    immediate: true
-})
-</script>
-
-<style lang="less" scoped>
-@import './index.less';
-</style>

+ 0 - 47
src/packages/gstj/components/base/tabbar/index.less

@@ -1,47 +0,0 @@
-.app-tabbar {
-    height          : 1rem;
-    background-color: #fff;
-
-    &__wrapper {
-        bottom    : 0;
-        display   : flex;
-        width     : 100%;
-        height    : ~"calc(1rem - 1px)";
-        border-top: 1px solid #eee;
-        box-sizing: content-box;
-    }
-
-    &__item {
-        flex           : 1;
-        display        : flex;
-        flex-direction : column;
-        justify-content: center;
-        align-items    : center;
-        height         : inherit;
-        cursor         : pointer;
-
-        [class^='g-icon'] {
-            display        : flex;
-            flex-direction : column;
-            justify-content: center;
-            align-items    : center;
-
-            img {
-                width     : .44rem;
-                height    : .44rem;
-                object-fit: contain;
-            }
-
-            span {
-                font-size : .24rem;
-                margin-top: .05rem;
-            }
-
-            &:before {
-                width    : .44rem;
-                height   : .44rem;
-                font-size: .44rem;
-            }
-        }
-    }
-}

+ 0 - 69
src/packages/gstj/components/base/tabbar/index.vue

@@ -1,69 +0,0 @@
-<template>
-  <div class="app-tabbar">
-    <div class="app-tabbar__wrapper" :style="styles">
-      <template v-for="(item, index) in dataList" :key="index">
-        <div :class="['app-tabbar__item', 'app-tabbar__item--' + item.name, dataIndex === index && 'is-active']"
-          @click="onClick(index)">
-          <slot :item="item" :index="index">
-            <!--判断是否图片图标-->
-            <template v-if="item.iconType === 'image'">
-              <div :class="['g-icon', dataIndex === index && 'active']">
-                <img :src="item.activeIcon" v-if="dataIndex === index" />
-                <img :src="item.icon" v-else />
-                <span>{{ item.label }}</span>
-              </div>
-            </template>
-            <template v-else>
-              <app-iconfont label-direction="bottom" :icon="item.icon" :active-icon="item.activeIcon"
-                :active="dataIndex === index">{{ item.label }}</app-iconfont>
-            </template>
-          </slot>
-        </div>
-      </template>
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { PropType, computed } from 'vue'
-import { Tabbar } from './types'
-import { useGlobalStore } from '@/stores'
-import AppIconfont from '../../base/iconfont/index.vue'
-
-const emit = defineEmits(['click'])
-
-const props = defineProps({
-  // 数据列表
-  dataList: {
-    type: Array as PropType<Tabbar[]>,
-    default: () => ([]),
-  },
-  // 当前标签索引
-  dataIndex: {
-    type: Number,
-    default: 0,
-  },
-  // 是否固定在底部
-  fixed: {
-    type: Boolean,
-    default: false,
-  }
-})
-
-const globalStore = useGlobalStore()
-
-const styles = computed(() => ({
-  position: props.fixed ? 'fixed' : 'static',
-  width: globalStore.clientWidth + 'px',
-}))
-
-const onClick = (index: number) => {
-  if (props.dataIndex !== index) {
-    emit('click', index)
-  }
-}
-</script>
-
-<style lang="less" scoped>
-@import './index.less';
-</style>

+ 0 - 7
src/packages/gstj/components/base/tabbar/types.ts

@@ -1,7 +0,0 @@
-export interface Tabbar {
-    name: string;
-    label: string;
-    iconType?: 'iconfont' | 'image';
-    icon: string;
-    activeIcon?: string;
-}

+ 0 - 28
src/packages/gstj/components/base/table/index.less

@@ -1,28 +0,0 @@
-.app-table {
-    overflow: auto;
-
-    &__body {
-        width           : 100%;
-        text-align      : center;
-        background-color: #fff;
-        margin-bottom   : .2rem;
-        border          : 0;
-    }
-
-    & thead &__row {
-        background-color: #d9e2ed;
-    }
-
-    & thead &__cell {
-        padding: .12rem 0;
-    }
-
-    & tbody &__row {
-        background-color: #fff
-    }
-
-    & tbody &__cell {
-        color  : #666;
-        padding: .12rem 0;
-    }
-}

+ 0 - 72
src/packages/gstj/components/base/table/index.vue

@@ -1,72 +0,0 @@
-<template>
-    <div class="app-table">
-        <table class="app-table__body" cellspacing="0" cellpadding="0">
-            <thead>
-                <Draggable class="app-table__row" :list="columns" tag="tr" item-key="key">
-                    <template #header v-if="$slots.expand">
-                        <th class="app-table__cell expand"></th>
-                    </template>
-                    <template #item="{ element }">
-                        <th class="app-table__cell">{{ element.label }}</th>
-                    </template>
-                </Draggable>
-            </thead>
-            <tbody>
-                <template v-for="(row, i) in dataList" :key="i">
-                    <tr class="app-table__row" @click="rowClick(i)">
-                        <td class="app-table__cell expand" v-if="$slots.expand">
-                            <Icon name="arrow-down" v-if="selectedIndex === i" />
-                            <Icon name="arrow" v-else />
-                        </td>
-                        <td class="app-table__cell" :class="column.className" v-for="(column, n) in columns"
-                            :key="i + n.toString()">
-                            <slot :name="column.prop" :value="row[column.prop]" :row="row">{{ row[column.prop] }}</slot>
-                        </td>
-                    </tr>
-                    <!-- expand -->
-                    <tr class="app-table__row expand" v-show="selectedIndex === i" v-if="$slots.expand">
-                        <td class="app-table__cell" :colspan="columns.length + 1">
-                            <slot name="expandRow" :row="row"></slot>
-                        </td>
-                    </tr>
-                </template>
-            </tbody>
-        </table>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { PropType, ref } from 'vue'
-import { Icon } from 'vant'
-import { TableColumn } from './types'
-import Draggable from 'vuedraggable'
-
-const emit = defineEmits(['rowClick'])
-
-const props = defineProps({
-    // 数据列表
-    dataList: {
-        type: Array,
-        default: () => ([]),
-    },
-    columns: {
-        type: Array as PropType<TableColumn[]>,
-        default: () => ([]),
-    },
-})
-
-const selectedIndex = ref(-1);
-
-const rowClick = (index: number) => {
-    if (selectedIndex.value === index) {
-        selectedIndex.value = -1;
-    } else {
-        selectedIndex.value = index;
-    }
-    emit('rowClick', index, props.dataList[index]);
-}
-</script>
-
-<style lang="less" scoped>
-@import './index.less';
-</style>

+ 0 - 8
src/packages/gstj/components/base/table/types.ts

@@ -1,8 +0,0 @@
-export interface TableColumn {
-    prop: string;
-    label: string;
-    className?: string;
-    align?: string;
-    width?: number;
-    sort?: number;
-}

+ 0 - 43
src/packages/gstj/components/base/uploader/index.vue

@@ -1,43 +0,0 @@
-<template>
-    <Uploader v-model="fileList" :max-count="1" :max-size="5 * 1024 * 1024" @oversize="onOversize" :after-read="afterRead"
-        @delete="onDelete" />
-</template>
-
-<script lang="ts" setup>
-import { ref } from 'vue'
-import { showFailToast, Uploader, UploaderFileListItem } from 'vant'
-import service from '@/services'
-import axios from 'axios'
-
-const emit = defineEmits(['success'])
-const fileList = ref<UploaderFileListItem[]>([])
-
-const onOversize = () => {
-    showFailToast('图片大小不能超过 5Mb')
-}
-
-// eslint-disable-next-line
-const afterRead = (file: any) => {
-    const data = new FormData()
-    data.append('file', file.file)
-
-    file.status = 'uploading'
-    file.message = '上传中...'
-    axios.post(service.getConfig('uploadUrl'), data).then(res => {
-        if (res.status == 200) {
-            file.status = 'success'
-            file.message = '上传成功'
-            if (res.data.length) {
-                emit('success', res.data[0].filePath)
-            }
-        } else {
-            file.status = 'failed'
-            file.message = '上传失败'
-        }
-    })
-}
-
-const onDelete = () => {
-    emit('success', '')
-}
-</script>

+ 0 - 12
src/packages/gstj/components/base/waterfall/index.less

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

+ 0 - 112
src/packages/gstj/components/base/waterfall/index.vue

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

+ 0 - 27
src/packages/gstj/components/layouts/block/index.less

@@ -1,27 +0,0 @@
-.app-block {
-    padding: .2rem;
-    padding-bottom: 0;
-
-    &:last-of-type {
-        padding-bottom: .2rem;
-    }
-
-    &__wrapper {
-        background-color: #fff;
-        border-radius: .1rem;
-        overflow: hidden;
-    }
-
-    &.bg &__wrapper {
-        //background: #fff url('../../../assets/images/block-bg.png') no-repeat center bottom;
-        background-size: 100%;
-    }
-
-    &.flex &__wrapper {
-        display: flex;
-    }
-
-    &.flex--column &__wrapper {
-        flex-direction: column;
-    }
-}

+ 0 - 14
src/packages/gstj/components/layouts/block/index.vue

@@ -1,14 +0,0 @@
-<template>
-    <div class="app-block">
-        <div class="app-block__wrapper">
-            <slot></slot>
-        </div>
-    </div>
-</template>
-
-<script lang="ts" setup>
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 1
src/packages/gstj/components/layouts/footer/index.less

@@ -1 +0,0 @@
-.app-footer {}

+ 0 - 12
src/packages/gstj/components/layouts/footer/index.vue

@@ -1,12 +0,0 @@
-<template>
-    <div class="app-footer">
-        <slot></slot>
-    </div>
-</template>
-
-<script lang="ts" setup>
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 25
src/packages/gstj/components/layouts/form/index.vue

@@ -1,25 +0,0 @@
-<template>
-    <div class="app-form">
-        <div class="app-form__header">
-            <slot name="header"></slot>
-        </div>
-        <Form ref="formRef" class="app-form__body" @submit="formSubmit">
-            <slot></slot>
-        </Form>
-        <div class="app-form__footer">
-            <slot name="footer"></slot>
-        </div>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from 'vue'
-import { Form, FormInstance } from 'vant'
-
-const emit = defineEmits(['submit'])
-const formRef = shallowRef<FormInstance>()
-
-const formSubmit = () => {
-    emit('submit')
-}
-</script>

+ 0 - 30
src/packages/gstj/components/layouts/index.ts

@@ -1,30 +0,0 @@
-import { App } from 'vue'
-import AppPage from './page/index.vue'
-import AppView from './view/index.vue'
-import AppScrollView from './scroll-view/index.vue'
-import AppStatusbar from './statusbar/index.vue'
-import AppNavback from './navback/index.vue'
-import AppNavbar from './navbar/index.vue'
-import AppFooter from './footer/index.vue'
-import AppBlock from './block/index.vue'
-
-const components = {
-    AppPage,
-    AppView,
-    AppFooter,
-    AppScrollView,
-    AppStatusbar,
-    AppNavback,
-    AppNavbar,
-    AppBlock,
-}
-
-const install = (app: App) => {
-    for (const [key, value] of Object.entries(components)) {
-        app.component(key, value); //注册全局组件
-    }
-}
-
-export default {
-    install,
-}

+ 0 - 23
src/packages/gstj/components/layouts/navback/index.less

@@ -1,23 +0,0 @@
-.app-navback {
-    position: fixed;
-    left: 0;
-    top: 0;
-    z-index: 1;
-    display: inline-flex;
-
-    &:empty {
-        display: none;
-    }
-
-    >.van-icon {
-        display: inline-flex;
-        align-items: center;
-        justify-content: center;
-        height: var(--navbar-height);
-        line-height: 1;
-        font-size: .36rem;
-        color: var(--navbar-backbutton-color);
-        cursor: pointer;
-        padding: 0 .28rem;
-    }
-}

+ 0 - 30
src/packages/gstj/components/layouts/navback/index.vue

@@ -1,30 +0,0 @@
-<template>
-    <app-statusbar class="app-navback" @click="goback">
-        <slot>
-            <Icon name="arrow-left" />
-        </slot>
-    </app-statusbar>
-</template>
-
-<script lang="ts" setup>
-import { useAttrs } from 'vue'
-import { useRouter } from 'vue-router'
-import { Icon } from 'vant'
-
-const emit = defineEmits<{ (event: string, ...args: unknown[]): void }>()
-const router = useRouter()
-const attrs = useAttrs()
-
-// 返回按钮事件
-const goback = () => {
-    if (attrs.onBack) {
-        emit('back')
-    } else {
-        router.go(-1)
-    }
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 70
src/packages/gstj/components/layouts/navbar/index.less

@@ -1,70 +0,0 @@
-.app-navbar {
-    z-index: 100;
-
-    &__wrapper {
-        background: var(--navbar-background);
-        color: var(--navbar-color);
-    }
-
-    &__backbutton {
-        position: absolute;
-        z-index: 1;
-
-        &:empty {
-            display: none;
-        }
-
-        >.van-icon {
-            display: inline-flex;
-            align-items: center;
-            justify-content: center;
-            height: var(--navbar-height);
-            line-height: 1;
-            font-size: .36rem;
-            color: var(--navbar-backbutton-color);
-            cursor: pointer;
-            padding: 0 .28rem;
-        }
-    }
-
-    &__header {
-        display: flex;
-        align-items: center;
-
-        .column {
-            flex: 1;
-            display: inline-flex;
-            justify-content: center;
-            align-items: center;
-            height: var(--navbar-height);
-            white-space: nowrap;
-
-            &-block {
-                display: flex;
-                justify-content: center;
-                align-items: center;
-                height: 100%;
-            }
-
-            &--left>.column-block {
-                margin-right: auto;
-            }
-
-            &--right>.column-block {
-                padding-right: .28rem;
-                margin-left: auto;
-            }
-
-            &--center {
-                flex: auto;
-                font-size: .36rem;
-            }
-        }
-    }
-
-    &__footer {
-        &:empty {
-            display: none;
-        }
-    }
-}

+ 0 - 75
src/packages/gstj/components/layouts/navbar/index.vue

@@ -1,75 +0,0 @@
-<template>
-  <div class="app-navbar" :style="styles">
-    <app-navback class="app-navbar__backbutton" @back="goback" v-if="showBackButton" />
-    <app-statusbar class="app-navbar__wrapper" @ready="onReady">
-      <div class="app-navbar__header">
-        <div class="column column--left">
-          <div class="column-block">
-            <slot name="left"></slot>
-          </div>
-        </div>
-        <div class="column column--center">
-          <div class="column-block">
-            <slot>
-              <span>{{ title }}</span>
-            </slot>
-          </div>
-        </div>
-        <div class="column column--right">
-          <div class="column-block">
-            <slot name="right"></slot>
-          </div>
-        </div>
-      </div>
-      <div class="app-navbar__footer">
-        <slot name="footer"></slot>
-      </div>
-    </app-statusbar>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { useAttrs, computed } from 'vue'
-import { useRouter } from 'vue-router'
-import { useGlobalStore } from '@/stores'
-
-const emit = defineEmits<{ (event: string, ...args: unknown[]): void }>()
-
-const props = defineProps({
-  // 导航栏标题
-  title: String,
-  // 是否固定导航栏
-  fixed: Boolean,
-  // 是否显示返回按钮
-  showBackButton: {
-    type: Boolean,
-    default: true,
-  }
-})
-
-const router = useRouter();
-const attrs = useAttrs();
-const globalStore = useGlobalStore()
-
-const styles = computed(() => ({
-  position: props.fixed ? 'fixed' : 'static',
-  width: globalStore.clientWidth + 'px',
-}))
-
-// 返回按钮事件
-const goback = () => {
-  if (attrs.onBack) {
-    emit('back');
-  } else {
-    router.go(-1);
-  }
-}
-
-const onReady = (el: HTMLElement) => {
-  emit('ready', el);
-}
-</script>
-
-<style lang="less" scoped>
-@import './index.less';
-</style>

+ 0 - 6
src/packages/gstj/components/layouts/page/index.less

@@ -1,6 +0,0 @@
-.app-page {
-    width: 100%;
-    height: 100%;
-    overflow-y: auto;
-    background-color: #f6f6f6;
-}

+ 0 - 46
src/packages/gstj/components/layouts/page/index.vue

@@ -1,46 +0,0 @@
-<template>
-  <router-view class="app-page" v-slot="{ Component, route }">
-    <RouterTransition :transition-name="state.transitionName" @leave="onLeave" @after-enter="onAfterEnter">
-      <!-- 缓存组件,前进刷新,后退缓存 -->
-      <keep-alive :exclude="state.excludeViews">
-        <component :is="handleComponent(Component, route)" :key="getRouteKey(route)" />
-      </keep-alive>
-    </RouterTransition>
-  </router-view>
-</template>
-
-<script lang="ts" setup>
-import { RouteLocationNormalized, RouteRecordNormalized, RouteRecordName } from 'vue-router'
-import animateRouter from '../../../router/animateRouter'
-import RouterTransition from '../../../components/base/router-transition/index.vue'
-import http from '@/services/http'
-
-const { state } = animateRouter
-
-// 手动给组件添加 name 属性,处理缓存 exclude 无效的问题
-const handleComponent = (component: Record<'type', { name: RouteRecordName | undefined }>, route: RouteRecordNormalized) => {
-  if (component) {
-    component.type.name = route.name
-  }
-  return component
-}
-
-// key 的作用是当 $route.query 参数发生变化时会刷新页面
-// 不直接使用 $route.fullPath 的原因是每次都会刷新页面,导致嵌套路由缓存失效
-const getRouteKey = (route: RouteLocationNormalized) => {
-  const qs = Object.keys(route.query)
-  return qs.length ? route.fullPath : undefined
-}
-
-const onLeave = () => {
-  http.pending = true
-}
-
-const onAfterEnter = () => {
-  http.pending = false
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 19
src/packages/gstj/components/layouts/scroll-view/index.less

@@ -1,19 +0,0 @@
-.app-scroll-view {
-    height    : 100%;
-    overflow-y: auto;
-
-    &__header {
-        position: fixed;
-        top     : 0;
-        z-index : 1;
-
-        &:empty {
-            display: none;
-        }
-
-        &.after {
-            opacity: 0;
-            z-index: -1;
-        }
-    }
-}

+ 0 - 120
src/packages/gstj/components/layouts/scroll-view/index.vue

@@ -1,120 +0,0 @@
-<template>
-  <div ref="scrollRef" class="app-scroll-view">
-    <div ref="afterHeaderRef" class="app-scroll-view__header after">
-      <slot name="afterHeader"></slot>
-    </div>
-    <div ref="beforeHeaderRef" class="app-scroll-view__header before">
-      <slot name="beforeHeader"></slot>
-    </div>
-    <slot></slot>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { ref, onMounted, onActivated, onDeactivated, watch } from 'vue'
-
-const props = defineProps({
-  // 滚动元素名称(用于不同组件缓存滚动条位置)
-  scrollName: {
-    type: String,
-    default: 'default',
-  },
-  // 滚动条位置
-  scrollTop: {
-    type: Number,
-    default: 0,
-  },
-})
-
-const emit = defineEmits(['update:scrollTop', 'scroll'])
-const scrollRef = ref<HTMLDivElement>()
-const beforeHeaderRef = ref<HTMLDivElement>() // 前标题栏
-const afterHeaderRef = ref<HTMLDivElement>() // 后标题栏
-const scrollMap = new Map<string, number>()
-
-// 设置透明样式
-const setOpacity = (style: CSSStyleDeclaration, value: number) => {
-  if (value > 1) {
-    style.setProperty('opacity', '1')
-  } else if (value < 0) {
-    style.setProperty('opacity', '0')
-    style.setProperty('z-index', '-1')
-  } else {
-    style.setProperty('opacity', value.toString())
-    style.setProperty('z-index', '1')
-  }
-}
-
-// 监听滚动条位置
-const onScroll = (e: Event) => {
-  const el = e.target as HTMLDivElement
-  const beforeHeaderEl = beforeHeaderRef.value
-  const afterHeaderEl = afterHeaderRef.value
-  scrollMap.set(props.scrollName, el.scrollTop)
-
-  // 滚动隐藏标题栏
-  if (beforeHeaderEl) {
-    const { clientHeight, style } = beforeHeaderEl
-    const alpha = (clientHeight * 2 - el.scrollTop) / clientHeight
-    setOpacity(style, alpha)
-  }
-  // 滚动显示标题栏
-  if (afterHeaderEl) {
-    const { clientHeight, style } = afterHeaderEl
-    const alpha = (el.scrollTop - clientHeight) / clientHeight
-    setOpacity(style, alpha)
-  }
-
-  emit('update:scrollTop', el.scrollTop)
-  emit('scroll', el)
-}
-
-// 设置滚动条位置
-const setScrollTop = (callback?: (el: HTMLDivElement) => void) => {
-  const el = scrollRef.value
-  if (el) {
-    el.style.setProperty('opacity', '0')
-    el.scrollTop = scrollMap.get(props.scrollName) ?? 0
-
-    window.setTimeout(() => {
-      el.style.setProperty('opacity', '1')
-      callback && callback(el)
-    }, 0)
-  }
-}
-
-onMounted(() => {
-  window.setTimeout(() => {
-    const scrollEl = scrollRef.value
-    const beforeHeaderEl = beforeHeaderRef.value
-
-    if (scrollEl && beforeHeaderEl) {
-      scrollEl.style.setProperty('padding-top', beforeHeaderEl.clientHeight + 'px')
-    }
-  }, 0)
-
-  const addScrollListener = (el: HTMLDivElement) => {
-    el.addEventListener('scroll', onScroll) // 监听滚动条事件
-  }
-
-  // 组件挂载后调用
-  setScrollTop(addScrollListener)
-
-  // 缓存组件时调用
-  onActivated(() => {
-    setScrollTop(addScrollListener)
-  })
-
-  // 缓存组件被移除时调用
-  onDeactivated(() => {
-    const el = scrollRef.value
-    el?.removeEventListener('scroll', onScroll) // 移除滚动条事件
-  })
-})
-
-watch(() => props.scrollName, () => setScrollTop())
-</script>
-
-<style lang="less" scoped>
-@import './index.less';
-</style>

+ 0 - 25
src/packages/gstj/components/layouts/statusbar/index.vue

@@ -1,25 +0,0 @@
-<template>
-  <div ref="statusbarElement" class="app-statusbar">
-    <slot></slot>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { ref, onMounted, nextTick } from 'vue'
-import plus from '@/utils/h5plus'
-
-const emit = defineEmits(['ready']);
-
-const statusbarElement = ref<HTMLElement>();
-
-// 组件挂载完成
-onMounted(() => {
-  const el = statusbarElement.value;
-
-  plus.getStatusBarHeight((height) => {
-    el?.style.setProperty('padding-top', height + 'px');
-  })
-
-  nextTick(() => emit('ready', el));
-})
-</script>

+ 0 - 24
src/packages/gstj/components/layouts/view/index.less

@@ -1,24 +0,0 @@
-.app-view {
-    display: flex;
-    flex-direction: column;
-    height: 100%;
-    background-color: #f6f6f6;
-    -webkit-overflow-scrolling: touch;
-
-    &__loading {
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        height: 50%;
-    }
-
-    &__body {
-        flex: 1;
-        overflow-y: auto;
-
-        &.flex {
-            display: flex;
-            flex-direction: column;
-        }
-    }
-}

+ 0 - 38
src/packages/gstj/components/layouts/view/index.vue

@@ -1,38 +0,0 @@
-<template>
-    <div ref="viewRef" class="app-view">
-        <slot name="header"></slot>
-        <app-scroll-view :class="['app-view__body', flex && 'flex']">
-            <Loading class="app-view__loading" v-if="loading" />
-            <slot></slot>
-        </app-scroll-view>
-        <slot name="footer"></slot>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, onMounted } from 'vue'
-import { Loading } from 'vant'
-
-defineProps({
-    // 显示一个加载动画
-    loading: {
-        type: Boolean,
-        default: false
-    },
-    flex: {
-        type: Boolean,
-        default: false
-    },
-})
-
-const emit = defineEmits(['ready'])
-const viewRef = shallowRef()
-
-onMounted(() => {
-    emit('ready', viewRef.value)
-})
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 30
src/packages/gstj/components/modules/contact/index.vue

@@ -1,30 +0,0 @@
-<template>
-    <app-modal direction="right" height="100%" v-model:show="showModal">
-        <app-address :show-radio="true" @change="onChange" />
-    </app-modal>
-</template>
-
-<script lang="ts" setup>
-import { computed } from 'vue'
-import AppModal from '@/components/base/modal/index.vue'
-import AppAddress from '../../../views/mine/address/Index.vue'
-
-const props = defineProps({
-    show: {
-        type: Boolean,
-        default: false
-    }
-})
-
-const emit = defineEmits(['update:show', 'change'])
-
-const showModal = computed({
-    get: () => props.show,
-    set: (val) => emit('update:show', val)
-})
-
-const onChange = (item: Model.UserReceiveInfoRsp) => {
-    showModal.value = false
-    emit('change', item)
-}
-</script>

+ 0 - 158
src/packages/gstj/components/modules/delivery/index.vue

@@ -1,158 +0,0 @@
-<!-- 交收操作 -->
-<template>
-    <app-modal direction="right" height="100%" v-model:show="showModal" :refresh="refresh">
-        <app-view class="g-form">
-            <template #header>
-                <app-navbar title="交收" @back="closed" />
-            </template>
-            <Form ref="formRef" class="g-form__container" @submit="onSubmit">
-                <CellGroup title="持仓信息" inset v-if="$slots.header">
-                    <slot name="header"></slot>
-                </CellGroup>
-                <CellGroup title="交收信息" inset>
-                    <Field name="wrstandardname" label="点选仓单" placeholder="请选择" :rules="formRules.wrstandardname"
-                        v-model="checkedRow.wrstandardname" @click="showWarehouseReceipt = true" is-link readonly />
-                    <template v-if="checkedRow.deliverygoodsid">
-                        <Field label="持有人" v-model="checkedRow.username" readonly />
-                        <Field label="仓库" v-model="checkedRow.warehousename" readonly />
-                        <Field label="数量" v-model="checkedRow.avalidqty" readonly />
-                    </template>
-                </CellGroup>
-                <CellGroup inset>
-                    <Field name="DeliveryQty" type="digit" :rules="formRules.DeliveryQty" label="交收数量">
-                        <template #input>
-                            <Stepper v-model="formData.DeliveryQty" theme="round" button-size="22" :min="0" :max="maxQty"
-                                integer />
-                        </template>
-                    </Field>
-                    <Field label="升贴水">
-                        <template #input>
-                            {{ discount.toFixed(2) }}
-                        </template>
-                    </Field>
-                    <slot name="form" :discount="discount" :qty="formData.DeliveryQty ?? 0"></slot>
-                </CellGroup>
-            </Form>
-            <template #footer>
-                <Button block square type="danger" @click="formRef?.submit">提交</Button>
-            </template>
-        </app-view>
-        <component :is="WarehouseReceipt" v-model:show="showWarehouseReceipt" :goods-id="goodsId" @change="onChange" />
-    </app-modal>
-</template>
-
-<script lang="ts" setup>
-import { reactive, shallowRef, computed, defineAsyncComponent } from 'vue'
-import { v4 } from 'uuid'
-import { CellGroup, Button, FieldRule, Form, Field, Stepper, FormInstance } from 'vant'
-import { dialog, fullloading } from '@/utils/vant'
-import { ClientType } from '@/constants/client'
-import { deliveryOrder } from '@/services/api/trade'
-import { useAccountStore } from '@/stores'
-import moment from 'moment'
-import AppModal from '@/components/base/modal/index.vue'
-
-const props = defineProps({
-    goodsId: {
-        type: Number,
-        required: true,
-    },
-    total: {
-        type: Number,
-        required: true,
-    }
-})
-
-const WarehouseReceipt = defineAsyncComponent(() => import('./warehouse-receipt.vue'))
-
-const accountStore = useAccountStore()
-const showModal = shallowRef(true)
-const refresh = shallowRef(false) // 是否刷新父组件数据
-const formRef = shallowRef<FormInstance>()
-const checkedRow = shallowRef<Partial<Model.WrDeliveryAvalidHoldLBRsp>>({}) //选中的点选仓单
-const showWarehouseReceipt = shallowRef(false)
-
-const formData = reactive<Partial<Proto.DeliveryOrderReq>>({
-    ClientType: ClientType.Web,
-    AccountID: accountStore.currentAccountId,
-    XGoodsID: props.goodsId
-})
-
-// 可选最大交收数量
-const maxQty = computed(() => {
-    const avalidqty = checkedRow.value.avalidqty ?? 0
-    const enableqty = props.total
-    return avalidqty > enableqty ? enableqty : avalidqty
-})
-
-// 升贴水
-const discount = computed(() => (checkedRow.value.pricemove ?? 0) * (formData.DeliveryQty ?? 0))
-
-// 表单验证规则
-const formRules: { [key: string]: FieldRule[] } = {
-    wrstandardname: [{
-        message: '请选择点选仓单',
-        validator: () => {
-            return !!checkedRow.value.deliverygoodsid
-        }
-    }],
-    DeliveryQty: [{
-        message: '请输入交收数量',
-        validator: () => {
-            return !!formData.DeliveryQty
-        }
-    }],
-}
-
-// 选择现货仓单
-const onChange = (item: Model.WrDeliveryAvalidHoldLBRsp) => {
-    checkedRow.value = item
-    showWarehouseReceipt.value = false
-}
-
-const onSubmit = () => {
-    dialog({
-        message: '确认要交收吗?',
-        showCancelButton: true,
-    }).then(() => {
-        fullloading((hideLoading) => {
-            const item = checkedRow.value
-            formData.DeliveryGoodsID = item.deliverygoodsid
-            formData.XQty = formData.DeliveryQty
-            formData.DeliveryOrderDetail = {
-                AccountID: item.accountid, // 对手方账号
-                Qty: formData.DeliveryQty, // 点选数量
-                LadingBillID: item.ladingbillid,// 提单ID
-                SubNum: item.subnum, // 提单子单号
-                WRFactorTypeID: item.wrfactortypeid, // 仓单要素类型ID
-            }
-            formData.ClientSerialNo = v4()
-            formData.ClientOrderTime = moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
-
-            deliveryOrder({
-                data: formData
-            }).then(() => {
-                hideLoading('交收成功', 'success')
-                closed(true)
-            }).catch((err) => {
-                hideLoading(err, 'fail')
-            })
-        })
-    })
-}
-
-// 关闭弹窗
-const closed = (isRefresh = false) => {
-    if (showWarehouseReceipt.value) {
-        showWarehouseReceipt.value = false
-    } else {
-        refresh.value = isRefresh
-        showModal.value = false
-    }
-}
-
-// 暴露组件属性给父组件调用
-defineExpose({
-    closed,
-})
-</script>

+ 0 - 77
src/packages/gstj/components/modules/delivery/warehouse-receipt.vue

@@ -1,77 +0,0 @@
-<template>
-    <app-modal direction="right" height="100%">
-        <app-view class="g-form">
-            <template #header>
-                <app-navbar title="选择点选仓单" @back="closed" />
-            </template>
-            <RadioGroup class="g-form__container" v-model="checkedRow" v-if="dataList.length">
-                <CellGroup v-for="(item, index) in dataList" :key="index" @click="onChange(item)" inset>
-                    <Cell>
-                        <template #title>
-                            <Radio :name="item" checked-color="#ee0a24">
-                                <ul style="margin-left: .2rem;">
-                                    <li>
-                                        <span>持有人:</span>
-                                        <span>{{ item.username }}</span>
-                                    </li>
-                                    <li>
-                                        <span>商品:</span>
-                                        <span>{{ item.wrstandardname }}</span>
-                                    </li>
-                                    <li>
-                                        <span>仓库:</span>
-                                        <span>{{ item.warehousename }}</span>
-                                    </li>
-                                    <li>
-                                        <span>数量:</span>
-                                        <span>{{ item.avalidqty }}</span>
-                                    </li>
-                                    <li>
-                                        <span>升贴水:</span>
-                                        <span>{{ item.pricemove }}</span>
-                                    </li>
-                                </ul>
-                            </Radio>
-                        </template>
-                    </Cell>
-                </CellGroup>
-            </RadioGroup>
-            <Empty description="暂无数据" v-else />
-        </app-view>
-    </app-modal>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from 'vue'
-import { RadioGroup, Radio, Cell, CellGroup, Empty } from 'vant'
-import { useRequest } from '@/hooks/request'
-import { queryWrDeliveryAvalidHoldLB } from '@/services/api/transfer'
-import AppModal from '@/components/base/modal/index.vue'
-
-const props = defineProps({
-    goodsId: {
-        type: Number,
-        required: true,
-    },
-})
-
-const emit = defineEmits(['update:show', 'change'])
-const checkedRow = shallowRef<Model.WrDeliveryAvalidHoldLBRsp>()
-
-const { dataList } = useRequest(queryWrDeliveryAvalidHoldLB, {
-    params: {
-        goodsid: props.goodsId,
-    },
-})
-
-// 选择仓单
-const onChange = (item: Model.WrDeliveryAvalidHoldLBRsp) => {
-    checkedRow.value = item
-    emit('change', item)
-}
-
-// 关闭弹窗
-const closed = () => {
-    emit('update:show', false)
-}
-</script>

+ 0 - 3
src/packages/gstj/components/modules/echarts-line/index.less

@@ -1,3 +0,0 @@
-.app-echats-line {
-    height: 4rem;
-}

+ 0 - 55
src/packages/gstj/components/modules/echarts-line/index.vue

@@ -1,55 +0,0 @@
-<template>
-    <div class="app-echats-line">
-        <template v-if="loading">
-            <div class="app-echats-line__tip">正在加载...</div>
-        </template>
-        <template v-else-if="isEmpty">
-            <div class="app-echats-line__tip">暂无数据</div>
-        </template>
-        <template v-else>
-            <!-- <ul class="legend">
-                <li class="legend-item">收盘: {{ selectedItem.price }}</li>
-            </ul> -->
-            <app-echarts :option="options.line" v-model:dataIndex="dataIndex" @ready="initOptions" />
-        </template>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, PropType, watch } from 'vue'
-import { useLineChart } from '@/hooks/echarts/line'
-import { EchartsDataset } from '@/hooks/echarts/line/types'
-import AppEcharts from '@/components/base/echarts/index.vue'
-
-const props = defineProps({
-    loading: {
-        type: Boolean,
-        default: false
-    },
-    dataList: {
-        type: Object as PropType<EchartsDataset['line']['source']>,
-        required: true
-    },
-})
-
-const { options, dataIndex, initData, initOptions } = useLineChart()
-const isEmpty = shallowRef(false)
-
-watch(() => props.loading, (status) => {
-    if (status) {
-        isEmpty.value = false
-    } else {
-        if (props.dataList.price.length) {
-            initData(props.dataList)
-        } else {
-            isEmpty.value = true
-        }
-    }
-}, {
-    immediate: true
-})
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 8
src/packages/gstj/components/modules/pdf/index.vue

@@ -1,8 +0,0 @@
-<template>
-    <div class="app-pdf">
-
-    </div>
-</template>
-
-<script lang="ts" setup>
-</script>

+ 0 - 19
src/packages/gstj/components/modules/performance/index.less

@@ -1,19 +0,0 @@
-.app-performance {
-    &-item {
-        height: auto;
-        padding: 10px;
-        line-height: 1;
-
-        &:not(:first-child) {
-            border-top: 1px solid #576675;
-        }
-
-        &__title {
-            margin-bottom: 8px;
-        }
-
-        &.selected &__title {
-            font-weight: bold;
-        }
-    }
-}

+ 0 - 52
src/packages/gstj/components/modules/performance/index.vue

@@ -1,52 +0,0 @@
-<template>
-    <Field type="number" :label="label" @click="show = true" is-link readonly>
-        <template #input>
-            <input :placeholder="placeholder" :value="templateName" />
-            <PerformanceList v-model:show="show" :market-id="marketId" :selected-id="modelValue" @change="onChange" />
-        </template>
-    </Field>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from 'vue'
-import { Field } from 'vant'
-import PerformanceList from './list/index.vue'
-
-defineProps({
-    modelValue: Number,
-    marketId: Number,
-    label: {
-        type: String,
-        default: '履约模板'
-    },
-    placeholder: {
-        type: String,
-        default: '请选择'
-    }
-})
-
-const emit = defineEmits(['update:modelValue', 'change'])
-const show = shallowRef(false)
-const templateName = shallowRef<string>()
-
-const onChange = (item?: Model.PermancePlanTmpRsp) => {
-    templateName.value = item?.templatename
-    emit('update:modelValue', item?.autoid)
-    emit('change', item)
-}
-
-// 暴露组件属性给父组件调用
-defineExpose({
-    closed: () => {
-        if (show.value) {
-            show.value = false
-            return false
-        }
-        return true
-    },
-})
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 46
src/packages/gstj/components/modules/performance/list/index.less

@@ -1,46 +0,0 @@
-.app-performance {
-    &__step {
-        display: flex;
-        padding-top: .1rem;
-        overflow-x: auto;
-
-        li {
-            --van-tag-primary-color: #3a73ad;
-
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            font-size: .24rem;
-
-            &:not(:first-child) {
-                margin-left: .1rem;
-            }
-
-            span {
-                color: var(--van-tag-primary-color);
-                white-space: nowrap;
-            }
-        }
-    }
-
-    .van-radio {
-        &__label {
-            overflow: hidden;
-            padding: .1rem;
-        }
-    }
-
-    .van-cell {
-        &-group {
-            margin-top: .2rem;
-        }
-
-        &__title {
-            overflow: hidden;
-        }
-
-        &__label {
-            overflow: hidden;
-        }
-    }
-}

+ 0 - 75
src/packages/gstj/components/modules/performance/list/index.vue

@@ -1,75 +0,0 @@
-<template>
-    <app-modal direction="right" height="100%" v-model:show="showModal">
-        <app-view class="app-performance">
-            <template #header>
-                <app-navbar title="履约模板" @back="showModal = false" />
-            </template>
-            <RadioGroup v-model="checkedRow" @change="onChange">
-                <CellGroup v-for="(item, index) in dataList" :key="index" inset>
-                    <Cell>
-                        <template #title>
-                            <Radio :name="item">
-                                <span>{{ item.templatename }}</span>
-                                <ul class="app-performance__step">
-                                    <li v-for="(step, i) in item.LstStep" :key="i">
-                                        <Tag type="primary " size="large" plain>{{ step.stepinfo }}
-                                        </Tag>
-                                        <span>{{ step.stepdate }}</span>
-                                    </li>
-                                </ul>
-                            </Radio>
-                        </template>
-                    </Cell>
-                </CellGroup>
-            </RadioGroup>
-        </app-view>
-    </app-modal>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, computed } from 'vue'
-import { RadioGroup, Radio, CellGroup, Cell, Tag } from 'vant'
-import { useRequest } from '@/hooks/request'
-import { queryPermancePlanTmp } from '@/services/api/performance'
-import AppModal from '@/components/base/modal/index.vue'
-
-const props = defineProps({
-    show: {
-        type: Boolean,
-        default: false
-    },
-    selectedId: Number,
-    marketId: Number,
-})
-
-const emit = defineEmits(['update:show', 'change'])
-const checkedRow = shallowRef<Model.PermancePlanTmpRsp>()
-
-const showModal = computed({
-    get: () => props.show,
-    set: (val) => emit('update:show', val)
-})
-
-const { dataList } = useRequest(queryPermancePlanTmp, {
-    params: {
-        marketid: props.marketId
-    },
-    onFinally: () => {
-        const item = dataList.value.find((e) => e.autoid === props.selectedId)
-        if (item) {
-            checkedRow.value = item
-        } else {
-            emit('change')
-        }
-    }
-})
-
-const onChange = () => {
-    emit('change', checkedRow.value)
-    showModal.value = false
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 17
src/packages/gstj/components/modules/quote/chart/index.less

@@ -1,17 +0,0 @@
-.app-quote-chart {
-    background-color: #fff;
-
-    &__header {
-        display: flex;
-        align-items: center;
-        background-color: #f2f2f2;
-
-        .van-tabs {
-            flex: 1;
-
-            &__nav {
-                background-color: transparent;
-            }
-        }
-    }
-}

+ 0 - 110
src/packages/gstj/components/modules/quote/chart/index.vue

@@ -1,110 +0,0 @@
-<template>
-    <div class="app-quote-chart">
-        <div class="app-quote-chart__header">
-            <Tabs v-model:active="tabIndex" :before-change="onTabChange">
-                <Tab title="分时" />
-                <Tab>
-                    <template #title>
-                        <Popover :actions="actions" @select="onPopoverSelect">
-                            <template #reference>{{ selectedText || '分钟' }}</template>
-                        </Popover>
-                    </template>
-                </Tab>
-                <Tab title="日线" />
-                <Tab title="周线" />
-                <Tab title="月线" />
-            </Tabs>
-            <Icon name="setting-o" style="padding: 0 .32rem;" v-if="false" />
-        </div>
-        <TimeLine v-bind="{ goodsCode }" v-if="tabIndex === 0" />
-        <KLine v-bind="{ goodsCode, cycleType }" v-else />
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from 'vue'
-import { Tab, Tabs, Popover, Icon, PopoverAction } from 'vant'
-import { ChartCycleType } from '@/constants/chart'
-import TimeLine from './timeline/index.vue'
-import KLine from './kline/index.vue'
-
-defineProps({
-    goodsCode: {
-        type: String,
-        required: true
-    }
-})
-
-const tabIndex = shallowRef(0) // 当前选中的标签
-const selectedText = shallowRef('') // 当前选中的分钟线
-const cycleType = shallowRef(ChartCycleType.Minutes) // 图表周期类型
-
-const actions = [
-    { text: '1分钟' },
-    { text: '5分钟', },
-    { text: '30分钟', },
-    { text: '60分钟', },
-    { text: '4小时', }
-]
-
-// 切换图表
-const onTabChange = (index: number) => {
-    switch (index) {
-        case 1: {
-            return false
-        }
-        case 2: {
-            cycleType.value = ChartCycleType.Day
-            return true
-        }
-        case 3: {
-            cycleType.value = ChartCycleType.Week
-            return true
-        }
-        case 4: {
-            cycleType.value = ChartCycleType.Month
-            return true
-        }
-        default: {
-            return true
-        }
-    }
-}
-
-// 切换分钟
-const onPopoverSelect = (action: PopoverAction) => {
-    tabIndex.value = 1
-    selectedText.value = action.text
-
-    switch (action.text) {
-        case '1分钟': {
-            cycleType.value = ChartCycleType.Minutes
-            break
-        }
-        case '5分钟': {
-            cycleType.value = ChartCycleType.Minutes5
-            break
-        }
-        case '30分钟': {
-            cycleType.value = ChartCycleType.Minutes30
-            break
-        }
-        case '60分钟': {
-            cycleType.value = ChartCycleType.Minutes60
-            break
-        }
-        case '2小时': {
-            cycleType.value = ChartCycleType.Hours2
-            break
-        }
-        case '4小时': {
-            cycleType.value = ChartCycleType.Hours4
-            break
-        }
-    }
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 45
src/packages/gstj/components/modules/quote/chart/kline/index.less

@@ -1,45 +0,0 @@
-.app-echats-kline {
-    display: flex;
-    flex-direction: column;
-    height: 8rem;
-
-    &__tip {
-        margin: auto;
-    }
-
-    &__container {
-        flex: 1;
-        display: flex;
-        flex-direction: column;
-
-        .app-echarts {
-            flex: 1;
-        }
-
-        .legend {
-            display: flex;
-            color: #7a8a94;
-            font-size: 12px;
-            padding: 4px 4%;
-            margin: 0;
-
-            &-item {
-                &:not(:first-child) {
-                    margin-left: 10px;
-                }
-            }
-        }
-    }
-
-    .app-tabs {
-        height: 3rem;
-
-        .tabs {
-            padding: .1rem;
-
-            &-item {
-                font-size: .24rem;
-            }
-        }
-    }
-}

+ 0 - 114
src/packages/gstj/components/modules/quote/chart/kline/index.vue

@@ -1,114 +0,0 @@
-<template>
-    <div class="app-echats-kline">
-        <div class="app-echats-kline__tip" v-if="loading">正在加载...</div>
-        <div class="app-echats-kline__tip" v-else-if="isEmpty">暂无数据</div>
-        <template v-else>
-            <div class="app-echats-kline__container">
-                <ul class="legend">
-                    <!-- <li class="legend-item">开: {{ selectedItem.open }}</li>
-                    <li class="legend-item">收: {{ selectedItem.close }}</li>
-                    <li class="legend-item">高: {{ selectedItem.highest }}</li>
-                    <li class="legend-item">低: {{ selectedItem.lowest }}</li> -->
-                    <li class="legend-item">MA5: {{ selectedItem.ma5 }}</li>
-                    <li class="legend-item">MA10: {{ selectedItem.ma10 }}</li>
-                    <li class="legend-item">MA15: {{ selectedItem.ma15 }}</li>
-                </ul>
-                <app-echarts :option="options.candlestick" v-model:dataIndex="dataIndex" @ready="mainReady" />
-            </div>
-            <app-tabs direction="bottom" :data-list="chartSeriesTypeList" @change="tabChange" v-if="showIndicator">
-                <!-- MACD -->
-                <div class="app-echats-kline__container" v-if="activeSeriesType === ChartSeriesType.MACD">
-                    <ul class="legend">
-                        <li class="legend-item">MACD: {{ selectedItem.macd }}</li>
-                        <li class="legend-item">DIF: {{ selectedItem.dif }}</li>
-                        <li class="legend-item">DEA: {{ selectedItem.dea }}</li>
-                    </ul>
-                    <app-echarts :option="options.macd" v-model:dataIndex="dataIndex" @ready="indicatorReady" />
-                </div>
-                <!-- VOL -->
-                <div class="app-echats-kline__container" v-if="activeSeriesType === ChartSeriesType.VOL">
-                    <ul class="legend">
-                        <li class="legend-item">VOL: {{ selectedItem.vol }}</li>
-                    </ul>
-                    <app-echarts :option="options.vol" v-model:dataIndex="dataIndex" @ready="indicatorReady" />
-                </div>
-                <!-- KDJ -->
-                <div class="app-echats-kline__container" v-if="activeSeriesType === ChartSeriesType.KDJ">
-                    <ul class="legend">
-                        <li class="legend-item">K: {{ selectedItem.k }}</li>
-                        <li class="legend-item">D: {{ selectedItem.d }}</li>
-                        <li class="legend-item">J: {{ selectedItem.j }}</li>
-                    </ul>
-                    <app-echarts :option="options.kdj" v-model:dataIndex="dataIndex" @ready="indicatorReady" />
-                </div>
-                <!-- CCI -->
-                <div class="app-echats-kline__container" v-if="activeSeriesType === ChartSeriesType.CCI">
-                    <ul class="legend">
-                        <li class="legend-item">CCI: {{ selectedItem.cci }}</li>
-                    </ul>
-                    <app-echarts :option="options.cci" v-model:dataIndex="dataIndex" @ready="indicatorReady" />
-                </div>
-            </app-tabs>
-        </template>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { PropType, watch, shallowRef } from 'vue'
-import { echarts } from '@/components/base/echarts/core'
-import { ChartCycleType, ChartSeriesType, getChartSeriesTypeList } from '@/constants/chart'
-import { useCandlestickChart } from '@/hooks/echarts/candlestick'
-import AppEcharts from '@/components/base/echarts/index.vue'
-import AppTabs from '@/components/base/tabs/index.vue'
-
-const props = defineProps({
-    goodsCode: {
-        type: String,
-        default: '',
-    },
-    // 周期类型
-    cycleType: {
-        type: Number as PropType<ChartCycleType>,
-        default: ChartCycleType.Minutes,
-    },
-    // 是否显示指标
-    showIndicator: {
-        type: Boolean,
-        default: true,
-    },
-})
-
-const { loading, dataIndex, isEmpty, options, selectedItem, initData, initOptions } = useCandlestickChart(props.goodsCode);
-const activeSeriesType = shallowRef(ChartSeriesType.MACD); // 当前选中的指标
-const chartGroup = new Map<string, echarts.ECharts>(); // 图表联动实例组
-const chartSeriesTypeList = getChartSeriesTypeList();
-
-// 指标切换
-const tabChange = (index: number) => {
-    activeSeriesType.value = chartSeriesTypeList[index].value;
-    setTimeout(() => {
-        initOptions();
-    }, 0);
-}
-
-const mainReady = (chart: echarts.ECharts) => {
-    chartGroup.set('main', chart);
-    initOptions();
-}
-
-const indicatorReady = (chart: echarts.ECharts) => {
-    chartGroup.set('indicator', chart);
-    echarts.connect([...chartGroup.values()]); // 图表联动
-}
-
-// 监听周期选择变化
-watch(() => props.cycleType, (val) => {
-    initData(val);
-}, {
-    immediate: true
-})
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 33
src/packages/gstj/components/modules/quote/chart/timeline/index.less

@@ -1,33 +0,0 @@
-.app-echats-timeline {
-    display: flex;
-    flex-direction: column;
-    height: 260px;
-
-    &__tip {
-        margin: auto;
-    }
-
-    &__container {
-        flex: 1;
-        display: flex;
-        flex-direction: column;
-
-        .app-echarts {
-            flex: 1;
-        }
-
-        .legend {
-            display: flex;
-            color: #7a8a94;
-            font-size: 12px;
-            padding: 4px 4%;
-            margin: 0;
-
-            &-item {
-                &:not(:first-child) {
-                    margin-left: 10px;
-                }
-            }
-        }
-    }
-}

+ 0 - 36
src/packages/gstj/components/modules/quote/chart/timeline/index.vue

@@ -1,36 +0,0 @@
-<template>
-    <div class="app-echats-timeline">
-        <template v-if="loading">
-            <div class="app-echats-timeline__tip">正在加载...</div>
-        </template>
-        <template v-else-if="isEmpty">
-            <div class="app-echats-timeline__tip">暂无数据</div>
-        </template>
-        <template v-else>
-            <div class="app-echats-timeline__container">
-                <ul class="legend" v-if="false">
-                    <li class="legend-item">MA5: {{ selectedItem.ma5 }}</li>
-                </ul>
-                <app-echarts :option="options.timeline" v-model:dataIndex="dataIndex" @ready="initOptions" />
-            </div>
-        </template>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { useTimelineChart } from '@/hooks/echarts/timeline'
-import AppEcharts from '@/components/base/echarts/index.vue'
-
-const props = defineProps({
-    goodsCode: {
-        type: String,
-        default: '',
-    },
-})
-
-const { loading, dataIndex, isEmpty, options, selectedItem, initOptions } = useTimelineChart(props.goodsCode)
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 42
src/packages/gstj/components/modules/quote/forex/index.less

@@ -1,42 +0,0 @@
-.app-quote-forex {
-    display: flex;
-    background-color: #fff;
-    margin-top: .2rem;
-
-    dl {
-        flex: 1;
-        padding: .24rem;
-
-        dt {
-            display: flex;
-            justify-content: space-between;
-            padding-bottom: .24rem;
-
-            span {
-                &:last-child {
-                    font-size: .24rem;
-                    color: #999;
-                }
-            }
-        }
-
-        dd {
-            display: flex;
-            font-size: .24rem;
-            text-align: center;
-            padding: .1rem 0;
-
-            span {
-                flex: 1;
-
-                &:first-child {
-                    text-align: left;
-                }
-
-                &:last-child {
-                    text-align: right;
-                }
-            }
-        }
-    }
-}

+ 0 - 176
src/packages/gstj/components/modules/quote/forex/index.vue

@@ -1,176 +0,0 @@
-<template>
-    <div class="app-quote-forex">
-        <dl>
-            <dt>
-                <span>卖挂牌</span>
-                <span @click="onMoreClick(BuyOrSell.Sell)" v-if="showMore">更多
-                    <Icon name="arrow" />
-                </span>
-            </dt>
-            <template v-for="(item, index) in sellList" :key="index">
-                <dd :class="active === 'sell_' + index ? 'is-active' : ''" @click="onPriceClick(BuyOrSell.Sell, index)">
-                    <span>{{ item.label }}</span>
-                    <span :class="item.color">{{ handleNumberValue(item.price.toFixed(quote?.decimalplace)) }}</span>
-                    <span>{{ handleNumberValue(item.qty) }}</span>
-                </dd>
-            </template>
-        </dl>
-        <dl>
-            <dt>
-                <span>买挂牌</span>
-                <span @click="onMoreClick(BuyOrSell.Buy)" v-if="showMore">更多
-                    <Icon name="arrow" />
-                </span>
-            </dt>
-            <template v-for="(item, index) in buyList" :key="index">
-                <dd :class="active === 'buy_' + index ? 'is-active' : ''" @click="onPriceClick(BuyOrSell.Buy, index)">
-                    <span>{{ item.label }}</span>
-                    <span :class="item.color">{{ handleNumberValue(item.price.toFixed(quote?.decimalplace)) }}</span>
-                    <span>{{ handleNumberValue(item.qty) }}</span>
-                </dd>
-            </template>
-        </dl>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, computed, useAttrs } from 'vue'
-import { Icon } from 'vant'
-import { handleNumberValue } from '@/filters'
-import { BuyOrSell } from '@/constants/order'
-import { useFuturesStore } from '@/stores'
-
-const props = defineProps({
-    goodsCode: {
-        type: String,
-        required: true
-    },
-    showMore: {
-        type: Boolean,
-        default: true
-    }
-})
-
-const emit = defineEmits<{ (event: string, ...args: unknown[]): void }>()
-const attrs = useAttrs()
-const futuresStore = useFuturesStore()
-const quote = computed(() => futuresStore.getGoodsQuote(props.goodsCode).value)
-const active = shallowRef('')
-
-const buyList = computed(() => {
-    const item = quote.value
-    if (item) {
-        const result = [
-            {
-                label: '买一',
-                price: item.bid,
-                qty: item.bidvolume,
-                color: item.bidColor,
-            },
-            {
-                label: '买二',
-                price: item.bid2,
-                qty: item.bidvolume2,
-                color: item.bid2Color,
-            },
-            {
-                label: '买三',
-                price: item.bid3,
-                qty: item.bidvolume3,
-                color: item.bid3Color,
-            },
-            {
-                label: '买四',
-                price: item.bid4,
-                qty: item.bidvolume4,
-                color: item.bid4Color,
-            },
-            {
-                label: '买五',
-                price: item.bid5,
-                qty: item.bidvolume5,
-                color: item.bid5Color,
-            }
-        ]
-        return result.slice(0, item.quotegear || 1)
-    }
-    return []
-})
-
-const sellList = computed(() => {
-    const item = quote.value
-    if (item) {
-        const result = [
-            {
-                label: '卖一',
-                price: item.ask,
-                qty: item.askvolume,
-                color: item.askColor,
-            },
-            {
-                label: '卖二',
-                price: item.ask2,
-                qty: item.askvolume2,
-                color: item.ask2Color,
-            },
-            {
-                label: '卖三',
-                price: item.ask3,
-                qty: item.askvolume3,
-                color: item.ask3Color,
-            },
-            {
-                label: '卖四',
-                price: item.ask4,
-                qty: item.askvolume4,
-                color: item.ask4Color,
-            },
-            {
-                label: '卖五',
-                price: item.ask5,
-                qty: item.askvolume5,
-                color: item.ask5Color,
-            }
-        ]
-        return result.slice(0, item.quotegear || 1)
-    }
-    return []
-})
-
-const onPriceClick = (buyorsell: BuyOrSell, index: number) => {
-    if (attrs.onPriceClick) {
-        switch (buyorsell) {
-            case BuyOrSell.Buy: {
-                onBuyClick(index)
-                break
-            }
-            case BuyOrSell.Sell: {
-                onSellClick(index)
-                break
-            }
-        }
-    }
-}
-
-const onBuyClick = (index: number) => {
-    const { bid, presettle } = quote.value ?? {}
-    const item = buyList.value[index]
-    active.value = 'buy_' + index
-    emit('priceClick', BuyOrSell.Buy, item.price || bid || presettle)
-}
-
-const onSellClick = (index: number) => {
-    const { ask, presettle } = quote.value ?? {}
-    const item = sellList.value[index]
-    active.value = 'sell_' + index
-    emit('priceClick', BuyOrSell.Sell, item.price || ask || presettle)
-}
-
-const onMoreClick = (buyorsell: BuyOrSell) => {
-    emit('moreClick', buyorsell)
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 23
src/packages/gstj/components/modules/quote/index.vue

@@ -1,23 +0,0 @@
-<template>
-    <div class="app-quote">
-        <Price v-bind="{ goodsCode }" />
-        <Chart v-bind="{ goodsCode }" />
-        <Forex v-bind="{ goodsCode }" v-if="showForex" />
-        <Tik v-bind="{ goodsCode }" />
-    </div>
-</template>
-
-<script lang="ts" setup>
-import Price from './price/index.vue'
-import Chart from './chart/index.vue'
-import Forex from './forex/index.vue'
-import Tik from './tik/index.vue'
-
-defineProps({
-    goodsCode: {
-        type: String,
-        required: true
-    },
-    showForex: Boolean,
-})
-</script>

+ 0 - 90
src/packages/gstj/components/modules/quote/price/index.less

@@ -1,90 +0,0 @@
-.app-quote-price {
-    color: #333;
-    background-color: #fff;
-    padding: .2rem 0;
-
-    .van-divider {
-        margin: 0;
-    }
-
-    &__main {
-        display: flex;
-        align-items: center;
-        text-align: center;
-
-        .block {
-            &-left {
-                width: 3rem;
-
-                .top-content {
-                    font-size: .56rem;
-                    margin-bottom: .1rem;
-                }
-
-                .bottom-content {
-                    font-size: .32rem;
-
-                    span {
-                        +span {
-                            margin-left: .2rem;
-                        }
-
-                        &.g-price-up {
-                            &::before {
-                                content: '+';
-                            }
-                        }
-                    }
-                }
-            }
-
-            &-right {
-                flex: 1;
-
-                ul {
-                    display: flex;
-                    flex-wrap: wrap;
-
-                    li {
-                        display: flex;
-                        flex-direction: column;
-                        width: calc(~'100% / 3');
-                        margin-bottom: .2rem;
-
-                        span {
-                            &:first-child {
-                                color: #888;
-                                font-size: .24rem;
-                                margin-bottom: .1rem;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    &__more {
-        ul {
-            display: flex;
-            flex-wrap: wrap;
-            width: 100%;
-            background-color: #fff;
-
-            li {
-                display: flex;
-                justify-content: space-between;
-                align-items: center;
-                width: 50%;
-                padding: .1rem .24rem;
-
-                span {
-                    &:first-child {
-                        font-size: .24rem;
-                        color: #888;
-                    }
-                }
-            }
-        }
-    }
-}

+ 0 - 108
src/packages/gstj/components/modules/quote/price/index.vue

@@ -1,108 +0,0 @@
-<template>
-    <div class="app-quote-price">
-        <div class="app-quote-price__main" v-if="quote">
-            <div class="block-left">
-                <div class="top-content">
-                    <span :class="quote.lastColor">{{ handleNumberValue(quote.last.toFixed(quote.decimalplace)) }}</span>
-                </div>
-                <div class="bottom-content">
-                    <span :class="quote.lastColor">{{ quote.rise.toFixed(quote.decimalplace) }}</span>
-                    <span :class="quote.lastColor">{{ parsePercent(quote.change) }}</span>
-                </div>
-            </div>
-            <div class="block-right">
-                <ul>
-                    <li>
-                        <span>开盘</span>
-                        <span :class="quote.openedColor">
-                            {{ handleNumberValue(quote.opened.toFixed(quote.decimalplace)) }}
-                        </span>
-                    </li>
-                    <li>
-                        <span>最高</span>
-                        <span :class="quote.highestColor">
-                            {{ handleNumberValue(quote.highest.toFixed(quote.decimalplace)) }}
-                        </span>
-                    </li>
-                    <li>
-                        <span>涨停</span>
-                        <span class="g-price-up">{{ handleNumberValue(quote.limitup.toFixed(quote.decimalplace)) }}</span>
-                    </li>
-                    <li>
-                        <span>昨结</span>
-                        <span>{{ handleNumberValue(quote.presettle.toFixed(quote.decimalplace)) }}</span>
-                    </li>
-                    <li>
-                        <span>最低</span>
-                        <span :class="quote.lowestColor">{{ handleNumberValue(quote.lowest.toFixed(quote.decimalplace))
-                        }}</span>
-                    </li>
-                    <li>
-                        <span>跌停</span>
-                        <span class="g-price-down">{{ handleNumberValue(quote.limitdown.toFixed(quote.decimalplace))
-                        }}</span>
-                    </li>
-                </ul>
-            </div>
-        </div>
-        <Divider @click="showMore = !showMore">
-            <Icon :name="showMore ? 'arrow-up' : 'arrow-down'" />
-        </Divider>
-        <div class="app-quote-price__more" v-if="quote">
-            <ul v-show="showMore">
-                <li>
-                    <span>买量</span>
-                    <span>{{ handleNumberValue(quote.bidvolume) }}</span>
-                </li>
-                <li>
-                    <span>卖量</span>
-                    <span>{{ handleNumberValue(quote.askvolume) }}</span>
-                </li>
-                <li>
-                    <span>买价</span>
-                    <span :class="quote.bidColor">{{ handleNumberValue(quote.bid.toFixed(quote.decimalplace)) }}</span>
-                </li>
-                <li>
-                    <span>卖价</span>
-                    <span :class="quote.askColor">{{ handleNumberValue(quote.ask.toFixed(quote.decimalplace)) }}</span>
-                </li>
-                <li>
-                    <span>均价</span>
-                    <span :class="quote.averagepriceColor">{{
-                        handleNumberValue(quote.averageprice.toFixed(quote.decimalplace)) }}</span>
-                </li>
-                <li>
-                    <span>振幅</span>
-                    <span>{{ parsePercent(quote.amplitude) }}</span>
-                </li>
-            </ul>
-        </div>
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, onMounted, onUnmounted } from 'vue'
-import { Icon, Divider } from 'vant'
-import { parsePercent, handleNumberValue } from '@/filters'
-import { useFuturesStore } from '@/stores'
-import quoteSocket from '@/services/websocket/quote'
-
-const props = defineProps({
-    goodsCode: {
-        type: String,
-        required: true
-    }
-})
-
-const futuresStore = useFuturesStore()
-const subscribe = quoteSocket.createSubscribe()
-const quote = futuresStore.getGoodsQuote(props.goodsCode)
-const showMore = shallowRef(false)
-
-onMounted(() => subscribe.start(props.goodsCode))
-onUnmounted(() => subscribe.stop())
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 3
src/packages/gstj/components/modules/quote/tik/index.less

@@ -1,3 +0,0 @@
-.app-quote-tik {
-    margin-top: .2rem;
-}

+ 0 - 94
src/packages/gstj/components/modules/quote/tik/index.vue

@@ -1,94 +0,0 @@
-<template>
-    <AppList class="app-quote-tik" :columns="columns" :data-list="dataList">
-        <template #TS="{ value }">
-            {{ formatDate(value, 'HH:mm:ss') }}
-        </template>
-        <template #PE="{ value }">
-            <span>{{ handleNumberValue(value) }}</span>
-        </template>
-        <template #Vol="{ value }">
-            <span>{{ handleNumberValue(value) }}</span>
-        </template>
-    </AppList>
-</template>
-
-<script lang="ts" setup>
-import { ref, watch } from 'vue'
-import { formatDate, handleNumberValue } from '@/filters'
-import { useRequest } from '@/hooks/request'
-import { queryHistoryTikDatas, queryMarketRun } from '@/services/api/market'
-import { useFuturesStore } from '@/stores'
-import AppList from '../../../base/list/index.vue'
-
-const props = defineProps({
-    goodsCode: {
-        type: String,
-        required: true
-    },
-})
-
-const futuresStore = useFuturesStore()
-const quote = futuresStore.getGoodsQuote(props.goodsCode)
-const dataList = ref<Model.HistoryTikDatasRsp[]>([])
-
-const columns: Model.TableColumn[] = [
-    { prop: 'TS', label: '时间' },
-    { prop: 'PE', label: '最新价' },
-    { prop: 'Vol', label: '现量' },
-]
-
-const { run: getHistoryTikDatas } = useRequest(queryHistoryTikDatas, {
-    manual: true,
-    params: {
-        goodsCode: props.goodsCode,
-        count: 10
-    },
-    onSuccess: (res) => {
-        dataList.value = res.data
-    }
-})
-
-useRequest(queryMarketRun, {
-    params: {
-        marketID: quote.value?.marketid
-    },
-    onSuccess: (res) => {
-        const market = res.data[0]
-        if (market) {
-            getHistoryTikDatas({
-                startTime: formatDate(market.startTime),
-                endTime: formatDate(market.endTime),
-            })
-        }
-    }
-})
-
-watch(() => quote.value, (q) => {
-    if (q?.last && q.lastvolume) {
-        const list = dataList.value
-        if (list.length > 9) {
-            // 移除列表最后一条记录
-            list.pop()
-        }
-        // 向列表开头添加新纪录
-        list.unshift({
-            AV: 0,
-            Ask: 0,
-            BV: 0,
-            Bid: 0,
-            HI: 0,
-            HV: 0,
-            PE: q.last,
-            TDR: 0,
-            TK: 0,
-            TS: q.lasttime,
-            TT: 0,
-            Vol: q.lastvolume,
-        })
-    }
-})
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 30
src/packages/gstj/components/modules/receipt/index.vue

@@ -1,30 +0,0 @@
-<template>
-    <app-modal direction="right" height="100%" v-model:show="showModal">
-        <app-invoice :show-radio="true" @change="onChange" />
-    </app-modal>
-</template>
-
-<script lang="ts" setup>
-import { computed } from 'vue'
-import AppModal from '@/components/base/modal/index.vue'
-import AppInvoice from '../../../views/mine/invoice/Index.vue'
-
-const props = defineProps({
-    show: {
-        type: Boolean,
-        default: false
-    }
-})
-
-const emit = defineEmits(['update:show', 'change'])
-
-const showModal = computed({
-    get: () => props.show,
-    set: (val) => emit('update:show', val)
-})
-
-const onChange = (item: Model.WrUserReceiptInfoRsp) => {
-    showModal.value = false
-    emit('change', item)
-}
-</script>

+ 0 - 20
src/packages/gstj/components/modules/register-code/index.less

@@ -1,20 +0,0 @@
-.app-register-code {
-    &__wrapper {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-        min-height: 4rem;
-        padding: .32rem;
-    }
-
-    &__qrcode {
-        max-width: 4.8rem;
-        max-height: 4.8rem;
-    }
-
-    &__content {
-        font-size: .32rem;
-        font-weight: bold;
-    }
-}

+ 0 - 63
src/packages/gstj/components/modules/register-code/index.vue

@@ -1,63 +0,0 @@
-<template>
-    <Dialog class="app-register-code" teleport="body" v-model:show="showDialog" :show-confirm-button="showConfirmButton"
-        confirm-button-text="保存" show-cancel-button @confirm="onConfirm">
-        <div class="app-register-code__wrapper">
-            <div class="app-register-code__canvas">
-                <app-qrcode class="app-register-code__qrcode" v-model="base64Data" :text="qrContent"
-                    :logo="require('../../../assets/logo.svg')" />
-            </div>
-            <div class="app-register-code__content" :data-clipboard-text="props.text" v-copy="onCopy">{{ props.text }}</div>
-        </div>
-    </Dialog>
-</template>
-
-<script lang="ts" setup>
-import { computed, shallowRef } from 'vue'
-import { Dialog, showFailToast, showSuccessToast } from 'vant'
-import service from '@/services'
-import plus from '@/utils/h5plus'
-import AppQrcode from '@/components/base/qrcode/index.vue'
-
-const props = defineProps({
-    show: {
-        type: Boolean,
-        default: false
-    },
-    text: String,
-})
-
-const emit = defineEmits(['update:show'])
-const showConfirmButton = shallowRef(false)
-const base64Data = shallowRef('')
-
-const qrContent = computed(() => {
-    const url = service.getConfig('mobileOpenUrl')
-    return url + '/#/?code=' + props.text
-})
-
-const showDialog = computed({
-    get: () => props.show,
-    set: (val) => emit('update:show', val)
-})
-
-const onCopy = (status: boolean) => {
-    if (status) {
-        showSuccessToast('复制成功')
-    } else {
-        showFailToast('复制失败')
-    }
-}
-
-// 保存二维码
-const onConfirm = () => {
-    plus.saveImage(base64Data.value, 'thj_' + (props.text ?? new Date().getTime()))
-}
-
-plus.onPlusReady(() => {
-    showConfirmButton.value = true
-})
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 2 - 2
src/packages/gstj/main.ts

@@ -6,9 +6,9 @@ import router from './router'
 import directives from '@/directives' // 自定义指令集
 //import 'default-passive-events'
 import '@/utils/h5plus' // 加载html5+
-import layouts from './components/layouts' // 全局布局组件
+import layouts from '@mobile/components/layouts' // 全局布局组件
 import 'vant/lib/index.css'
-import './assets/iconfont/iconfont.js'
+import '@mobile/assets/iconfont/iconfont.js'
 import './assets/themes/style.less' // 主题样式
 import { timerInterceptor } from '@/utils/timer'
 import { useGlobalStore } from '@/stores'

+ 0 - 159
src/packages/gstj/router/animateRouter.ts

@@ -1,159 +0,0 @@
-import { ref, toRefs, readonly } from 'vue'
-import { createRouter, RouterOptions, RouteRecordRaw, RouteLocationNormalized } from 'vue-router'
-
-interface HistoryState {
-    history: RouteLocationNormalized[]; // 已访问的路由列表
-    excludeViews: string[]; // 不缓存的页面
-    actionName: '' | 'push' | 'replace' | 'forward' | 'back'; // 当前路由动作
-    transitionName: '' | 'route-out' | 'route-in'; // 前进后退动画
-    goStep: number; // 前进后退步数
-}
-
-export default new (class {
-    private storageKey = 'history_mobile';
-
-    private _state = ref<HistoryState>({
-        history: [],
-        excludeViews: [],
-        actionName: '',
-        transitionName: '',
-        goStep: 0,
-    })
-
-    /** 只读状态 */
-    state;
-
-    constructor() {
-        const state = sessionStorage.getItem(this.storageKey);
-        if (state) {
-            this._state.value = JSON.parse(state);
-        }
-        this.state = readonly(toRefs(this._state.value));
-    }
-
-    /**
-     * 创建路由
-     * @param options 
-     * @returns 
-     */
-    create = (options: RouterOptions) => {
-        const router = createRouter(options);
-        const { push, replace, go, forward, back } = router;
-        const { actionName, goStep } = toRefs(this._state.value);
-
-        // 添加
-        router.push = (to: RouteRecordRaw) => {
-            actionName.value = 'push';
-            return push(to);
-        }
-
-        // 替换
-        router.replace = (to: RouteRecordRaw) => {
-            actionName.value = 'replace';
-            return replace(to);
-        }
-
-        // 前进后退
-        router.go = (delta: number) => {
-            goStep.value = delta;
-            if (delta > 0) {
-                actionName.value = 'forward';
-            }
-            if (delta < 0) {
-                actionName.value = 'back';
-            }
-            go(delta);
-        }
-
-        // 前进
-        router.forward = () => {
-            actionName.value = 'forward';
-            forward();
-        }
-
-        // 后退
-        router.back = () => {
-            actionName.value = 'back';
-            back();
-        }
-
-        router.beforeResolve((to) => {
-            this.addHistory(to);
-        })
-
-        router.afterEach(() => {
-            const { excludeViews } = toRefs(this._state.value);
-            excludeViews.value = [];
-        })
-
-        return router;
-    }
-
-    /**
-     * 添加历史记录
-     * @param route 
-     */
-    private addHistory = (route: RouteLocationNormalized) => {
-        const { history, excludeViews, actionName, transitionName, goStep } = toRefs(this._state.value);
-
-        // 如果是替换动作,必定是前进
-        if (actionName.value === 'replace') {
-            const lastIndex = history.value.length - 1;
-            const lastView = history.value[lastIndex];
-
-            if (lastView) {
-                excludeViews.value.push(lastView.name as string);
-                history.value[lastIndex] = route; // 更新最后一条记录
-            } else {
-                history.value.push(route);
-            }
-            transitionName.value = 'route-in'; // 前进动画
-        } else {
-            // 倒序查找路由所在的位置
-            const index = (() => {
-                for (let i = history.value.length - 1; i >= 0; i--) {
-                    if (history.value[i].fullPath === route.fullPath) {
-                        return i;
-                    }
-                }
-                return -1;
-            })();
-
-            if (index > -1) {
-                if (actionName.value === 'push') {
-                    history.value.push(route);
-                    transitionName.value = 'route-in'; //前进动画
-                } else {
-                    if (history.value.length > 1) {
-                        const i = index + 1;
-                        const n = history.value.length - i;
-
-                        excludeViews.value = history.value.map((e) => e.name).slice(-n) as string[]; // 返回数组最后位置开始的n个元素
-                        history.value.splice(i, n); // 从i位置开始删除后面所有元素(包括i)
-                    }
-                    transitionName.value = 'route-out'; //后退动画
-                }
-            } else {
-                if (goStep.value < 0) {
-                    const start = history.value.length + goStep.value
-                    if (start) {
-                        history.value.splice(start)
-                    }
-                }
-                // 忽略重定向的页面
-                if (route.redirectedFrom) {
-                    transitionName.value = 'route-in'; // 前进动画
-                } else {
-                    history.value.push(route);
-                    if (history.value.length > 1) {
-                        transitionName.value = 'route-in'; // 前进动画
-                    }
-                }
-            }
-        }
-
-        actionName.value = '';
-        goStep.value = 0
-        sessionStorage.setItem(this.storageKey, JSON.stringify(this._state.value));
-    }
-})

+ 48 - 127
src/packages/gstj/router/index.ts

@@ -2,8 +2,8 @@ import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import { useLoginStore } from '@/stores'
 import { clearPending } from '@/services/http/pending'
 import service from '@/services'
-import Page from '../components/layouts/page/index.vue'
-import animateRouter from './animateRouter'
+import Page from '@mobile/components/layouts/page/index.vue'
+import animateRouter from '@mobile/router/animateRouter'
 
 const loginStore = useLoginStore()
 
@@ -44,7 +44,7 @@ const routes: Array<RouteRecordRaw> = [
           {
             path: 'goods',
             name: 'home-goods',
-            component: () => import('../views/goods/list/Index.vue'),
+            component: () => import('@mobile/views/goods/list/Index.vue'),
             props: {
               marketId: 50101
             }
@@ -52,7 +52,7 @@ const routes: Array<RouteRecordRaw> = [
           {
             path: 'forward',
             name: 'home-forward',
-            component: () => import('../views/goods/list/Index.vue'),
+            component: () => import('@mobile/views/goods/list/Index.vue'),
             props: {
               marketId: 50102
             }
@@ -60,7 +60,7 @@ const routes: Array<RouteRecordRaw> = [
           {
             path: 'spot',
             name: 'home-spot',
-            component: () => import('../views/spot/list/Index.vue'),
+            component: () => import('@mobile/views/spot/list/Index.vue'),
           },
           {
             path: 'mine',
@@ -86,7 +86,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'register',
         name: 'user-register',
-        component: () => import('../views/user/register/Index.vue'),
+        component: () => import('@mobile/views/user/register/Index.vue'),
         meta: {
           ignoreAuth: true,
         },
@@ -94,7 +94,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'forget',
         name: 'user-forget',
-        component: () => import('../views/user/forget/Index.vue'),
+        component: () => import('@mobile/views/user/forget/Index.vue'),
         meta: {
           ignoreAuth: true,
         },
@@ -102,17 +102,17 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'cancel',
         name: 'user-cancel',
-        component: () => import('../views/user/cancel/Index.vue'),
+        component: () => import('@mobile/views/user/cancel/Index.vue'),
       },
       {
         path: 'password',
         name: 'user-password',
-        component: () => import('../views/user/password/Index.vue'),
+        component: () => import('@mobile/views/user/password/Index.vue'),
       },
       {
         path: 'avatar',
         name: 'user-avatar',
-        component: () => import('../views/user/avatar/Index.vue'),
+        component: () => import('@mobile/views/user/avatar/Index.vue'),
       },
     ],
   },
@@ -123,7 +123,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'certification',
         name: 'account-certification',
-        component: () => import('../views/account/certification/Index.vue'),
+        component: () => import('@mobile/views/account/certification/Index.vue'),
       },
     ],
   },
@@ -134,7 +134,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: '',
         name: 'news-list',
-        component: () => import('../views/news/list/Index.vue'),
+        component: () => import('@mobile/views/news/list/Index.vue'),
         meta: {
           ignoreAuth: true,
         },
@@ -142,7 +142,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'detail',
         name: 'news-detail',
-        component: () => import('../views/news/detail/Index.vue'),
+        component: () => import('@mobile/views/news/detail/Index.vue'),
         meta: {
           ignoreAuth: true,
         },
@@ -156,12 +156,12 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'detail',
         name: 'goods-detail',
-        component: () => import('../views/goods/detail/Index.vue'),
+        component: () => import('@mobile/views/goods/detail/Index.vue'),
       },
       {
         path: 'trade',
         name: 'goods-trade',
-        component: () => import('../views/goods/trade/index.vue'),
+        component: () => import('@mobile/views/goods/trade/index.vue'),
       },
     ],
   },
@@ -170,19 +170,14 @@ const routes: Array<RouteRecordRaw> = [
     component: Page,
     children: [
       {
-        path: '',
-        name: 'spot-list',
-        component: () => import('../views/spot/list/Index.vue'),
-      },
-      {
         path: 'detail',
         name: 'spot-detail',
-        component: () => import('../views/spot/detail/Index.vue'),
+        component: () => import('@mobile/views/spot/detail/Index.vue'),
       },
       {
         path: 'add',
         name: 'spot-add',
-        component: () => import('../views/spot/add/index.vue'),
+        component: () => import('@mobile/views/spot/add/index.vue'),
       },
     ],
   },
@@ -193,22 +188,22 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'wallet',
         name: 'bank-wallet',
-        component: () => import('../views/bank/wallet/Index.vue'),
+        component: () => import('@mobile/views/bank/wallet/Index.vue'),
       },
       {
         path: 'sign',
         name: 'bank-sign',
-        component: () => import('../views/bank/sign/Index.vue'),
+        component: () => import('@mobile/views/bank/sign/Index.vue'),
       },
       {
         path: 'statement',
         name: 'bank-statement',
-        component: () => import('../views/bank/statement/Index.vue'),
+        component: () => import('@mobile/views/bank/statement/Index.vue'),
       },
       {
         path: 'statement/history',
         name: 'bank-statement-history',
-        component: () => import('../views/bank/statement/history/Index.vue'),
+        component: () => import('@mobile/views/bank/statement/history/Index.vue'),
       },
     ],
   },
@@ -234,7 +229,21 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'performance',
         name: 'order-performance',
-        component: () => import('../views/order/performance/Index.vue'),
+        component: () => import('@mobile/views/order/performance/Index.vue'),
+      },
+    ],
+  },
+  {
+    path: '/forward',
+    component: Page,
+    children: [
+      {
+        path: '',
+        name: 'forward-list',
+        component: () => import('@mobile/views/goods/list/Index.vue'),
+        props: {
+          marketId: 50102
+        }
       },
     ],
   },
@@ -245,22 +254,22 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: 'address',
         name: 'mine-address',
-        component: () => import('../views/mine/address/Index.vue'),
+        component: () => import('@mobile/views/mine/address/Index.vue'),
       },
       {
         path: 'invoice',
         name: 'mine-invoice',
-        component: () => import('../views/mine/invoice/Index.vue'),
+        component: () => import('@mobile/views/mine/invoice/Index.vue'),
       },
       {
         path: 'profile',
         name: 'mine-profile',
-        component: () => import('../views/mine/profile/Index.vue'),
+        component: () => import('@mobile/views/mine/profile/Index.vue'),
       },
       {
         path: 'setting',
         name: 'mine-setting',
-        component: () => import('../views/mine/setting/Index.vue'),
+        component: () => import('@mobile/views/mine/setting/Index.vue'),
       },
     ],
   },
@@ -271,7 +280,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: '',
         name: 'notice-list',
-        component: () => import('../views/notice/list/index.vue'),
+        component: () => import('@mobile/views/notice/list/index.vue'),
       },
     ],
   },
@@ -280,33 +289,9 @@ const routes: Array<RouteRecordRaw> = [
     component: Page,
     children: [
       {
-        path: "ptgz",
-        name: "rules-ptgz",
-        component: () => import("../views/rules/ptgz/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "myrz",
-        name: "rules-myrz",
-        component: () => import("../views/rules/myrz/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "ccwl",
-        name: "rules-ccwl",
-        component: () => import("../views/rules/ccwl/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
         path: "zcxy",
         name: "rules-zcxy",
-        component: () => import("../views/rules/zcxy/Index.vue"),
+        component: () => import("@mobile/views/rules/zcxy/Index.vue"),
         meta: {
           ignoreAuth: true,
         },
@@ -314,7 +299,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: "yhkhfxgzs",
         name: "rules-yhkhfxgzs",
-        component: () => import("../views/rules/fxgzs/Index.vue"),
+        component: () => import("@mobile/views/rules/fxgzs/Index.vue"),
         meta: {
           ignoreAuth: true,
         },
@@ -322,7 +307,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: "yszc",
         name: "rules-yszc",
-        component: () => import("../views/rules/yszc/Index.vue"),
+        component: () => import("@mobile/views/rules/yszc/Index.vue"),
         meta: {
           ignoreAuth: true,
         },
@@ -330,15 +315,7 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: "gywm",
         name: "rules-gywm",
-        component: () => import("../views/rules/gywm/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "fpsm",
-        name: "rules-fpsm",
-        component: () => import("../views/rules/fpsm/Index.vue"),
+        component: () => import("@mobile/views/rules/gywm/Index.vue"),
         meta: {
           ignoreAuth: true,
         },
@@ -346,69 +323,13 @@ const routes: Array<RouteRecordRaw> = [
       {
         path: "fwrx",
         name: "rules-fwrx",
-        component: () => import("../views/rules/fwrx/Index.vue"),
+        component: () => import("@mobile/views/rules/fwrx/Index.vue"),
         meta: {
           ignoreAuth: true,
         },
       },
-      {
-        path: "buyrule",
-        name: "rules-buyrule",
-        component: () => import("../views/rules/buyrule/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "sellrule",
-        name: "rules-sellrule",
-        component: () => import("../views/rules/sellrule/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "djgz",
-        name: "rules-dj",
-        component: () => import("../views/rules/djgz/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "jfgz",
-        name: "rules-jf",
-        component: () => import("../views/rules/jfgz/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "cght",
-        name: "rules-cght",
-        component: () => import("../views/rules/cght/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "zrht",
-        name: "rules-zrht",
-        component: () => import("../views/rules/zrht/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-      {
-        path: "xhht",
-        name: "rules-xhht",
-        component: () => import("../views/rules/xhht/Index.vue"),
-        meta: {
-          ignoreAuth: true,
-        },
-      },
-    ],
-  },
+    ]
+  }
 ]
 
 const router = animateRouter.create({

+ 0 - 129
src/packages/gstj/router/navigation.ts

@@ -1,129 +0,0 @@
-import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router'
-import animateRouter from './animateRouter'
-
-export function useNavigation() {
-    const route = useRoute()
-    const router = useRouter()
-
-    // 缓存全局Url参数
-    const setGlobalUrlParams = <T extends object>(params?: T) => {
-        sessionStorage.setItem('globalUrlParams', JSON.stringify(params ?? {}))
-    }
-
-    // 是否有历史页面
-    const hasHistory = () => {
-        const { state } = animateRouter
-        return state.history.length > 1
-    }
-
-    // 获取全局Url参数(只能获取一次)
-    const getGlobalUrlParams = () => {
-        const params = sessionStorage.getItem('globalUrlParams')
-        if (params) {
-            sessionStorage.removeItem('globalUrlParams')
-            return JSON.parse(params)
-        } else {
-            return {}
-        }
-    }
-
-    // 获取参数字符串
-    const getParamString = (name: string) => {
-        return route.params[name] ?? ''
-    }
-
-    // 获取查询字符串
-    const getQueryString = (name: string) => {
-        const qs = route.query[name]
-        if (qs) {
-            return qs.toString()
-        }
-        return ''
-    }
-
-    const getQueryStringToNumber = (name: string) => {
-        const reg = /^[0-9]+.?[0-9]*/
-        const value = getQueryString(name)
-        return reg.test(value) ? Number(value) : 0
-    }
-
-    // 返回指定页面
-    // const backTo = <T extends object>(name: string, params?: T) => {
-    //     const { state } = animateRouter
-    //     const total = state.history.length - 1
-    //     const index = state.history.findIndex(((e) => e.name === name))
-
-    //     if (total > -1) {
-    //         if (index > -1) {
-    //             setGlobalUrlParams(params)
-    //             const delta = total - index
-    //             if (delta > 0) {
-    //                 router.go(-delta)
-    //             } else {
-    //                 router.replace({ name })
-    //             }
-    //         }
-    //     } else {
-    //         router.replace({ name })
-    //     }
-    // }
-
-    // 返回主页
-    const backHome = () => {
-        const { state } = animateRouter
-        const delta = state.history.length - 1
-        const params = { tabIndex: 0 }
-
-        if (delta) {
-            setGlobalUrlParams(params)
-            router.go(-delta)
-        } else {
-            const page = state.history[0]
-            if (page?.name !== 'home-index') {
-                setGlobalUrlParams(params)
-                router.replace({ name: 'home-index' })
-            }
-        }
-    }
-
-    // 返回上个页面
-    const routerBack = <T extends object>(params?: T) => {
-        setGlobalUrlParams(params)
-        router.back()
-    }
-
-    // 路由跳转
-    const routerTo = (name: string, replace = false) => {
-        if (replace) {
-            router.replace({ name })
-        } else {
-            router.push({ name })
-        }
-    }
-
-    // 路由守卫
-    const beforeRouteLeave = (callback: () => boolean) => {
-        onBeforeRouteLeave((to, from, next) => {
-            if (callback()) {
-                next()
-            } else {
-                next(false)
-            }
-        })
-    }
-
-    return {
-        route,
-        router,
-        hasHistory,
-        setGlobalUrlParams,
-        getGlobalUrlParams,
-        getParamString,
-        getQueryString,
-        getQueryStringToNumber,
-        backHome,
-        routerBack,
-        routerTo,
-        beforeRouteLeave,
-    }
-}

+ 0 - 96
src/packages/gstj/views/account/certification/Index.vue

@@ -1,96 +0,0 @@
-<template>
-    <app-view class="g-form account-certification">
-        <template #header>
-            <app-navbar title="实名认证" />
-        </template>
-        <Form ref="formRef" class="g-form__container" @submit="onSubmit">
-            <CellGroup inset>
-                <Field v-model="formData.username" name="username" label="姓名" placeholder="请输入用户姓名"
-                    :rules="formRules.username" />
-                <Field name="cardtype" label="证件类型" :rules="formRules.cardtype" is-link>
-                    <template #input>
-                        <app-select v-model="formData.cardtype" placeholder="请选择证件类型" :options="enums" />
-                    </template>
-                </Field>
-                <Field v-model="formData.cardnum" name="cardnum" label="证件号码" placeholder="请输入证件号码"
-                    :rules="formRules.cardnum" />
-                <Field name="cardfrontphotourl" label="证件正面照片" :rules="formRules.cardfrontphotourl">
-                    <template #input>
-                        <app-uploader @success="b_afterRead" />
-                    </template>
-                </Field>
-                <Field name="cardbackphotourl" label="证件反面照片" :rules="formRules.cardbackphotourl">
-                    <template #input>
-                        <app-uploader @success="f_afterRead" />
-                    </template>
-                </Field>
-            </CellGroup>
-        </Form>
-        <img src="../../../assets/images/certification.png" />
-        <template #footer>
-            <div class="g-form__footer inset">
-                <Button type="danger" @click="formRef?.submit" round block>提交实名认证</Button>
-            </div>
-        </template>
-    </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, computed } from 'vue'
-import { CellGroup, Button, Field, Form, FormInstance, showFailToast, FieldRule } from 'vant'
-import { addAuthReq } from '@/business/user'
-import { fullloading, dialog } from '@/utils/vant';
-import { getCertificateTypeList } from "@/constants/account";
-import AppSelect from '../../../components/base/select/index.vue'
-import { useNavigation } from '../../../router/navigation'
-import AppUploader from '../../../components/base/uploader/index.vue'
-
-const formRef = shallowRef<FormInstance>()
-const { formData, formSubmit } = addAuthReq()
-const { router } = useNavigation()
-
-/// 获取对应的证件枚举类型
-const enums = computed(() => { return getCertificateTypeList().map(obj => { return { label: obj.label, value: obj.value } }) })
-
-const b_afterRead = (filePath: string) => {
-    formData.cardfrontphotourl = filePath
-}
-
-const f_afterRead = (filePath: string) => {
-    formData.cardbackphotourl = filePath
-}
-
-// 表单验证规则
-const formRules: { [key in keyof Model.AddAuthReq]?: FieldRule[] } = {
-    username: [{
-        required: true,
-        message: '请输入用户姓名',
-    }],
-    cardnum: [{
-        required: true,
-        message: '请输入证件号码',
-
-    }],
-    cardbackphotourl: [{
-        required: true,
-        message: '请上传证件背面照片',
-    }],
-    cardfrontphotourl: [{
-        required: true,
-        message: '请上传证件正面照片',
-    }],
-}
-
-const onSubmit = () => {
-    fullloading((hideLoading) => {
-        formSubmit().then(() => {
-            hideLoading()
-            dialog('实名认证提交请求成功').then(() => {
-                router.back()
-            })
-        }).catch((err) => {
-            showFailToast(err)
-        })
-    })
-}
-</script>

+ 0 - 71
src/packages/gstj/views/bank/sign/Index.vue

@@ -1,71 +0,0 @@
-<template>
-    <app-view class="bank-sign g-form">
-        <template #header>
-            <app-navbar title="签约账户管理" />
-        </template>
-        <div class="bank-sign__container" v-if="bankInfo">
-            <CellGroup>
-                <Cell title="开户银行" :value="bankInfo.bankname" />
-                <Cell title="银行卡号" :value="bankInfo.bankaccountno" />
-                <Cell title="姓名" :value="bankInfo.bankaccountname" />
-                <Cell title="支行名称" :value="bankInfo.branchbankname" />
-                <Cell title="状态" :value="getSignStatusName(bankInfo.signstatus)" />
-            </CellGroup>
-        </div>
-        <div class="bank-sign__empty" v-else>
-            <Empty description="您还未添加签约账户" />
-            <Button type="danger" @click="openComponent('edit')" round>添加签约账户</Button>
-        </div>
-        <template #footer>
-            <div class="g-form__footer inset" v-if="bankInfo">
-                <Button type="warning" round block @click="formSubmit"
-                    v-if="bankInfo.signstatus === SignStatus.Signed">解约</Button>
-                <Button type="danger" round block @click="openComponent('edit')"
-                    v-if="[SignStatus.Unsigned, SignStatus.Refuse, SignStatus.Signed].includes(bankInfo.signstatus)">修改</Button>
-            </div>
-        </template>
-        <component ref="componentRef" :is="componentMap.get(componentId)" @closed="closeComponent" v-if="componentId" />
-    </app-view>
-</template>
-
-<script lang="ts" setup>
-import { onActivated, defineAsyncComponent } from 'vue'
-import { CellGroup, Cell, Button, Empty, showFailToast } from 'vant'
-import { fullloading, dialog } from '@/utils/vant'
-import { useComponent } from '@/hooks/component'
-import { getSignStatusName, SignStatus } from '@/constants/bank'
-import { useDoCancelBankSign } from '@/business/bank'
-import { useNavigation } from '../../../router/navigation'
-
-const componentMap = new Map<string, unknown>([
-    ['edit', defineAsyncComponent(() => import('./components/edit/Index.vue'))],
-])
-
-const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => formRefresh())
-const { cancelSubmit, formRefresh, bankInfo } = useDoCancelBankSign()
-const { router } = useNavigation()
-
-const formSubmit = () => {
-    dialog({
-        message: '确认解约?',
-        showCancelButton: true
-    }).then(() => {
-        fullloading((hideLoading) => {
-            cancelSubmit().then(() => {
-                hideLoading()
-                dialog('签约提交成功,请耐心等待审核。').then(() => {
-                    router.back()
-                })
-            }).catch((err) => {
-                showFailToast(err)
-            })
-        })
-    })
-}
-
-onActivated(() => formRefresh())
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 131
src/packages/gstj/views/bank/sign/components/edit/Index.vue

@@ -1,131 +0,0 @@
-<template>
-    <app-modal direction="right" height="100%" v-model:show="showModal" :refresh="refresh">
-        <app-view class="g-form">
-            <template #header>
-                <app-navbar :title="isedit ? '修改签约账户' : '添加签约账户'" @back="closed" />
-            </template>
-            <Form ref="formRef" class="g-form__container" @submit="formSubmit">
-                <CellGroup inset>
-                    <Field name="OpenBankAccId" label="开户银行" :rules="formRules.OpenBankAccId" is-link>
-                        <template #input>
-                            <app-select v-model="formData.OpenBankAccId" placeholder="请选择开户银行" :options="banklist"
-                                :optionProps="{ label: 'bankname', value: 'bankid' }" />
-                        </template>
-                    </Field>
-                    <Field name="BankNo" label="银行卡号" v-model="formData.BankAccountNo" placeholder="请输入银行卡账号"
-                        :rules="formRules.BankAccountNo" />
-                    <Field name="AccountName" label="姓名" readonly v-model="formData.BankAccountName" placeholder="请输入银行卡账户名"
-                        :rules="formRules.BankAccountName" />
-                    <template v-for="(item, index) in configs" :key="index">
-                        <Field v-if="item.usabletype === 1 || item.usabletype === userStore.userInfo?.userinfotype" 
-                            :name="item.fieldcode" :label="item.fieldname" v-model="item.value" :placeholder="`请输入${ item.fieldname }`" />
-                    </template>
-                </CellGroup>
-            </Form>
-            <template #footer>
-                <div class="g-form__footer inset">
-                    <Button type="danger" round block @click="formRef?.submit()">{{ bankInfo ? '修改' : '提交' }}</Button>
-                </div>
-            </template>
-        </app-view>
-    </app-modal>
-</template>
-
-<script lang="ts" setup>
-
-import { shallowRef } from 'vue'
-import { CellGroup, Button, Field, Form, FormInstance, FieldRule, showFailToast } from 'vant'
-import { fullloading, dialog } from '@/utils/vant'
-import { useDoBankSign, useDoCusBankExtendConfigs } from '@/business/bank'
-import { validateRules } from '@/constants/regex'
-import { useErrorInfoStore } from '@/stores'
-import { useUserStore } from '@/stores'
-import AppModal from '@/components/base/modal/index.vue'
-import AppSelect from '../../../../../components/base/select/index.vue'
-
-const { formData, onSubmit, banklist, bankInfo } = useDoBankSign()
-const showModal = shallowRef(true)
-const refresh = shallowRef(false) // 是否刷新父组件数据
-const formRef = shallowRef<FormInstance>()
-const { configs } = useDoCusBankExtendConfigs(1)
-const userStore = useUserStore()
-
-const props = defineProps({
-    isedit: {
-        type: Boolean,
-        required: true,
-    }
-})
-
-// 表单验证规则
-const formRules: { [key in keyof Proto.t2bBankSignReq]?: FieldRule[] } = {
-    OpenBankAccId: [{
-        message: '请选择银行信息',
-        validator: () => {
-            return !!formData.OpenBankAccId
-        }
-    }],
-    BankAccountNo: [{
-        required: true,
-        message: '请输入银行卡账号',
-        validator: (val) => {
-            if (validateRules.bankcardno.validate(val)) {
-                return true
-            }
-            return validateRules.bankcardno.message
-        }
-    }],
-    BankAccountName: [{
-        required: true,
-        message: '请输入银行卡账户名',
-    }],
-    OpenBankName: [{
-        required: true,
-        message: '请输入银行卡支行名称',
-    }],
-}
-
-const formSubmit = () => {
-    fullloading((hideLoading) => {
-        const obj:{[key:string]:unknown}=Object.create({})
-        configs.value.forEach((e)=>{
-            if(e.value){
-                obj[e.fieldcode]=e.value
-            }
-            if (e.fieldcode === 'bank_branch_name') {
-                formData.OpenBankName = e.value
-            }
-            if (e.fieldcode === '100') {
-                formData.OpenBankNo = e.value
-            }
-            if (e.fieldcode === '101') {
-                formData.BankProvince = e.value
-            }
-            if (e.fieldcode === '102') {
-                formData.BankCity = e.value
-            }
-        })
-        formData.extend_info = JSON.stringify(obj)
-        onSubmit().then(() => {
-            hideLoading()
-            dialog(props.isedit ? '签约信息修改提交成功' : '签约提交成功,请耐心等待审核。').then(() => {
-                closed(true)
-            })
-        }).catch((err) => {
-            const { getErrorInfoByCode } = useErrorInfoStore()
-            showFailToast(getErrorInfoByCode(Number(err)) ?? '')
-        })
-    })
-}
-
-// 关闭弹窗
-const closed = (isRefresh = false) => {
-    refresh.value = isRefresh
-    showModal.value = false
-}
-
-// 暴露组件属性给父组件调用
-defineExpose({
-    closed,
-})
-</script>

+ 0 - 19
src/packages/gstj/views/bank/sign/index.less

@@ -1,19 +0,0 @@
-.bank-sign {
-    &__container {
-        padding-top: .2rem;
-
-        .van-cell {
-            &__title {
-                flex: initial;
-            }
-        }
-    }
-
-    &__empty {
-        text-align: center;
-
-        .van-button {
-            width: 50%;
-        }
-    }
-}

+ 0 - 78
src/packages/gstj/views/bank/statement/Index.vue

@@ -1,78 +0,0 @@
-<template>
-    <app-view class="bank-statement">
-        <template #header>
-            <app-navbar title="资金流水">
-                <template #right>
-                    <div class="button-more" @click="routerTo('bank-statement-history')">
-                        <span>更多</span>
-                    </div>
-                </template>
-            </app-navbar>
-        </template>
-        <app-pull-refresh v-model:loading="loading" v-model:error="error" v-model:pageIndex="pageIndex"
-            :page-count="pageCount" @refresh="run">
-            <app-list class="bank-statement__table" :columns="columns" :data-list="dataList">
-                <template #createtime="{ value }">
-                    <span>{{ formatDate(value, 'YYYY-MM-DD') }}</span>
-                    <span>{{ formatDate(value, 'HH:mm:ss') }}</span>
-                </template>
-            </app-list>
-        </app-pull-refresh>
-    </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from 'vue'
-import { formatDate } from '@/filters'
-import { useRequest } from '@/hooks/request'
-import { useNavigation } from '../../../router/navigation'
-import { queryAmountLog } from '@/services/api/bank'
-import AppPullRefresh from '../../../components/base/pull-refresh/index.vue'
-import AppList from '../../../components/base/list/index.vue'
-
-const { routerTo } = useNavigation()
-const dataList = shallowRef<Model.AmountLogRsp[]>([])
-const error = shallowRef(false)
-
-const columns: Model.TableColumn[] = [
-    { prop: 'createtime', label: '时间' },
-    { prop: 'operatetypename', label: '操作类型' },
-    { prop: 'amount', label: '金额' },
-]
-
-const { loading, pageIndex, pageCount, run } = useRequest(queryAmountLog, {
-    manual: true,
-    params: {
-        pagesize: 20,
-        pageflag: 1,
-    },
-    onSuccess: (res) => {
-        if (pageIndex.value === 1) {
-            dataList.value = []
-        }
-        dataList.value.push(...res.data)
-    },
-    onError: () => {
-        error.value = true
-    }
-})
-</script>
-
-<style lang="less">
-.bank-statement {
-    &__table {
-        td.app-list__column {
-            &:first-child {
-                span:last-child {
-                    color: #999;
-                    font-size: .24rem;
-                }
-            }
-
-            &:not(:first-child) {
-                font-size: .32rem;
-            }
-        }
-    }
-}
-</style>

+ 0 - 70
src/packages/gstj/views/bank/statement/history/Index.vue

@@ -1,70 +0,0 @@
-<template>
-    <app-view class="bank-hisstatement">
-        <template #header>
-            <app-navbar title="历史资金流水" />
-        </template>
-        <app-pull-refresh v-model:loading="loading" v-model:error="error" v-model:pageIndex="pageIndex"
-            :page-count="pageCount" @refresh="run">
-            <app-list class="bank-hisstatement__table" :columns="columns" :data-list="dataList">
-                <template #createtime="{ value }">
-                    <span>{{ formatDate(value, 'YYYY-MM-DD') }}</span>
-                    <span>{{ formatDate(value, 'HH:mm:ss') }}</span>
-                </template>
-            </app-list>
-        </app-pull-refresh>
-    </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from 'vue'
-import { formatDate } from '@/filters'
-import { useRequest } from '@/hooks/request'
-import { queryHisAmountLog } from '@/services/api/bank'
-import AppPullRefresh from '../../../../components/base/pull-refresh/index.vue'
-import AppList from '../../../../components/base/list/index.vue'
-
-const dataList = shallowRef<Model.HisAmountLogRsp[]>([])
-const error = shallowRef(false)
-
-const columns: Model.TableColumn[] = [
-    { prop: 'createtime', label: '时间' },
-    { prop: 'operatetypename', label: '操作类型' },
-    { prop: 'amount', label: '金额' },
-]
-
-const { loading, pageIndex, pageCount, run } = useRequest(queryHisAmountLog, {
-    manual: true,
-    params: {
-        pagesize: 20,
-        pageflag: 1,
-    },
-    onSuccess: (res) => {
-        if (pageIndex.value === 1) {
-            dataList.value = []
-        }
-        dataList.value.push(...res.data)
-    },
-    onError: () => {
-        error.value = true
-    }
-})
-</script>
-
-<style lang="less">
-.bank-hisstatement {
-    &__table {
-        td.app-list__column {
-            &:first-child {
-                span:last-child {
-                    color: #999;
-                    font-size: .24rem;
-                }
-            }
-
-            &:not(:first-child) {
-                font-size: .32rem;
-            }
-        }
-    }
-}
-</style>

+ 0 - 27
src/packages/gstj/views/bank/wallet/Index.vue

@@ -1,27 +0,0 @@
-<template>
-    <app-view>
-        <template #header>
-            <app-navbar title="充值提现" />
-        </template>
-        <Tabs v-model:active="active">
-            <Tab title="充值">
-                <app-deposit />
-            </Tab>
-            <Tab title="提现">
-                <app-withdraw />
-            </Tab>
-        </Tabs>
-    </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef } from 'vue'
-import { Tab, Tabs } from 'vant'
-import { useNavigation } from '../../../router/navigation'
-import AppDeposit from './components/deposit/Index.vue'
-import AppWithdraw from './components/withdraw/Index.vue'
-
-const { getQueryStringToNumber } = useNavigation()
-
-const active = shallowRef(getQueryStringToNumber('tab'))
-</script>

+ 0 - 143
src/packages/gstj/views/bank/wallet/components/deposit/Index.vue

@@ -1,143 +0,0 @@
-<template>
-    <app-view class="g-form bank-wallet-deposit">
-        <Form ref="formRef" v-if="cusBank.caninamount === 1" class="g-form__container" @submit="formSubmit">
-            <CellGroup inset>
-                <Field type="number" v-model="formData.Amount" label="充值金额" placeholder="请填写充值金额"
-                    :rules="formRules.Amount" />
-                <Field label="凭证" :rules="formRules.filePath">
-                    <template #input>
-                        <app-uploader @success="onUploadSuccess" />
-                    </template>
-                </Field>
-                <template v-for="(item, index) in configs" :key="index">
-                    <Field v-if="item.usabletype === 1 || item.usabletype === userStore.userInfo?.userinfotype" :name="item.fieldcode" 
-                       :label="item.fieldname" v-model="item.value" :placeholder="`请输入${ item.fieldname }`" />
-                </template>
-            </CellGroup>
-        </Form>
-        <div class="g-form__bank" v-else>
-            <span>{{ msg }}</span>
-        </div>
-        <div class="g-form__time">
-            <label>充值提现时间:{{ start }}-{{ end }}</label>
-        </div>
-        <div class="g-form__bank" v-if="false">
-            <table cellspacing="10" cellpadding="0">
-                <tr>
-                    <td>
-                        <span>企业名称:</span>
-                        <span>上海徽行供应链有限公司</span>
-                    </td>
-                    <td>
-                        <button type="button" data-clipboard-text="上海徽行供应链有限公司" v-copy="onCopy">复制</button>
-                    </td>
-                </tr>
-                <tr>
-                    <td colspan="2">
-                        <span>开户银行:</span>
-                        <span>中信银行上海虹口支行</span>
-                    </td>
-                </tr>
-                <tr>
-                    <td>
-                        <span>银行账户:</span>
-                        <span>8110201012101533442</span>
-                    </td>
-                    <td>
-                        <button ref="copy2" type="button" data-clipboard-text="8110201012101533442"
-                            v-copy="onCopy">复制</button>
-                    </td>
-                </tr>
-                <tr>
-                    <td colspan="2">
-                        <span>(汇款备注:预付货款或合同转让款)</span>
-                    </td>
-                </tr>
-                <tr>
-                    <td colspan="2">
-                        <span>电话: 021-63138889, 13681901188</span>
-                    </td>
-                </tr>
-            </table>
-        </div>
-        <template #footer>
-            <div class="g-form__footer inset">
-                <Button round block type="danger" @click="formRef?.submit()">确定</Button>
-            </div>
-        </template>
-    </app-view>
-</template>
-
-<script lang="ts" setup>
-import { shallowRef, ref } from 'vue'
-import { Form, Field, CellGroup, Button, FieldRule, FormInstance, showFailToast, showSuccessToast } from 'vant'
-import { useDoDeposit, useDoCusBankExtendConfigs, useQueryCusBankSignBank } from '@/business/bank'
-import { fullloading, dialog } from '@/utils/vant'
-import { useNavigation } from '../../../../../router/navigation'
-import { useUserStore } from '@/stores'
-import AppUploader from '../../../../../components/base/uploader/index.vue'
-
-const formRef = shallowRef<FormInstance>()
-const { formData, onSubmit } = useDoDeposit()
-const { router } = useNavigation()
-const { getSystemParamValue } = useUserStore()
-const start = getSystemParamValue('012')
-const end = getSystemParamValue('013')
-const msg = getSystemParamValue('302')
-const { configs } = useDoCusBankExtendConfigs(2)
-const certificate_photo_url = ref('')
-const userStore = useUserStore()
-/// 查询托管银行信息
-const { cusBank } = useQueryCusBankSignBank()
-
-// 表单验证规则
-const formRules: { [key in keyof Proto.t2bBankDepositReq | 'filePath']?: FieldRule[] } = {
-    Amount: [{
-        required: true,
-        message: '请填写充值金额',
-    }],
-    filePath: [{
-        message: '请上传转账凭证',
-        validator: () => {
-            return !!certificate_photo_url.value
-        }
-    }]
-}
-
-const onCopy = (status: boolean) => {
-    if (status) {
-        showSuccessToast('复制成功')
-    } else {
-        showFailToast('复制失败')
-    }
-}
-
-const onUploadSuccess = (filePath: string) => {
-    certificate_photo_url.value = filePath
-}
-
-const formSubmit = () => {
-    fullloading((hideLoading) => {
-        const obj:{[key:string]:unknown}=Object.create({})
-        configs.value.forEach((e)=>{
-            if(e.value){
-                obj[e.fieldcode]=e.value
-            }
-        })
-        obj['certificate_photo_url'] = certificate_photo_url.value
-        formData.extend_info = JSON.stringify(obj)
-        onSubmit().then(() => {
-            hideLoading()
-            dialog('充值申请提交成功,请等待审核。').then(() => {
-                router.back()
-            })
-        }).catch(() => {
-            hideLoading('充值失败', 'fail')
-        })
-    })
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 35
src/packages/gstj/views/bank/wallet/components/deposit/index.less

@@ -1,35 +0,0 @@
-.bank-wallet-deposit {
-    .g-form__time {
-        color: #999;
-        padding-left: 15px;
-    }
-
-    .g-form__bank {
-        padding: 16px;
-
-        table {
-            width: 100%;
-            font-size: .24rem;
-            border: 1px dashed #ddd;
-            border-radius: .1rem;
-
-            td {
-                &:not(:first-child) {
-                    text-align: right;
-                }
-
-                span {
-                    &:first-child {
-                        color: #999;
-                    }
-                }
-
-                button {
-                    background-color: #e1e1e1;
-                    border-radius: .1rem;
-                    padding: .04rem .2rem;
-                }
-            }
-        }
-    }
-}

+ 0 - 105
src/packages/gstj/views/bank/wallet/components/withdraw/Index.vue

@@ -1,105 +0,0 @@
-<template>
-    <app-view class="g-form bank-wallet-withdraw">
-        <Form ref="formRef" v-if="cusBank.canoutamount === 1" class="g-form__container" @submit="formSubmit">
-            <CellGroup inset>
-                <Field class="form-field" type="number" label="提现金额" v-model="formData.Amount" :rules="formRules.Amount">
-                    <template #input>
-                        <input v-model="formData.Amount" placeholder="请填写提现金额" />
-                        <span class="form-field__tips">可出金额:{{ fund.AvailableOutMoney }}</span>
-                    </template>
-                </Field>
-                <Field label="开户银行">
-                    <template #input>
-                        {{ sign.bankname }}
-                    </template>
-                </Field>
-                <Field label="银行卡号">
-                    <template #input>
-                        {{ sign.bankaccountno }}
-                    </template>
-                </Field>
-                <Field label="姓名">
-                    <template #input>
-                        {{ sign.bankaccountname }}
-                    </template>
-                </Field>
-                <template v-for="(item, index) in configs" :key="index">
-                    <Field v-if="item.usabletype === 1 || item.usabletype === userStore.userInfo?.userinfotype" :name="item.fieldcode" 
-                       :label="item.fieldname" v-model="item.value" :placeholder="`请输入${ item.fieldname }`" />
-                </template>
-            </CellGroup>
-        </Form>
-        <div class="g-form__bank" v-else>
-                <span>{{ msg }}</span>
-            </div>
-        <div class="g-form__time">
-            <label>充值提现时间:{{ start }}-{{ end }}</label>
-        </div>
-        <template #footer>
-            <div class="g-form__footer inset">
-                <Button round block type="danger" @click="formRef?.submit()">确定</Button>
-            </div>
-        </template>
-    </app-view>
-</template>
-
-<script lang="ts" setup>
-import { useDoWithdraw, useAccountFundInfo, useDoCusBankExtendConfigs, useQueryCusBankSignBank } from '@/business/bank';
-import { Form, Field, CellGroup, FormInstance, Button, FieldRule } from 'vant'
-import { shallowRef } from 'vue'
-import { fullloading, dialog } from '@/utils/vant'
-import { useNavigation } from '../../../../../router/navigation'
-import { useUserStore } from '@/stores'
-
-const { formData, onSubmit, sign } = useDoWithdraw()
-const { configs } = useDoCusBankExtendConfigs(3)
-/// 资金账户信息
-const { fund } = useAccountFundInfo()
-const { router } = useNavigation()
-const formRef = shallowRef<FormInstance>()
-const { getSystemParamValue } = useUserStore()
-const start = getSystemParamValue('012')
-const end = getSystemParamValue('013')
-const msg = getSystemParamValue('302')
-const userStore = useUserStore()
-/// 查询托管银行信息
-const { cusBank } = useQueryCusBankSignBank()
-
-// 表单验证规则
-const formRules: { [key in keyof Proto.t2bBankWithdrawReq]?: FieldRule[] } = {
-    Amount: [{
-        required: true,
-        message: '请输入出金金额',
-        validator: (val) => {
-            if (val <= (fund.value.AvailableOutMoney ?? 0.0)) {
-                return true
-            }
-            return '超过可出金额'
-        }
-    }]
-}
-
-const formSubmit = () => {
-    const obj:{[key:string]:unknown}=Object.create({})
-    configs.value.forEach((e)=>{
-        if(e.value){
-            obj[e.fieldcode]=e.value
-        }
-    })
-    formData.extend_info = JSON.stringify(obj)
-    fullloading((hideLoading) => {
-        onSubmit().then(() => {
-            hideLoading()
-            dialog('出金提交申请成功,请耐心等待审核。').then(() => {
-                router.back()
-            })
-        }).catch(() => {
-            hideLoading('出金失败', 'fail')
-        })
-    })
-}
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 22
src/packages/gstj/views/bank/wallet/components/withdraw/index.less

@@ -1,22 +0,0 @@
-.bank-wallet-withdraw {
-    .form-field {
-        .van-field__control {
-            display: flex;
-            flex-direction: column;
-            align-items: flex-start;
-        }
-
-        &__tips {
-            font-size: .24rem;
-        }
-    }
-
-    .g-form__bank {
-        padding: 16px;
-    }
-
-    .g-form__time {
-        color: #999;
-        padding-left: 15px;
-    }
-}

+ 2 - 2
src/packages/gstj/views/boot/Index.vue

@@ -1,8 +1,8 @@
 <template>
-  <div class="boot">
+  <div class="boot" :style="`background-image: url(${'./app/splashscreen/1080x1920.png'});`">
     <Swipe class="boot__guide" :loop="false" v-if="state.showGuide">
       <SwipeItem>
-        <img src="../../assets/images/boot-1080p.png" />
+        <img :src="'./app/splashscreen/1080x1920.png'" />
       </SwipeItem>
       <SwipeItem>
         <img src="../../assets/images/guide-1.png" />

+ 3 - 1
src/packages/gstj/views/boot/index.less

@@ -1,6 +1,8 @@
 .boot {
     height: 100vh;
-    background: #fff url('../../assets/images/boot-1080p.png') no-repeat center top;
+    background-color: #fff;
+    background-repeat: no-repeat;
+    background-position: center top;
     background-size: cover;
     overflow: hidden;
 

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini