xiongzhu il y a 3 ans
Parent
commit
97640f050f

+ 1 - 0
jsconfig.json

@@ -0,0 +1 @@
+{}

+ 2 - 0
package.json

@@ -9,6 +9,7 @@
     "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
     "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
   },
   },
   "dependencies": {
   "dependencies": {
+    "@chenfengyuan/vue-qrcode": "2",
     "@ionic/vue": "^6.3.8",
     "@ionic/vue": "^6.3.8",
     "@ionic/vue-router": "^6.3.8",
     "@ionic/vue-router": "^6.3.8",
     "@vant/area-data": "^1.3.2",
     "@vant/area-data": "^1.3.2",
@@ -21,6 +22,7 @@
     "less-loader": "^11.1.0",
     "less-loader": "^11.1.0",
     "normalize.css": "^8.0.1",
     "normalize.css": "^8.0.1",
     "pinia": "^2.0.26",
     "pinia": "^2.0.26",
+    "qrcode": "1",
     "qs": "^6.11.0",
     "qs": "^6.11.0",
     "swiper": "^8.4.5",
     "swiper": "^8.4.5",
     "vant": "^3.2.3",
     "vant": "^3.2.3",

+ 4 - 4
src/components/CommissionItem.vue

@@ -5,7 +5,7 @@
                 <img src="../assets/bg.png" />
                 <img src="../assets/bg.png" />
             </ion-thumbnail>
             </ion-thumbnail>
             <div class="name">吴尧东</div>
             <div class="name">吴尧东</div>
-            <div class="num">佣金:+5.68</div>
+            <div class="num">{{ $t('distribution.commission') }}: +5.68</div>
         </div>
         </div>
         <div class="order">
         <div class="order">
             <ion-thumbnail class="cover">
             <ion-thumbnail class="cover">
@@ -19,12 +19,12 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        <div class="prop">订单编号:2022112052035464</div>
-        <div class="prop">下单时间:2022-11-20 12:10</div>
+        <div class="prop">{{ $t('order.id') }}: 2022112052035464</div>
+        <div class="prop">{{ $t('order.createdAt') }}: 2022-11-20 12:10</div>
     </div>
     </div>
 </template>
 </template>
 <script setup>
 <script setup>
-import { ref, computed, onMounted, defineProps } from 'vue'
+import { ref, computed, onMounted } from 'vue'
 const props = defineProps({
 const props = defineProps({
     commission: {
     commission: {
         type: Object,
         type: Object,

+ 1 - 1
src/components/ProductInfo.vue

@@ -78,7 +78,7 @@ export default defineComponent({
 
 
     .text1 {
     .text1 {
         font-size: 14px;
         font-size: 14px;
-        color: #1b1300;
+        color: var(--ion-color-step-900);
         line-height: 24px;
         line-height: 24px;
         font-weight: bold;
         font-weight: bold;
     }
     }

+ 1 - 1
src/components/Record.vue

@@ -70,7 +70,7 @@ export default {
 
 
 .button {
 .button {
     height: 36px;
     height: 36px;
-    border-color: #fff !important;
+    border-color: var(--ion-color-step-0) !important;
     font-size: 12px;
     font-size: 12px;
     line-height: 36px;
     line-height: 36px;
 
 

+ 71 - 0
src/components/TeamMember.vue

@@ -0,0 +1,71 @@
+<template>
+    <div class="team-member">
+        <ion-thumbnail class="avatar">
+            <img src="../assets/bg.png" />
+        </ion-thumbnail>
+        <div class="info">
+            <div class="name">吴尧东</div>
+            <div class="time">{{ $t('distribution.joinTeamAt') }}: 2022-11-20 1</div>
+        </div>
+        <div class="divider"></div>
+        <div class="profit">
+            <div class="value">+13.5</div>
+            <div class="label">{{ $t('distribution.totalProfit') }}</div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, computed, onMounted } from 'vue'
+const props = defineProps({
+    commission: {
+        type: Object,
+        default: () => {}
+    }
+})
+</script>
+<style lang="less" scoped>
+.team-member {
+    .f();
+    margin: 10px 16px 0 16px;
+    height: 68px;
+    background: var(--ion-color-step-0);
+    border-radius: 2px;
+    padding: 0 15px;
+    .avatar {
+        width: 36px;
+        height: 36px;
+        border-radius: 2px;
+    }
+    .info {
+        .f-col();
+        margin-left: 10px;
+        flex: 1;
+        .name {
+            font-size: 14px;
+            line-height: 20px;
+        }
+        .time {
+            font-size: 12px;
+            color: var(--ion-color-step-600);
+            line-height: 17px;
+        }
+    }
+    .divider {
+        width: 1px;
+        height: 36px;
+        background-color: var(--ion-color-step-50);
+    }
+    .profit {
+        width: 68px;
+        .f-col();
+        align-items: flex-end;
+        font-size: 12px;
+        line-height: 17px;
+        .value {
+            font-size: 12px;
+            line-height: 17px;
+        }
+    }
+}
+</style>

+ 8 - 2
src/locales/zh.json

@@ -3,7 +3,8 @@
     "login": "登录",
     "login": "登录",
     "title": {
     "title": {
         "balanceRecord": "交易明细",
         "balanceRecord": "交易明细",
-        "distribution": "收益中心"
+        "distribution": "收益中心",
+        "myTeam": "我的团队"
     },
     },
     "common": {
     "common": {
         "cancel": "取消",
         "cancel": "取消",
@@ -17,6 +18,7 @@
     },
     },
     "order": {
     "order": {
         "id": "订单编号",
         "id": "订单编号",
+        "createdAt": "下单时间",
         "my": "我的订单",
         "my": "我的订单",
         "detail": "订单详情",
         "detail": "订单详情",
         "payMethod": "支付方式",
         "payMethod": "支付方式",
@@ -100,6 +102,10 @@
         "profitDetails": "收益明细",
         "profitDetails": "收益明细",
         "teamNum": "团队人数",
         "teamNum": "团队人数",
         "viewDetail": "查看明细",
         "viewDetail": "查看明细",
-        "viewTeam": "查看团队"
+        "viewTeam": "查看团队",
+        "commission": "佣金",
+        "totalProfit": "总收益",
+        "orderNum": "订单数",
+        "joinTeamAt": "加入团队时间"
     }
     }
 }
 }

+ 10 - 0
src/router/index.js

@@ -117,6 +117,16 @@ const router = createRouter({
             path: '/distribution',
             path: '/distribution',
             name: 'distribution',
             name: 'distribution',
             component: () => import('@/views/DistributionPage.vue')
             component: () => import('@/views/DistributionPage.vue')
+        },
+        {
+            path: '/commissionList',
+            name: 'commissionList',
+            component: () => import('@/views/CommissionListPage.vue')
+        },
+        {
+            path: '/myTeam',
+            name: 'myTeam',
+            component: () => import('@/views/MyTeamPage.vue')
         }
         }
     ]
     ]
 })
 })

+ 12 - 4
src/styles/main.less

@@ -1,5 +1,4 @@
 :root {
 :root {
-    --bg2: #f5f7fa;
     --van-primary-color: #2d2d2d;
     --van-primary-color: #2d2d2d;
     --van-tabbar-item-icon-margin-bottom: 2px;
     --van-tabbar-item-icon-margin-bottom: 2px;
     --van-dialog-confirm-button-text-color: #a108ff;
     --van-dialog-confirm-button-text-color: #a108ff;
@@ -14,9 +13,6 @@
     --van-empty-description-color: #8c7af8;
     --van-empty-description-color: #8c7af8;
     --van-empty-description-margin-top: 16px;
     --van-empty-description-margin-top: 16px;
 }
 }
-ion-back-button {
-    --color: var(--van-primary-color);
-}
 
 
 ion-content {
 ion-content {
     &::-webkit-scrollbar {
     &::-webkit-scrollbar {
@@ -37,6 +33,12 @@ ion-toast.error-toast {
 ion-toolbar {
 ion-toolbar {
     --border-style: none;
     --border-style: none;
     --background: var(--ion-color-step-0);
     --background: var(--ion-color-step-0);
+    ion-back-button {
+        --color: var(--ion-color-step-900);
+    }
+    ion-button {
+        --color: var(--ion-color-step-900);
+    }
 }
 }
 ion-refresher {
 ion-refresher {
     --color: var(--ion-color-step-400);
     --color: var(--ion-color-step-400);
@@ -44,6 +46,12 @@ ion-refresher {
 ion-button {
 ion-button {
     --border-radius: 4px;
     --border-radius: 4px;
 }
 }
+ion-modal.dialog {
+    --width: fit-content;
+    --height: fit-content;
+    --border-radius: 6px;
+    --box-shadow: 0 2px 6px rgba(var(--ion-color-light-contrast-rgb), 0.05);
+}
 .refresher-pulling-icon {
 .refresher-pulling-icon {
     color: var(--ion-color-step-400) !important;
     color: var(--ion-color-step-400) !important;
 }
 }

+ 183 - 0
src/views/CommissionListPage.vue

@@ -0,0 +1,183 @@
+<template>
+    <ion-page>
+        <ion-header>
+            <ion-toolbar>
+                <ion-buttons slot="start">
+                    <ion-back-button default-href="#" @click="$router.back()"></ion-back-button>
+                </ion-buttons>
+                <ion-title>{{ $t('title.balanceRecord') }}</ion-title>
+            </ion-toolbar>
+        </ion-header>
+        <ion-content>
+            <ion-refresher slot="fixed" @ionRefresh="refresh">
+                <ion-refresher-content></ion-refresher-content>
+            </ion-refresher>
+            <ion-item class="header" sticky>
+                <div class="date" @click="showPicker = true">
+                    {{ yearMonth }}
+                    <ion-icon :icon="caretDownOutline"></ion-icon>
+                </div>
+                <div class="total">
+                    {{ $t('distribution.totalProfit') }}{{ $t('balance.symbol') }}123&nbsp;&nbsp;
+                    {{ $t('distribution.orderNum') }}123
+                </div>
+            </ion-item>
+            <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="loadmore">
+                <CommissionItem v-for="item in records" :key="item.id"></CommissionItem>
+                <van-empty v-if="finished && records.length === 0"></van-empty>
+            </van-list>
+        </ion-content>
+        <ion-modal id="picker" :is-open="showPicker" @didDismiss="showPicker = false">
+            <ion-datetime
+                v-model="date"
+                presentation="month-year"
+                :cancel-text="$t('common.cancel')"
+                :done-text="$t('common.confirm')"
+                :show-default-buttons="true"
+                @ionChange="confirmPicker"
+            ></ion-datetime>
+        </ion-modal>
+    </ion-page>
+</template>
+<script>
+import balanceIcon from '@/assets/icon_balance.svg'
+import { caretDownOutline } from 'ionicons/icons'
+import { format, formatISO, parseISO, startOfMonth, endOfMonth } from 'date-fns'
+import CommissionItem from '../components/CommissionItem.vue'
+export default {
+    components: { CommissionItem },
+    data() {
+        return {
+            page: 0,
+            refreshing: true,
+            loading: false,
+            finished: false,
+            records: [],
+            balanceIcon,
+            caretDownOutline,
+            showPicker: false,
+            date: formatISO(new Date())
+        }
+    },
+    created() {
+        this.getData()
+    },
+    computed: {
+        yearMonth() {
+            return format(parseISO(this.date, new Date()), 'yyyy MMM')
+        },
+        totalWithDraw() {
+            return -this.records.filter(i => i.remark === 'balance.record.withdraw').reduce((a, b) => a + b.amount, 0)
+        }
+    },
+    methods: {
+        refresh(event) {
+            this.loading = true
+            this.page = 0
+            this.finished = false
+            this.getData(event)
+        },
+        loadmore() {
+            this.page++
+            this.getData()
+        },
+        getData(e) {
+            const date = parseISO(this.date, new Date())
+            return this.$http
+                .get('/user/balanceRecord', {
+                    page: this.page,
+                    size: 10000,
+                    start: format(startOfMonth(date), 'yyyy-MM-dd HH:mm:ss'),
+                    end: format(endOfMonth(date), 'yyyy-MM-dd HH:mm:ss')
+                })
+                .then(res => {
+                    if (res.number === 0) {
+                        this.records = []
+                    }
+                    this.records = this.records.concat(res.content)
+                    this.refreshing = false
+                    this.loading = false
+                    this.finished = res.last
+                    if (e) {
+                        e.target.complete()
+                    }
+                })
+        },
+        confirmPicker(e) {
+            this.date = e.detail.value
+            this.getData()
+        }
+    }
+}
+</script>
+<style lang="less" scoped>
+.header {
+    --border-style: none;
+    .date {
+        width: 104px;
+        height: 32px;
+        background: var(--ion-color-step-0);
+        border-radius: 4px;
+        font-size: 12px;
+        .f();
+        justify-content: center;
+        ion-icon {
+            margin-left: 6px;
+        }
+    }
+    .total {
+        flex-grow: 1;
+        text-align: right;
+        font-size: 12px;
+        color: var(--ion-color-step-400);
+        padding-right: 6px;
+    }
+}
+.record-item {
+    --background: var(--ion-color-step-0);
+    --border-color: var(--ion-color-step-100);
+    ion-icon {
+        width: 32px;
+        height: 32px;
+    }
+    ion-label {
+        margin-left: 10px;
+    }
+    .amount {
+        font-weight: bold;
+    }
+    ion-icon {
+        fill: #59b12c;
+    }
+    &.recharge,
+    &.receipt {
+        ion-icon {
+            fill: #477bff;
+        }
+        .amount {
+            color: #477bff;
+        }
+    }
+    &.withdraw {
+        h3 {
+            color: #ff7f1f;
+        }
+        ion-icon {
+            fill: #ff7f1f;
+        }
+        .amount {
+            color: #ff7f1f;
+        }
+    }
+}
+ion-modal#picker {
+    --width: fit-content;
+    --min-width: calc(100vw - 80px);
+    --height: fit-content;
+    --border-radius: 6px;
+    --box-shadow: 0 28px 48px rgba(var(--ion-color-light-contrast-rgb), 0.4);
+}
+ion-datetime {
+    color: var(--ion-text-color);
+}
+</style>

+ 1 - 1
src/views/CommissionPage.vue

@@ -87,7 +87,7 @@ export default {
     flex-direction: column;
     flex-direction: column;
     align-items: center;
     align-items: center;
     justify-content: center;
     justify-content: center;
-    color: #fff;
+    color: var(--ion-color-step-0);
     font-size: 12px;
     font-size: 12px;
     line-height: 17px;
     line-height: 17px;
 
 

+ 21 - 5
src/views/DistributionPage.vue

@@ -12,7 +12,7 @@
             <div class="head">
             <div class="head">
                 <div class="title">{{ $t('title.distribution') }}</div>
                 <div class="title">{{ $t('title.distribution') }}</div>
                 <div class="desc">{{ $t('distribution.myInvitor') }}:</div>
                 <div class="desc">{{ $t('distribution.myInvitor') }}:</div>
-                <div class="qr-wrapper">
+                <div class="qr-wrapper" @click="showQR = true">
                     <img src="@/assets/icon_qr.png" class="qr" />
                     <img src="@/assets/icon_qr.png" class="qr" />
                     <div class="desc">
                     <div class="desc">
                         <span class="text">{{ $t('distribution.qrCode') }}</span>
                         <span class="text">{{ $t('distribution.qrCode') }}</span>
@@ -28,7 +28,9 @@
                                 123<span class="unit">{{ $t('balance.unit') }}</span>
                                 123<span class="unit">{{ $t('balance.unit') }}</span>
                             </div>
                             </div>
                             <div class="title">{{ $t('distribution.myProfit') }}</div>
                             <div class="title">{{ $t('distribution.myProfit') }}</div>
-                            <div class="btn-detail">{{ $t('distribution.viewDetail') }}</div>
+                            <div class="btn-detail" @click="$router.push({ name: 'commissionList' })">
+                                {{ $t('distribution.viewDetail') }}
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div class="divider"></div>
                     <div class="divider"></div>
@@ -36,7 +38,9 @@
                         <div class="content">
                         <div class="content">
                             <div class="value">123</div>
                             <div class="value">123</div>
                             <div class="title">{{ $t('distribution.teamNum') }}</div>
                             <div class="title">{{ $t('distribution.teamNum') }}</div>
-                            <div class="btn-team">{{ $t('distribution.viewTeam') }}</div>
+                            <div class="btn-team" @click="$router.push({ name: 'myTeam' })">
+                                {{ $t('distribution.viewTeam') }}
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
@@ -49,6 +53,11 @@
                 </div>
                 </div>
             </div>
             </div>
             <CommissionItem></CommissionItem>
             <CommissionItem></CommissionItem>
+            <ion-modal class="qr-modal dialog" :is-open="showQR" @didDismiss="showQR = false">
+                <ion-content>
+                    <vue-qrcode value="Hello, World!" :options="{ width: 250, margin: 2 }"></vue-qrcode>
+                </ion-content>
+            </ion-modal>
         </ion-content>
         </ion-content>
     </ion-page>
     </ion-page>
 </template>
 </template>
@@ -57,9 +66,11 @@ import { mapState } from 'pinia'
 import { useUserStore } from '@/stores/user'
 import { useUserStore } from '@/stores/user'
 import { caretForwardCircleOutline, chevronForwardOutline } from 'ionicons/icons'
 import { caretForwardCircleOutline, chevronForwardOutline } from 'ionicons/icons'
 import CommissionItem from '@/components/CommissionItem.vue'
 import CommissionItem from '@/components/CommissionItem.vue'
+import VueQrcode from '@chenfengyuan/vue-qrcode'
 export default {
 export default {
     components: {
     components: {
-        CommissionItem
+        CommissionItem,
+        VueQrcode
     },
     },
     data() {
     data() {
         return {
         return {
@@ -67,7 +78,8 @@ export default {
             show: false,
             show: false,
             url: '',
             url: '',
             caretForwardCircleOutline,
             caretForwardCircleOutline,
-            chevronForwardOutline
+            chevronForwardOutline,
+            showQR: false
         }
         }
     },
     },
     computed: {
     computed: {
@@ -230,4 +242,8 @@ export default {
         font-size: 12px;
         font-size: 12px;
     }
     }
 }
 }
+.qr-modal {
+    --width: 250px;
+    --height: 250px;
+}
 </style>
 </style>

+ 33 - 45
src/views/HomePage.vue

@@ -47,7 +47,7 @@
             <!-- 通知 -->
             <!-- 通知 -->
             <van-notice-bar
             <van-notice-bar
                 left-icon="volume-o"
                 left-icon="volume-o"
-                background="#fff"
+                background="var(--ion-color-step-0)"
                 color="#000"
                 color="#000"
                 text="
                 text="
                     无论我们能活多久,我们能够享受的只有无法分割的此刻,此外别无其他。
                     无论我们能活多久,我们能够享受的只有无法分割的此刻,此外别无其他。
@@ -136,8 +136,6 @@ import { Swiper, SwiperSlide } from 'swiper/vue'
 import 'swiper/swiper.min.css'
 import 'swiper/swiper.min.css'
 import 'swiper/swiper-bundle.min.css'
 import 'swiper/swiper-bundle.min.css'
 import SwiperCore, { Pagination, Autoplay, Parallax, Controller } from 'swiper'
 import SwiperCore, { Pagination, Autoplay, Parallax, Controller } from 'swiper'
-
-import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonButton } from '@ionic/vue'
 import { useRouter } from 'vue-router'
 import { useRouter } from 'vue-router'
 import { ref, getCurrentInstance, onMounted } from 'vue'
 import { ref, getCurrentInstance, onMounted } from 'vue'
 
 
@@ -147,18 +145,14 @@ import secondImg from '../assets/bg2.png'
 
 
 import productInfo from '../components/ProductInfo.vue'
 import productInfo from '../components/ProductInfo.vue'
 import { isAfter, isBefore, parse, getYear, getMonth, getDate } from 'date-fns'
 import { isAfter, isBefore, parse, getYear, getMonth, getDate } from 'date-fns'
+import { http } from '@/plugins/http'
+import toast from '@/utils/toast'
 
 
 const router = useRouter()
 const router = useRouter()
 function navigate() {
 function navigate() {
     router.push({ name: 'login' })
     router.push({ name: 'login' })
 }
 }
 
 
-const {
-    appContext: {
-        config: { globalProperties: global }
-    }
-} = getCurrentInstance()
-
 SwiperCore.use([Pagination, Autoplay, Parallax, Controller])
 SwiperCore.use([Pagination, Autoplay, Parallax, Controller])
 const firstSwiper = ref(null)
 const firstSwiper = ref(null)
 const secondSwiper = ref(null)
 const secondSwiper = ref(null)
@@ -171,7 +165,7 @@ const setSecondSwiper = swiper => {
 
 
 const topBanners = ref([])
 const topBanners = ref([])
 function getBanner() {
 function getBanner() {
-    return global.$http.post('/banner/all', {}, { body: 'json' }).then(res => {
+    return http.post('/banner/all', {}, { body: 'json' }).then(res => {
         topBanners.value = res.content.filter(item => {
         topBanners.value = res.content.filter(item => {
             return item.type === 'TOP'
             return item.type === 'TOP'
         })
         })
@@ -181,28 +175,26 @@ function getBanner() {
 const saleBatchs = ref([])
 const saleBatchs = ref([])
 const hotInfo = ref({})
 const hotInfo = ref({})
 function getSaleBatch() {
 function getSaleBatch() {
-    return global.$http.post('saleBatch/all', {}, { body: 'json' }).then(res => {
+    return http.post('saleBatch/all', {}, { body: 'json' }).then(res => {
         saleBatchs.value = res.content
         saleBatchs.value = res.content
         if (!res.empty) {
         if (!res.empty) {
-            global.$http
-                .post(
-                    'product/all',
-                    {
-                        query: {
-                            batchId: res.content[0].id,
-                            status: 'IN_STOCK',
-                            enabled: true
-                        },
-                        size: 1,
-                        sort: 'id,desc'
+            http.post(
+                'product/all',
+                {
+                    query: {
+                        batchId: res.content[0].id,
+                        status: 'IN_STOCK',
+                        enabled: true
                     },
                     },
-                    { body: 'json' }
-                )
-                .then(res => {
-                    if (!res.empty) {
-                        hotInfo.value = res.content[0]
-                    }
-                })
+                    size: 1,
+                    sort: 'id,desc'
+                },
+                { body: 'json' }
+            ).then(res => {
+                if (!res.empty) {
+                    hotInfo.value = res.content[0]
+                }
+            })
         }
         }
     })
     })
 }
 }
@@ -217,13 +209,13 @@ const goList = id => {
 }
 }
 
 
 onMounted(() => {
 onMounted(() => {
-    global.$toast.loading({
-        message: '加载中...',
-        forbidClick: true
-    })
+    // toast.loading({
+    //     message: '加载中...',
+    //     forbidClick: true
+    // })
     Promise.all([getBanner(), getSaleBatch()]).then(() => {
     Promise.all([getBanner(), getSaleBatch()]).then(() => {
-        console.log(global.$toast)
-        global.$toast.dismiss()
+        console.log(toast)
+        toast.dismiss()
     })
     })
 })
 })
 
 
@@ -244,10 +236,6 @@ const getStatus = info => {
 </script>
 </script>
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>
-.home {
-    --ion-background-color: var(--bg2);
-}
-
 .swiper-content {
 .swiper-content {
     padding-bottom: 6.4vw;
     padding-bottom: 6.4vw;
 }
 }
@@ -258,8 +246,8 @@ const getStatus = info => {
     background: #112982 linear-gradient(135deg, #d700ff 0%, #3e22ff 100%);
     background: #112982 linear-gradient(135deg, #d700ff 0%, #3e22ff 100%);
     box-shadow: 0px 0px 6px 0px #4a65ff;
     box-shadow: 0px 0px 6px 0px #4a65ff;
     border-radius: 2px;
     border-radius: 2px;
-    --swiper-theme-color: #fff;
-    --swiper-pagination-color: #fff;
+    --swiper-theme-color: var(--ion-color-step-0);
+    --swiper-pagination-color: var(--ion-color-step-0);
     position: absolute;
     position: absolute;
     top: 40vw;
     top: 40vw;
     left: 5.5vw;
     left: 5.5vw;
@@ -285,7 +273,7 @@ const getStatus = info => {
     }
     }
 
 
     :deep(.swiper-pagination-bullet) {
     :deep(.swiper-pagination-bullet) {
-        background-color: #fff;
+        background-color: var(--ion-color-step-0);
         width: 18px;
         width: 18px;
         height: 2px;
         height: 2px;
         border-radius: 2px;
         border-radius: 2px;
@@ -313,9 +301,9 @@ const getStatus = info => {
 }
 }
 
 
 :deep(.van-cell) {
 :deep(.van-cell) {
-    --van-cell-background-color: var(--bg2);
+    --van-cell-background-color: var(--ion-background-color);
     --van-cell-horizontal-padding: 20px;
     --van-cell-horizontal-padding: 20px;
-    background: var(--bg2);
+    --van-cell-text-color: var(--ion-color-step-800);
     .f();
     .f();
     .van-cell__title {
     .van-cell__title {
         font-size: 16px;
         font-size: 16px;
@@ -381,7 +369,7 @@ const getStatus = info => {
         .f();
         .f();
         justify-content: center;
         justify-content: center;
         height: 58px;
         height: 58px;
-        background: #efefef;
+        background: var(--ion-color-step-100);
         border-radius: 4px;
         border-radius: 4px;
         img {
         img {
             width: 22px;
             width: 22px;

+ 1 - 1
src/views/LoginPage.vue

@@ -181,7 +181,7 @@ ion-back-button {
 
 
     :deep(.van-checkbox__icon--checked .van-icon) {
     :deep(.van-checkbox__icon--checked .van-icon) {
         background: linear-gradient(135deg, #a108ff 0%, #5c7cff 100%);
         background: linear-gradient(135deg, #a108ff 0%, #5c7cff 100%);
-        border-color: #fff;
+        border-color: var(--ion-color-step-0);
     }
     }
 }
 }
 
 

+ 1 - 1
src/views/LoginPhonePage.vue

@@ -200,7 +200,7 @@ ion-back-button {
 
 
     :deep(.van-checkbox__icon--checked .van-icon) {
     :deep(.van-checkbox__icon--checked .van-icon) {
         background: linear-gradient(135deg, #a108ff 0%, #5c7cff 100%);
         background: linear-gradient(135deg, #a108ff 0%, #5c7cff 100%);
-        border-color: #fff;
+        border-color: var(--ion-color-step-0);
     }
     }
 }
 }
 
 

+ 2 - 2
src/views/MinePage.vue

@@ -128,7 +128,7 @@ const goSetting = () => {
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>
 .mine {
 .mine {
-    --ion-background-color: #fff;
+    --ion-background-color: var(--ion-color-step-0);
 }
 }
 .userInfo-bg {
 .userInfo-bg {
     position: absolute;
     position: absolute;
@@ -195,7 +195,7 @@ const goSetting = () => {
 
 
     .card-content {
     .card-content {
         margin-top: 8px;
         margin-top: 8px;
-        --van-grid-item-content-background: #fff8fc;
+        --van-grid-item-content-background: var(--ion-color-step-0)8fc;
         border-radius: 4px;
         border-radius: 4px;
         overflow: hidden;
         overflow: hidden;
     }
     }

+ 21 - 0
src/views/MyTeamPage.vue

@@ -0,0 +1,21 @@
+<template>
+    <ion-page>
+        <ion-header>
+            <ion-toolbar>
+                <ion-buttons slot="start">
+                    <ion-back-button default-href="#" @click="$router.back()"></ion-back-button>
+                </ion-buttons>
+                <ion-title>{{ $t('title.myTeam') }}</ion-title>
+            </ion-toolbar>
+        </ion-header>
+        <ion-content>
+            <TeamMember v-for="n in 20" :key="n"></TeamMember>
+        </ion-content>
+    </ion-page>
+</template>
+
+<script setup>
+import TeamMember from '../components/TeamMember.vue'
+</script>
+
+<style lang="less" scoped></style>

+ 4 - 2
src/views/ProductListPage.vue

@@ -6,8 +6,10 @@
                     <ion-back-button default-href="#" text="" @click="$router.back()"></ion-back-button>
                     <ion-back-button default-href="#" text="" @click="$router.back()"></ion-back-button>
                 </ion-buttons>
                 </ion-buttons>
                 <ion-title>{{ batchInfo.name }}</ion-title>
                 <ion-title>{{ batchInfo.name }}</ion-title>
-                <ion-buttons slot="end" @click="$router.push({ name: 'productSearch', query: { batchId } })">
-                    <ion-icon slot="icon-only" :icon="searchOutline"></ion-icon>
+                <ion-buttons slot="end">
+                    <ion-button @click="$router.push({ name: 'productSearch', query: { batchId } })">
+                        <ion-icon slot="icon-only" :icon="searchOutline"></ion-icon>
+                    </ion-button>
                 </ion-buttons>
                 </ion-buttons>
             </ion-toolbar>
             </ion-toolbar>
         </ion-header>
         </ion-header>

+ 1 - 1
src/views/RegisterPage.vue

@@ -252,7 +252,7 @@ ion-back-button {
 
 
     :deep(.van-checkbox__icon--checked .van-icon) {
     :deep(.van-checkbox__icon--checked .van-icon) {
         background: linear-gradient(135deg, #a108ff 0%, #5c7cff 100%);
         background: linear-gradient(135deg, #a108ff 0%, #5c7cff 100%);
-        border-color: #fff;
+        border-color: var(--ion-color-step-0);
     }
     }
 }
 }
 
 

+ 3 - 6
src/views/WalletPage.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-    <ion-page class="wallet-page">
+    <ion-page>
         <ion-header>
         <ion-header>
             <ion-toolbar>
             <ion-toolbar>
                 <ion-buttons slot="start">
                 <ion-buttons slot="start">
@@ -8,7 +8,7 @@
                 <ion-title>{{ $t('user.wallet') }}</ion-title>
                 <ion-title>{{ $t('user.wallet') }}</ion-title>
             </ion-toolbar>
             </ion-toolbar>
         </ion-header>
         </ion-header>
-        <ion-content :fullscreen="true" class="wallet-page">
+        <ion-content class="wallet-page">
             <div class="head">
             <div class="head">
                 <div class="balance">
                 <div class="balance">
                     <span class="sym">{{ $t('balance.symbol') }}</span
                     <span class="sym">{{ $t('balance.symbol') }}</span
@@ -199,7 +199,6 @@ export default {
     --ion-color-primary: #477bff;
     --ion-color-primary: #477bff;
 }
 }
 .wallet-page {
 .wallet-page {
-    background-color: white;
     display: flex;
     display: flex;
     flex-direction: column;
     flex-direction: column;
     .head {
     .head {
@@ -307,9 +306,6 @@ export default {
         }
         }
     }
     }
 }
 }
-:deep(ion-footer ion-toolbar) {
-    --background: var(--ion-color-step-0);
-}
 .bottom-buttons {
 .bottom-buttons {
     padding: 0 16px;
     padding: 0 16px;
     .f();
     .f();
@@ -334,6 +330,7 @@ ion-button.btn-recharge {
     height: 38px;
     height: 38px;
     margin-left: 20px;
     margin-left: 20px;
     --border-radius: 4px;
     --border-radius: 4px;
+    --color: var(--ion-color-step-0);
 }
 }
 ion-modal#modal-withdraw {
 ion-modal#modal-withdraw {
     --ion-color-primary: #477bff;
     --ion-color-primary: #477bff;

+ 164 - 3
yarn.lock

@@ -7,6 +7,11 @@
   resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8"
   resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8"
   integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==
   integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==
 
 
+"@chenfengyuan/vue-qrcode@2":
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/@chenfengyuan/vue-qrcode/-/vue-qrcode-2.0.0.tgz#8cd01f6fc528d471680ebe812ec47c830aea7e63"
+  integrity sha512-33Cfr0zjbc3Dd8d5b1IgzXRAgXH0c2Gv19VI4snS25V/x9Z41eg769tC+Us1x+vqgQQhgD5YUjLnkpkrQfeMSw==
+
 "@esbuild/android-arm@0.15.16":
 "@esbuild/android-arm@0.15.16":
   version "0.15.16"
   version "0.15.16"
   resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.15.16.tgz#0642926178b15e3d1545efae6eee05c4f3451d15"
   resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.15.16.tgz#0642926178b15e3d1545efae6eee05c4f3451d15"
@@ -431,7 +436,7 @@ ansi-styles@^2.2.1:
   resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
   resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
   integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==
   integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==
 
 
-ansi-styles@^4.1.0:
+ansi-styles@^4.0.0, ansi-styles@^4.1.0:
   version "4.3.0"
   version "4.3.0"
   resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
   resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
   integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
   integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
@@ -635,6 +640,11 @@ camelcase@^2.0.0:
   resolved "https://registry.npmmirror.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
   resolved "https://registry.npmmirror.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
   integrity sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==
   integrity sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==
 
 
+camelcase@^5.0.0:
+  version "5.3.1"
+  resolved "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
+  integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+
 caw@^2.0.0, caw@^2.0.1:
 caw@^2.0.0, caw@^2.0.1:
   version "2.0.1"
   version "2.0.1"
   resolved "https://registry.npmmirror.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95"
   resolved "https://registry.npmmirror.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95"
@@ -664,6 +674,15 @@ chalk@^4.0.0, chalk@^4.1.2:
     ansi-styles "^4.1.0"
     ansi-styles "^4.1.0"
     supports-color "^7.1.0"
     supports-color "^7.1.0"
 
 
+cliui@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
+  integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
+  dependencies:
+    string-width "^4.2.0"
+    strip-ansi "^6.0.0"
+    wrap-ansi "^6.2.0"
+
 clone-response@1.0.2:
 clone-response@1.0.2:
   version "1.0.2"
   version "1.0.2"
   resolved "https://registry.npmmirror.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
   resolved "https://registry.npmmirror.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
@@ -842,7 +861,7 @@ debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
   dependencies:
   dependencies:
     ms "2.1.2"
     ms "2.1.2"
 
 
-decamelize@^1.1.2:
+decamelize@^1.1.2, decamelize@^1.2.0:
   version "1.2.0"
   version "1.2.0"
   resolved "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
   resolved "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
   integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
   integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
@@ -922,6 +941,11 @@ delayed-stream@~1.0.0:
   resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
   resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
   integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
   integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
 
 
+dijkstrajs@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.2.tgz#2e48c0d3b825462afe75ab4ad5e829c8ece36257"
+  integrity sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==
+
 dir-glob@^3.0.1:
 dir-glob@^3.0.1:
   version "3.0.1"
   version "3.0.1"
   resolved "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
   resolved "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@@ -1013,6 +1037,16 @@ duplexer3@^0.1.4:
   resolved "https://registry.npmmirror.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
   resolved "https://registry.npmmirror.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
   integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==
   integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==
 
 
+emoji-regex@^8.0.0:
+  version "8.0.0"
+  resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+  integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
+encode-utf8@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.npmmirror.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda"
+  integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==
+
 end-of-stream@^1.0.0, end-of-stream@^1.1.0:
 end-of-stream@^1.0.0, end-of-stream@^1.1.0:
   version "1.4.4"
   version "1.4.4"
   resolved "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
   resolved "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
@@ -1662,6 +1696,14 @@ find-up@^1.0.0:
     path-exists "^2.0.0"
     path-exists "^2.0.0"
     pinkie-promise "^2.0.0"
     pinkie-promise "^2.0.0"
 
 
+find-up@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
+  integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
+  dependencies:
+    locate-path "^5.0.0"
+    path-exists "^4.0.0"
+
 find-up@^5.0.0:
 find-up@^5.0.0:
   version "5.0.0"
   version "5.0.0"
   resolved "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
   resolved "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
@@ -1741,6 +1783,11 @@ function-bind@^1.1.1:
   resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
   resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
   integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
   integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
 
 
+get-caller-file@^2.0.1:
+  version "2.0.5"
+  resolved "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
+  integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+
 get-intrinsic@^1.0.2:
 get-intrinsic@^1.0.2:
   version "1.1.3"
   version "1.1.3"
   resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
   resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
@@ -2155,6 +2202,11 @@ is-finite@^1.0.0:
   resolved "https://registry.npmmirror.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3"
   resolved "https://registry.npmmirror.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3"
   integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==
   integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==
 
 
+is-fullwidth-code-point@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+  integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+
 is-gif@^3.0.0:
 is-gif@^3.0.0:
   version "3.0.0"
   version "3.0.0"
   resolved "https://registry.npmmirror.com/is-gif/-/is-gif-3.0.0.tgz#c4be60b26a301d695bb833b20d9b5d66c6cf83b1"
   resolved "https://registry.npmmirror.com/is-gif/-/is-gif-3.0.0.tgz#c4be60b26a301d695bb833b20d9b5d66c6cf83b1"
@@ -2367,6 +2419,13 @@ load-json-file@^1.0.0:
     pinkie-promise "^2.0.0"
     pinkie-promise "^2.0.0"
     strip-bom "^2.0.0"
     strip-bom "^2.0.0"
 
 
+locate-path@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
+  integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
+  dependencies:
+    p-locate "^4.1.0"
+
 locate-path@^6.0.0:
 locate-path@^6.0.0:
   version "6.0.0"
   version "6.0.0"
   resolved "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
   resolved "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
@@ -2739,6 +2798,13 @@ p-is-promise@^1.1.0:
   resolved "https://registry.npmmirror.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
   resolved "https://registry.npmmirror.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
   integrity sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==
   integrity sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==
 
 
+p-limit@^2.2.0:
+  version "2.3.0"
+  resolved "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
+  integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
+  dependencies:
+    p-try "^2.0.0"
+
 p-limit@^3.0.2:
 p-limit@^3.0.2:
   version "3.1.0"
   version "3.1.0"
   resolved "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
   resolved "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
@@ -2746,6 +2812,13 @@ p-limit@^3.0.2:
   dependencies:
   dependencies:
     yocto-queue "^0.1.0"
     yocto-queue "^0.1.0"
 
 
+p-locate@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
+  integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
+  dependencies:
+    p-limit "^2.2.0"
+
 p-locate@^5.0.0:
 p-locate@^5.0.0:
   version "5.0.0"
   version "5.0.0"
   resolved "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
   resolved "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
@@ -2784,6 +2857,11 @@ p-timeout@^2.0.1:
   dependencies:
   dependencies:
     p-finally "^1.0.0"
     p-finally "^1.0.0"
 
 
+p-try@^2.0.0:
+  version "2.2.0"
+  resolved "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
+  integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+
 parent-module@^1.0.0:
 parent-module@^1.0.0:
   version "1.0.1"
   version "1.0.1"
   resolved "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
   resolved "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@@ -2904,6 +2982,11 @@ pinkie@^2.0.0:
   resolved "https://registry.npmmirror.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
   resolved "https://registry.npmmirror.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
   integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==
   integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==
 
 
+pngjs@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
+  integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==
+
 pngquant-bin@^6.0.0:
 pngquant-bin@^6.0.0:
   version "6.0.1"
   version "6.0.1"
   resolved "https://registry.npmmirror.com/pngquant-bin/-/pngquant-bin-6.0.1.tgz#2b5789ca219eeb4d8509ab1ae082092801b7f07e"
   resolved "https://registry.npmmirror.com/pngquant-bin/-/pngquant-bin-6.0.1.tgz#2b5789ca219eeb4d8509ab1ae082092801b7f07e"
@@ -2995,6 +3078,16 @@ punycode@^2.1.0:
   resolved "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
   resolved "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
   integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
   integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
 
 
+qrcode@1:
+  version "1.5.1"
+  resolved "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.1.tgz#0103f97317409f7bc91772ef30793a54cd59f0cb"
+  integrity sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg==
+  dependencies:
+    dijkstrajs "^1.0.1"
+    encode-utf8 "^1.0.3"
+    pngjs "^5.0.0"
+    yargs "^15.3.1"
+
 qs@^6.11.0:
 qs@^6.11.0:
   version "6.11.0"
   version "6.11.0"
   resolved "https://registry.npmmirror.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
   resolved "https://registry.npmmirror.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
@@ -3071,6 +3164,16 @@ replace-ext@^1.0.0:
   resolved "https://registry.npmmirror.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a"
   resolved "https://registry.npmmirror.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a"
   integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==
   integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==
 
 
+require-directory@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+  integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
+
+require-main-filename@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
+  integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
+
 resolve-from@^4.0.0:
 resolve-from@^4.0.0:
   version "4.0.0"
   version "4.0.0"
   resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
   resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
@@ -3181,6 +3284,11 @@ semver@^7.3.5, semver@^7.3.6:
   dependencies:
   dependencies:
     lru-cache "^6.0.0"
     lru-cache "^6.0.0"
 
 
+set-blocking@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+  integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
+
 shebang-command@^1.2.0:
 shebang-command@^1.2.0:
   version "1.2.0"
   version "1.2.0"
   resolved "https://registry.npmmirror.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
   resolved "https://registry.npmmirror.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
@@ -3310,6 +3418,15 @@ strict-uri-encode@^1.0.0:
   resolved "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
   resolved "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
   integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==
   integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==
 
 
+string-width@^4.1.0, string-width@^4.2.0:
+  version "4.2.3"
+  resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+  dependencies:
+    emoji-regex "^8.0.0"
+    is-fullwidth-code-point "^3.0.0"
+    strip-ansi "^6.0.1"
+
 string_decoder@~1.1.1:
 string_decoder@~1.1.1:
   version "1.1.1"
   version "1.1.1"
   resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
   resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
@@ -3324,7 +3441,7 @@ strip-ansi@^3.0.0:
   dependencies:
   dependencies:
     ansi-regex "^2.0.0"
     ansi-regex "^2.0.0"
 
 
-strip-ansi@^6.0.1:
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
   version "6.0.1"
   version "6.0.1"
   resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -3664,6 +3781,11 @@ vue@^3.2.45:
     "@vue/server-renderer" "3.2.45"
     "@vue/server-renderer" "3.2.45"
     "@vue/shared" "3.2.45"
     "@vue/shared" "3.2.45"
 
 
+which-module@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
+  integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==
+
 which@^1.2.9:
 which@^1.2.9:
   version "1.3.1"
   version "1.3.1"
   resolved "https://registry.npmmirror.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
   resolved "https://registry.npmmirror.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
@@ -3683,6 +3805,15 @@ word-wrap@^1.2.3:
   resolved "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
   resolved "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
   integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
   integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
 
 
+wrap-ansi@^6.2.0:
+  version "6.2.0"
+  resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
+  integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
+  dependencies:
+    ansi-styles "^4.0.0"
+    string-width "^4.1.0"
+    strip-ansi "^6.0.0"
+
 wrappy@1:
 wrappy@1:
   version "1.0.2"
   version "1.0.2"
   resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
   resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@@ -3698,6 +3829,11 @@ xtend@^4.0.0:
   resolved "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
   resolved "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
   integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
   integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
 
 
+y18n@^4.0.0:
+  version "4.0.3"
+  resolved "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
+  integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
+
 yallist@^2.1.2:
 yallist@^2.1.2:
   version "2.1.2"
   version "2.1.2"
   resolved "https://registry.npmmirror.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
   resolved "https://registry.npmmirror.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
@@ -3708,6 +3844,31 @@ yallist@^4.0.0:
   resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
   resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
   integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
   integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
 
 
+yargs-parser@^18.1.2:
+  version "18.1.3"
+  resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
+  integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
+  dependencies:
+    camelcase "^5.0.0"
+    decamelize "^1.2.0"
+
+yargs@^15.3.1:
+  version "15.4.1"
+  resolved "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
+  integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
+  dependencies:
+    cliui "^6.0.0"
+    decamelize "^1.2.0"
+    find-up "^4.1.0"
+    get-caller-file "^2.0.1"
+    require-directory "^2.1.1"
+    require-main-filename "^2.0.0"
+    set-blocking "^2.0.0"
+    string-width "^4.2.0"
+    which-module "^2.0.0"
+    y18n "^4.0.0"
+    yargs-parser "^18.1.2"
+
 yauzl@^2.4.2:
 yauzl@^2.4.2:
   version "2.10.0"
   version "2.10.0"
   resolved "https://registry.npmmirror.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
   resolved "https://registry.npmmirror.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"