Browse Source

个人端充值

lifanagju_citu 9 months ago
parent
commit
ee424aca25

+ 4 - 0
components.d.ts

@@ -37,6 +37,7 @@ declare module 'vue' {
     'Index copy': typeof import('./src/components/CtForm/index copy.vue')['default']
     IndustryTypeCard: typeof import('./src/components/industryTypeCard/index.vue')['default']
     Info: typeof import('./src/components/Enterprise/info.vue')['default']
+    InitPay: typeof import('./src/components/personalRecharge/initPay.vue')['default']
     Introduction: typeof import('./src/components/Enterprise/components/introduction.vue')['default']
     Item: typeof import('./src/components/Position/item.vue')['default']
     JobTypeCard: typeof import('./src/components/jobTypeCard/index.vue')['default']
@@ -46,11 +47,14 @@ declare module 'vue' {
     LongStrip: typeof import('./src/components/Position/longStrip.vue')['default']
     NestedListGroup: typeof import('./src/components/FormUI/nestedListGroup/index.vue')['default']
     Pay: typeof import('./src/components/pay/index.vue')['default']
+    PayList: typeof import('./src/components/personalPay/payList.vue')['default']
+    PersonalRecharge: typeof import('./src/components/personalRecharge/index.vue')['default']
     Positions: typeof import('./src/components/Enterprise/components/positions.vue')['default']
     PreviewImg: typeof import('./src/components/PreviewImg/index.vue')['default']
     QrCode: typeof import('./src/components/QrCode/index.vue')['default']
     RadioGroup: typeof import('./src/components/FormUI/radioGroup/index.vue')['default']
     Recharge: typeof import('./src/components/Recharge/index.vue')['default']
+    RechargeList: typeof import('./src/components/personalPay/rechargeList.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
     SimilarPositions: typeof import('./src/components/Position/similarPositions.vue')['default']

+ 17 - 0
src/api/recruit/personal/myWallet.js

@@ -0,0 +1,17 @@
+import request from '@/config/axios'
+
+// 获取用户积分明细
+export const getUserWalletRechargeList = async (params) => {
+  return await request.get({
+    url: 'app-api/pay/wallet-recharge-package/list',
+    params
+  })
+}
+
+// 创建钱包充值记录(发起充值)
+export const setWalletRecharge = async (data) => {
+  return await request.post({
+    url: '/app-api/pay/wallet-recharge/create',
+    data
+  })
+}

+ 4 - 5
src/components/pay/index.vue

@@ -68,7 +68,7 @@
 defineOptions({ name: 'pay-index'})
 import { computed, nextTick, onUnmounted, ref } from 'vue'
 import QrCode from '@/components/QrCode'
-import { definePayTypeList, qrCodePay, walletPay } from './until/payType'
+import { definePayTypeList, qrCodePay, walletPay } from '@/utils/payType'
 import { getEnableCodeList, getUnpaidOrder, payOrderSubmit, getOrderPayStatus } from '@/api/common'
 import { createTradeOrder } from '@/api/position'
 import { useSharedState } from '@/store/sharedState'
@@ -134,7 +134,6 @@ const notEnoughMoney = computed(() => {
   return (Number(props.cost) > Number(accountBalance.value))
 })
 
-// 生成二维码内容
 const timer = ref(null)
 onUnmounted(() => {
   if (timer.value) clearInterval(timer.value); timer.value = null
@@ -159,7 +158,7 @@ const paySubmit = async () => {
         params.id = payOrder.value.payOrderId // 支付单编号
       }
       const res = await payOrderSubmit(params)
-      payQrCodeTxt.value = res?.displayContent || '' // 二维码
+      payQrCodeTxt.value = res?.displayContent || '' // 生成二维码内容
 
       if (timer.value) clearInterval(timer.value); timer.value = null
       timer.value = setInterval(() => { payStatus() }, 1000) // 轮巡查询用户是否支付
@@ -205,7 +204,7 @@ const getUnpaidOrderList = async () => {
       // 
       payOrder.value = data?.payOrder || null
     }
-    if (isQrCodePay.value) paySubmit() // 生成二维码内容
+    if (isQrCodePay.value) paySubmit()
   } catch (error) {
     console.log(error)
   } finally {
@@ -224,7 +223,7 @@ const payTypeChange = (value) => {
   tip.value = payTypeList.value.find(e => e.code === payType.value)?.tip || ''
   isQrCodePay.value = qrCodePay.includes(payType.value)
   isWalletPay.value = walletPay.includes(payType.value)
-  paySubmit() // 生成二维码内容
+  paySubmit() //
 }
 // 1.支付方式
 const payType = ref('')

+ 168 - 0
src/components/personalRecharge/index.vue

@@ -0,0 +1,168 @@
+<template>
+  <div class="resume-box" :class="{'fullShow': fullShow}">
+    <div class="resume-header" v-if="showTitle">
+      <div class="resume-title">余额充值</div>
+    </div>
+    <div class="d-flex align-center mb-10 mt-5">
+      <div
+        v-for="(item, index) in list"
+        :key="index"
+        class="packagesItem cursor-pointer mx-3"
+        :class="{'active': current === (index+1)}"
+        style="width: 200px;"
+        @click="handleSelect(item, index)"
+      >
+        <div class="d-flex flex-column align-center pb-5" style="position: relative;">  
+          <div
+            class="my-4 mt-8 font-size-16 font-weight-bold titleColor"
+            :style="{'color': current === (index + 1) ? '#ff4747' : '#000'}"
+          >
+            {{ item.name }}
+          </div>  
+          <!-- <div class="font-weight-bold priceBox">
+            <span v-if="item.custom">
+              <input 
+                v-model="item.payPrice" 
+                type="text" 
+                class="custom-input-num" 
+                :style="{'color': current === (index + 1) ? '#ff4747' : '#000'}" 
+                @keyup.enter="handleCustomEnter"
+                @focus="item.tip = '输入完成后请按Enter键确认'"
+              >
+            </span>
+            <span class="font28" v-else>{{ item.payPrice }}</span>
+          </div>   -->
+          <div class="dailyPrice font-size-12 mt-3">
+            <span v-if="!item.custom">¥{{ payCalculation(item.payPrice, 'realPay') }}</span>
+            <span v-else>{{ item.tip }}</span>
+          </div>
+          <div class="vip">
+            <svg-icon v-if="current === (index+1)" name="diamond-active" size="50"></svg-icon>
+            <svg-icon v-else name="diamond" size="50"></svg-icon>
+          </div> 
+        </div> 
+      </div>
+    </div>
+    <initPay
+      v-if="current"
+      :info="itemInfo"
+      @paySuccess="current = 0"
+    ></initPay>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'personalRecharge-index'})
+import { payCalculation } from '@/utils/position'
+import { ref } from 'vue'
+import { getUserWalletRechargeList } from '@/api/recruit/personal/myWallet.js'
+import initPay from './initPay.vue'
+
+defineProps({
+  showTitle: {
+    type: Boolean,
+    default: true
+  }
+})
+
+import { useRoute } from 'vue-router'; const route = useRoute()
+const fullShow = ref(route.path === '/personalRecharge' ? true : false)
+
+const current = ref(0)
+
+const price = ref(0)
+
+const list = ref([])
+
+const getListData = async () => {
+  const data = await getUserWalletRechargeList()
+  list.value = data || []
+  // const end = { name: '自定义充值', payPrice: 100, custom: true, tip: '输入完成后请按Enter键确认' }
+  // list.value = data ? [...data, end] : [end]
+}
+getListData()
+
+// const handleCustomEnter = (e) => {
+//   const num = e.target.value
+//   const custom = list.value.find(k => k.custom)
+//   if (num < 100) {
+//     custom.tip = '最低充值金额为100元'
+//     custom.price = 100
+//     return
+//   }
+//   price.value = num
+// }
+
+const timer = ref(null)
+const itemInfo = ref(null)
+let count = 1; const interval = 2000;
+const handleSelect = (item, index) => {
+  count = 1
+  itemInfo.value = item
+  current.value = index + 1
+  price.value = item.payPrice
+  timer.value = setInterval(() => { clearIntervalFun() }, interval)
+}
+
+// 一段时间后清除二维码轮询
+const clearIntervalFun = () => {
+  // console.log('一段时间后清除二维码轮询', (count * interval))
+  count++
+  if ((count * interval) >= 30000 && timer.value) {
+    current.value = 0
+    clearInterval(timer.value); timer.value = null
+  }
+}
+
+</script>
+
+<style scoped lang="scss">
+.fullShow {
+  width: 1100px;
+  background-color: #fff;
+  margin: 0 auto;
+  min-height: 720px;
+}
+.packagesItem {
+  border: 1px solid var(--color-f3);
+  border-radius: 8px;
+  background-color: var(--color-f2f4f742);
+}
+.dailyPrice {
+  border-radius: 14px;
+  background-color: #dde3e94f;
+  padding: 2px 18px;
+  color: var(--color-666);
+}
+.active {
+  border: 2px solid #cf990c;
+  background: linear-gradient(rgb(255, 242, 214) 8.86%, rgb(255, 225, 177) 100%);;
+  .priceBox {
+    color: var(--v-error-base);
+  }
+  .dailyPrice {
+    color: var(--v-error-base);
+    background-color: #fff4e7;
+  }
+}
+.custom-input-num {
+  border: none;
+  outline: none;
+  background-color: transparent;
+  max-width: 100%;
+  text-align: center;
+  font-weight: 700;
+}
+.vip {
+  width: 50px; 
+  height: 50px;
+  position: absolute; 
+  top: 0; 
+  right: 0;
+  overflow: hidden;
+  border-radius: 8px
+}
+:deep(.v-slide-group__content) {
+  background: none !important;
+}
+</style>

+ 216 - 0
src/components/personalRecharge/initPay.vue

@@ -0,0 +1,216 @@
+<!-- 支付组件 -->
+<template>
+  <div v-if="payType && payQrCodeTxt" class="code pa-5 resume-box">
+    <div class="resume-header">
+      <div class="resume-title">扫码支付</div>
+    </div>
+    <div class="d-flex align-end mt-3">
+      <div class="code-left">
+        <QrCode :text="payQrCodeTxt" :width="170" />
+      </div>
+      <div class="code-right ml-5">
+        <div class="price">
+          <span class="font-size-13">¥</span>
+          {{ payCalculation(props.info?.payPrice || 0, 'realPay') }}
+        </div>
+        <div class="mt-3 d-flex align-center">
+          <span class="color-666 font-weight-bold mr-5">支付方式</span>
+          <!-- <v-chip-group v-model="payment" selected-class="text-primary" mandatory>
+            <v-chip filter v-for="k in paymentList" :key="k.value" :value="k.value" class="mr-3" label>
+              {{ k.label }}
+              <svg-icon class="ml-1" :name="k.icon" :size="k.size"></svg-icon>
+            </v-chip>
+          </v-chip-group> -->
+          <v-chip-group v-model="payType" selected-class="text-primary" column mandatory @update:modelValue="payTypeChange">
+            <v-chip filter v-for="k in payTypeList" :key="k.code" :value="k.code" class="mr-3" label>
+              {{ k.name }}
+              <svg-icon v-if="k.icon" class="ml-1" :name="k.icon" :size="k.size"></svg-icon>
+            </v-chip>
+          </v-chip-group>
+        </div>
+        <div class="font-size-14 color-666 mt-3 cursor-pointer">
+          服务协议
+          <span class="septal-line"></span>
+          充值协议
+        </div>
+      </div>
+    </div>
+    <div class="mt-5 ml-2" style="color: var(--v-error-base);">扫码支付时请勿离开</div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({name: 'personalRecharge-initPay'})
+import QrCode from '@/components/QrCode'
+import { payCalculation } from '@/utils/position'
+import { definePayTypeList, qrCodePay, walletPay } from '@/utils/payType'
+import { getEnableCodeList, payOrderSubmit, getOrderPayStatus } from '@/api/common'
+import { setWalletRecharge } from '@/api/recruit/personal/myWallet.js'
+import { onUnmounted, ref, nextTick } from 'vue'
+const emit = defineEmits(['payTypeChange', 'paySuccess'])
+const props = defineProps({
+  info: {
+    type: Object,
+    default: () => ({})
+  },
+  appId: {
+    type: Number,
+    default: 11 // 10为一般情况下支付,11为充值支付
+  },
+})
+
+// 1.支付方式
+// 2.发起充值(创建钱包充值记录)
+// 2.发起充值(创建钱包充值记录)
+// 3. 如果是二维码类型支付(isQrCodePay=true)生成二维码(需要绑定支付订单的订单号)
+// 4.轮询用户是否支付成功
+
+// 更新账户余额信息
+import { useUserStore } from '@/store/user'; const store = useUserStore()
+const updateAccountInfo = async () => {
+  await store.getUserAccountBalance()
+  loading.value = false
+}
+
+import Snackbar from '@/plugins/snackbar'
+import { useRoute } from 'vue-router'; const route = useRoute()
+import { useRouter } from 'vue-router'; const router = useRouter()
+const payStatus = async () => {
+  // if (timer.value) clearInterval(timer.value); timer.value = null
+  // setTimeout(() => { // 测试代码
+  // }, 2000)
+  try {
+    const data = await getOrderPayStatus({ id: (props.appId - 0) === 11 ? payOrder.value.payOrderId : payOrder.value.id })
+    if ((data?.status - 0) === 10) {
+      // 支付成功
+      if (timer.value) clearInterval(timer.value); timer.value = null
+      setTimeout(() => {
+        // 更新点数(充值、发布职位)
+        updateAccountInfo()
+        // 支付成功
+        emit('paySuccess')
+        // 返回指定页面
+        if (route.fullPath === props.returnUrl) router.go(0)
+        else if (props.returnUrl) router.push(props.returnUrl)
+        Snackbar.success('支付成功')
+      }, 2000);
+    }
+  } catch (error) {
+    console.log(error)
+  }
+}
+
+const timer = ref(null)
+const payQrCodeTxt = ref('')
+onUnmounted(() => {
+  if (timer.value) clearInterval(timer.value); timer.value = null
+})
+// 如果是点数支付的话走完payOrderSubmit之后即扣点数,如果是二维码支付的话只是生成二维码,这一步以后是轮询是否支付成功
+const paySubmit = async () => {
+  if (!payType.value) return
+  if (!payOrder.value?.payOrderId) return
+  try {
+    if (payOrder.value) {
+      // 提交支付订单
+      const params = {
+        id: payOrder.value.payOrderId, // 支付单编号
+        channelCode: payType.value, // 支付渠道
+      }
+      const res = await payOrderSubmit(params)
+      payQrCodeTxt.value = res?.displayContent || '二维码生成失败,请刷新再试。' // 生成二维码内容
+
+      if (timer.value) clearInterval(timer.value); timer.value = null
+      timer.value = setInterval(() => { payStatus() }, 1000) // 轮巡查询用户是否支付
+    }
+  } catch (error) {
+    console.log(error)
+  }
+}
+
+// 2.发起充值
+const loading = ref(false); setTimeout(() => { loading.value = true }, 500);
+const payOrder = ref({})
+const getUnpaidOrderList = async () => {
+  try {
+    //* 充值
+    if (props.info.payPrice === undefined && props.info.packageId === undefined) return
+    const params = {
+      payPrice: (props.info.payPrice-0),
+      packageId: props.info.id,
+    }
+    const data = await setWalletRecharge(params)
+    payOrder.value = data || {}
+    if (isQrCodePay.value) paySubmit()
+  } catch (error) {
+    console.log(error)
+  } finally {
+    nextTick(() => {
+      loading.value = false
+    })
+  }
+}
+
+// 1.支付方式
+const isWalletPay = ref(false)
+const isQrCodePay = ref(false)
+const tip = ref('')
+const payTypeChange = (value) => {
+  payType.value = value
+  tip.value = payTypeList.value.find(e => e.code === payType.value)?.tip || ''
+  isQrCodePay.value = qrCodePay.includes(payType.value)
+  isWalletPay.value = walletPay.includes(payType.value)
+  paySubmit()
+}
+// 1.支付方式
+const payType = ref('')
+const payTypeList = ref([])
+const codeList = ref([])
+const getCodeList = async () => {
+  try {
+    const list = await getEnableCodeList({appId: props.appId})
+    codeList.value = list || []
+  } catch (error) {
+    console.log(error)
+  } finally {
+    if (definePayTypeList?.length && codeList.value?.length) {
+      codeList.value.forEach(code => {
+        const item = definePayTypeList.find(p => p.code === code)
+        if (item) {
+          if (!payType.value) {
+            tip.value = item.tip || ''
+            // payTypeChange(code) // 默认值赋值
+            // 默认值赋值(暂时只支持扫码)
+            const bool = qrCodePay.includes(code)
+            if (bool) payTypeChange(code)
+          }
+          payTypeList.value.push(item)
+        }
+      })
+    }
+    getUnpaidOrderList()
+  }
+}
+getCodeList()
+
+</script>
+<style lang="scss" scoped>
+.code {
+  // max-width: 1100px;
+  // max-width: 600px;
+  border-radius: 6px;
+  // margin: 0 auto;
+  background-color: #f7f8fa;
+  &-left {
+    border: 1px solid #00897B;
+    border-radius: 6px;
+    padding: 5px;
+  }
+  &-right {
+    .price {
+      font-size: 30px;
+      font-weight: 700;
+      color: var(--v-error-base);
+    }
+  }
+}
+</style>

+ 4 - 2
src/layout/personal/navBar.vue

@@ -34,10 +34,10 @@
           <!-- 头像用户名 -->
           <div class="d-flex align-center" v-if="getToken()">
             <span class="cursor-pointer mr-5" @click="changeLoginType">我要招聘</span>
-            <span class="cursor-pointer" :class="{'routeActive': routeActive === 4}" @click="router.push({ path: paths[4] })">
+            <span class="cursor-pointer" :class="{'routeActive': routeActive === 6}" @click="router.push({ path: paths[6] })">
               {{t('enterprise.account.accountBalances')}}:{{ userAccount?.balance && userAccount?.balance > 0 ? (userAccount?.balance / 100.0).toFixed(2) : 0 }}
             </span>
-            <span class="mr-3 ml-3 cursor-pointer" :class="{'routeActive': routeActive === 4}" @click="router.push({ path: paths[4] })">{{t('resume.goldCoins')}}:{{ userAccount?.point || 0 }}</span>
+            <span class="mr-3 ml-3 cursor-pointer" :class="{'routeActive': routeActive === 7}" @click="router.push({ path: paths[7] })">{{t('resume.goldCoins')}}:{{ userAccount?.point || 0 }}</span>
 
             
             <v-menu open-on-hover>
@@ -155,6 +155,8 @@ const paths = [ // 有选中样式-路由列表
   '/recruit/personal/message', // 3
   '/recruit/personal/myWallet', // 4
   '/recruit/personal/personalCenter', // 5
+  '/recruit/personal/myWallet/myBalance', // 6
+  '/recruit/personal/myWallet/myIntegral', // 7
   ]
 const list = ref([
   { text: t('common.home'), path: paths[0] },

+ 1 - 1
src/locales/en.js

@@ -253,7 +253,7 @@ export default {
     attachmentResume: 'Attachment resume',
     uploadUpToFiveCopies: 'Upload up to 5 copies',
     accountWithdrawal: 'Account withdrawal',
-    goldCoins: 'Remaining gold coins',
+    goldCoins: 'Remaining points', // Remaining gold coins
     requestResume: 'I would like a copy of your resume, if you agree?'
   },
   setting: {

+ 1 - 1
src/locales/zh-CN.js

@@ -253,7 +253,7 @@ export default {
     attachmentResume: '附件简历',
     uploadUpToFiveCopies: '最多上传5份',
     accountWithdrawal: '账户取现',
-    goldCoins: '剩余金币',
+    goldCoins: '剩余积分',
     requestResume: '我想要一份您的简历,您是否同意'
   },
   setting: {

+ 22 - 1
src/router/modules/components/recruit/personal.js

@@ -112,7 +112,28 @@ const personal = [
         meta: {
           title: '我的钱包'
         },
-      }
+      },
+      {
+        path: '/recruit/personal/myWallet/myBalance',
+        component: () => import('@/views/recruit/personal/myWallet/myBalance'),
+        meta: {
+          title: '账户余额'
+        },
+      },
+      {
+        path: '/recruit/personal/myWallet/myIntegral',
+        component: () => import('@/views/integral/pointsManagement'),
+        meta: {
+          title: '我的积分'
+        },
+      },
+      {
+        path: '/personalRecharge',
+        component: () => import('@/components/personalRecharge'),
+        meta: {
+          title: '充值'
+        },
+      },
     ]
   },
   {

+ 1 - 1
src/store/user.js

@@ -155,7 +155,7 @@ export const useUserStore = defineStore('user',
         this.enterpriseUserAccount = data
         // this.getUserAccountBalance()
         localStorage.setItem('enterpriseUserAccount', JSON.stringify(data))
-        return data
+        return data // 方便直接获取
       },
       // 获取用户账户信息
       async getUserAccountInfo () {

+ 0 - 0
src/components/pay/until/payType.js → src/utils/payType.js


+ 2 - 2
src/views/integral/pointsManagement/components/integralShow.vue

@@ -50,8 +50,8 @@ const props = defineProps({
 })
 
 const list = ref([
-  { title: '您当前可用积分', value: 'point', showRules: true },
-  { title: '您当前剩余点数', value: 'balance', showRules: false }
+  { title: '您当前剩余积分', value: 'point', showRules: true },
+  // { title: '您当前余额', value: 'balance', showRules: false },
 ])
 
 const userStore = useUserStore()

+ 120 - 0
src/views/recruit/personal/myWallet/myBalance/index.vue

@@ -0,0 +1,120 @@
+<template>
+  <div class="default-width">
+    <div class="pa-3 mb-2 white-bgc">
+      <!-- 余额展示 -->
+      <div class="statisticsBox">
+        <div class="ml-10 mt-2">
+          <div class="item-title">
+            您当前可用余额
+          </div>
+          <div class="item-value">
+            {{ userAccount?.balance && userAccount?.balance > 0 ? (userAccount?.balance / 100.0).toFixed(2) : 0 }}
+            <span
+              class="text-decoration-underline cursor-pointer"
+              style="color: #666; font-size: 13px;"
+              @click="handleRecharge"
+            >充值</span>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 表格 -->
+    <div class="mt-3 white-bgc pa-3 pt-3">
+      <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f7f8fa" @update:model-value="handleChangeTab">
+        <v-tab value="balanceDetails">{{ $t('points.balanceDetails') }}</v-tab>
+        <!-- <v-tab :value="otherHeader">otherHeader</v-tab> -->
+      </v-tabs>
+      <CtTable
+        class="mt-3"
+        :items="dataList"
+        :headers="headerList[tab]"
+        :loading="false"
+        :elevation="0"
+        :isTools="false"
+        :showPage="true"
+        :total="total"
+        :page-info="query"
+        itemKey="id"
+        @pageHandleChange="handleChangePage"
+      >
+      </CtTable>
+    </div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({name: 'myWallet-myBalance-index'})
+import { ref } from 'vue'
+import { timesTampChange } from '@/utils/date'
+import { getUserRewardPointPage } from '@/api/integral'
+
+const tab = ref('balanceDetails')
+
+const userAccount = ref(JSON.parse(localStorage.getItem('userAccount')) || {}) // 账户信息
+
+const total = ref(0)
+const query = ref({
+  pageNo: 1,
+  pageSize: 10,
+})
+const dataList = ref([])
+
+const headerList = {
+  balanceDetails: [
+    { title: '标题', key: 'title', sortable: false },
+    { title: '描述', key: 'description', sortable: false },
+    { title: '获得积分点', key: 'point', sortable: false },
+    { title: '剩余点数', key: 'totalPoint', sortable: false },
+    { title: '发生时间', key: 'createTime', value: item =>  timesTampChange(item.createTime), sortable: false },
+  ],
+  // otherHeader: []
+}
+
+
+// 积分、签到明细
+const getData = async () => {
+  const res = await getUserRewardPointPage(query.value)
+  dataList.value = res.list
+  total.value = res.total
+}
+getData()
+
+const handleChangePage = (e) => {
+  query.value.pageNo = e
+  getData()
+}
+
+// 切换
+const handleChangeTab = () => {
+  query.value.pageNo = 1
+  getData()
+}
+
+// 充值
+import { useRouter } from 'vue-router'; const router = useRouter()
+const handleRecharge = () => {
+  router.push({ path: '/personalRecharge' })
+}
+</script>
+
+<style lang="scss" scoped>
+.statisticsBox {
+  padding: 10px 0;
+  border-radius: 10px;
+  background-color: var(--default-bgc);
+  // background-color: var(--color-f3);
+  // font-family: 宋体, SimSun;
+}
+.item-title {
+  font-size: 20px; 
+  color: var(--color-333); 
+  line-height: 28px; 
+  font-weight: bold;
+}
+.item-value {
+  font-size: 42px; 
+  color: #10897bba;
+  line-height: 50px;
+}
+</style>
+