li.shaoyi 2 тижнів тому
батько
коміт
011416784b

+ 67 - 0
src/packages/digital/components/field-currency/index.vue

@@ -0,0 +1,67 @@
+<template>
+    <Field v-bind="$attrs" placeholder="请选择" arrow-direction="down" is-link readonly @click="showSheet = true">
+        <template #input v-if="currencyItem">
+            <app-image-icon :url="getCurrencyIconUrl(currencyItem.label)" size="small" />
+            <span>{{ currencyItem.label }}</span>
+        </template>
+    </Field>
+    <ActionSheet v-model:show="showSheet" title="请选择" teleport="body">
+        <CellGroup style="min-height: 200px;">
+            <RadioGroup v-model="currencyId" v-if="digitalCurrencyList.length">
+                <template v-for="(item, index) in digitalCurrencyList" :key="index">
+                    <Cell size="large" :title="item.label" :border="false" clickable center
+                        @click="onRadioClick(item.value)">
+                        <template #icon>
+                            <app-image-icon :url="getCurrencyIconUrl(item.label)" size="small"
+                                style="margin-right: 8px;" />
+                        </template>
+                        <template #right-icon>
+                            <Radio :name="item.value" />
+                        </template>
+                    </Cell>
+                </template>
+            </RadioGroup>
+            <Empty description="暂无数据" v-else />
+        </CellGroup>
+    </ActionSheet>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, computed, onMounted, nextTick } from 'vue'
+import { Field, ActionSheet, CellGroup, RadioGroup, Cell, Radio, Empty } from 'vant'
+import { getCurrencyIconUrl } from '@/filters'
+import { getDigitalCurrencyList } from '@/constants/order'
+import AppImageIcon from '@mobile/components/base/image-icon/index.vue'
+
+const props = defineProps({
+    modelValue: {
+        type: Number
+    }
+})
+
+const emit = defineEmits(['update:modelValue', 'change'])
+
+const showSheet = shallowRef(false)
+const digitalCurrencyList = getDigitalCurrencyList()
+
+const currencyItem = computed(() => digitalCurrencyList.find((e) => e.enumitemname === currencyId.value))
+
+const currencyId = computed({
+    get: () => props.modelValue,
+    set: (val) => emit('update:modelValue', val)
+})
+
+const onChange = () => {
+    emit('change', currencyItem.value)
+}
+
+const onRadioClick = (value: number) => {
+    currencyId.value = value
+    showSheet.value = false
+    nextTick(() => onChange())
+}
+
+onMounted(() => {
+    onChange()
+})
+</script>

+ 82 - 0
src/packages/digital/components/field-token/index.vue

@@ -0,0 +1,82 @@
+<template>
+    <Field v-bind="$attrs" placeholder="请选择" arrow-direction="down" is-link readonly @click="showSheet = true">
+        <template #input v-if="tokenItem">
+            <app-image-icon :url="tokenItem.icon_url" size="small" />
+            <span>{{ tokenItem.name }} ({{ tokenItem.chain_id }})</span>
+        </template>
+    </Field>
+    <ActionSheet v-model:show="showSheet" title="请选择" teleport="body">
+        <CellGroup style="min-height: 200px;">
+            <RadioGroup v-model="tokenId" v-if="dataList.length">
+                <template v-for="(item, index) in dataList" :key="index">
+                    <Cell :title="item.name" :label="item.chain_id" :border="false" clickable center
+                        @click="onRadioClick(item.id)">
+                        <template #icon>
+                            <app-image-icon :url="item.icon_url" size="small" style="margin-right: 8px;" />
+                        </template>
+                        <template #right-icon>
+                            <Radio :name="item.id" />
+                        </template>
+                    </Cell>
+                </template>
+            </RadioGroup>
+            <Empty description="暂无数据" v-else />
+        </CellGroup>
+    </ActionSheet>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, computed, watch, nextTick } from 'vue'
+import { Field, ActionSheet, CellGroup, RadioGroup, Cell, Radio, Empty } from 'vant'
+import { useRequest } from '@/hooks/request'
+import { queryWalletTokens } from '@/services/api/digital'
+import AppImageIcon from '@mobile/components/base/image-icon/index.vue'
+
+const props = defineProps({
+    modelValue: {
+        type: Number,
+        required: true
+    },
+    currency: {
+        type: String,
+    }
+})
+
+const emit = defineEmits(['update:modelValue', 'change'])
+
+const showSheet = shallowRef(false)
+
+const tokenItem = computed(() => dataList.value.find((e) => e.id === tokenId.value))
+
+const tokenId = computed({
+    get: () => props.modelValue,
+    set: (val) => emit('update:modelValue', val)
+})
+
+const { dataList, run } = useRequest(queryWalletTokens, {
+    manual: true,
+    onSuccess: () => {
+        dataList.value.filter((e) => e.can_deposit === 1)
+    }
+})
+
+const onChange = () => {
+    emit('change', tokenItem.value)
+}
+
+const onRadioClick = (value: number) => {
+    tokenId.value = value
+    showSheet.value = false
+    nextTick(() => onChange())
+}
+
+watch(() => props.currency, (value) => {
+    if (value) {
+        run({
+            currency: value
+        })
+    } else {
+        dataList.value = []
+    }
+})
+</script>

+ 13 - 8
src/packages/digital/views/contract/components/position/detail/index.vue

@@ -16,7 +16,7 @@
                 <tr>
                     <td colspan="3">
                         <span class="text-small">{{ $t('account.profitLoss') + `(${currency(item.currencyid)})`
-                            }}</span>
+                        }}</span>
                         <span :class="item.profitLossClass">
                             {{ item.profitLoss.toFixed(item.decimalplace) }}
                         </span>
@@ -41,12 +41,12 @@
                 <tr>
                     <td>
                         <span class="text-small">{{ $t('position.goods.holderprice') + `(${currency(item.currencyid)})`
-                        }}</span>
+                            }}</span>
                         <span>{{ item.holderprice }}</span>
                     </td>
                     <td>
                         <span class="text-small">{{ $t('position.goods.holderamount') + `(${currency(item.currencyid)})`
-                        }}</span>
+                            }}</span>
                         <span>{{ item.holderamount }}</span>
                     </td>
                     <td></td>
@@ -75,7 +75,7 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, PropType, defineAsyncComponent, computed } from 'vue'
+import { shallowRef, PropType, defineAsyncComponent, computed, onUnmounted } from 'vue'
 import { Button } from 'vant'
 import { formatDate } from '@/filters'
 import { getBuyOrSellName, getGoodsCurrencyItemName } from '@/constants/order'
@@ -83,6 +83,7 @@ import { useRequest } from '@/hooks/request'
 import { useComponent } from '@/hooks/component'
 import { queryTradeHolderDetail } from '@/services/api/order'
 import { useFuturesStore } from '@/stores'
+import eventBus from '@/services/bus'
 import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
 
 const props = defineProps({
@@ -140,11 +141,15 @@ const closed = (isRefresh = false) => {
     showModal.value = false
 }
 
+// 接收成交通知
+const orderDealedNtf = eventBus.$on('OrderDealedNtf', () => {
+    pullRefreshRef.value?.refresh()
+})
+
+onUnmounted(() => orderDealedNtf.cancel())
+
 // 暴露组件属性给父组件调用
 defineExpose({
-    closed,
-    refresh: () => {
-        pullRefreshRef.value?.refresh()
-    }
+    closed
 })
 </script>

+ 17 - 14
src/packages/digital/views/contract/components/position/detail/tpsl/index.vue

@@ -82,6 +82,7 @@ import { handleRequestBigNumber } from '@/filters'
 import { getBuyOrSellName, getGoodsCurrencyItemName, BuyOrSell } from '@/constants/order'
 import { holderTPSLSet } from '@/services/api/trade'
 import { i18n, useFuturesStore } from '@/stores'
+import { Decimal } from 'decimal.js'
 import AppModal from '@/components/base/modal/index.vue'
 import AppStepper from '@mobile/components/base/stepper/index.vue'
 
@@ -123,29 +124,29 @@ const pricePoints = computed(() => {
     const multiplier = Math.pow(10, decimalplace)
 
     const price = {
-        takeProfit: lastPrice,
-        stopLoss: lastPrice,
+        takeProfit: Decimal(lastPrice),
+        stopLoss: Decimal(lastPrice),
     }
 
     if (buyorsell === BuyOrSell.Buy) {
         if (buytppoint) {
-            const profitPoint = buytppoint / multiplier
-            price.takeProfit = lastPrice + profitPoint // 买止盈
+            const profitPoint = Decimal(buytppoint).dividedBy(multiplier)
+            price.takeProfit = Decimal(lastPrice).plus(profitPoint) // 买止盈
         }
         if (buyslpoint) {
-            const lossPoint = buyslpoint / multiplier
-            price.stopLoss = lastPrice - lossPoint // 买止损
+            const lossPoint = Decimal(buyslpoint).dividedBy(multiplier)
+            price.stopLoss = Decimal(lastPrice).minus(lossPoint)  // 买止损
         }
     }
 
     if (buyorsell === BuyOrSell.Sell) {
         if (selltppoint) {
-            const profitPoint = selltppoint / multiplier
-            price.takeProfit = lastPrice - profitPoint // 卖止盈
+            const profitPoint = Decimal(selltppoint).dividedBy(multiplier)
+            price.takeProfit = Decimal(lastPrice).minus(profitPoint) // 卖止盈
         }
         if (sellslpoint) {
-            const lossPoint = sellslpoint / multiplier
-            price.stopLoss = lastPrice + lossPoint // 卖止损
+            const lossPoint = Decimal(sellslpoint).dividedBy(multiplier)
+            price.stopLoss = Decimal(lastPrice).plus(lossPoint) // 卖止损
         }
     }
 
@@ -158,8 +159,9 @@ const formRules: { [key: string]: FieldRule[] } = {
         message: '请输入止盈价格',
         validator: () => {
             if (formData.TPFlag) {
+                const { takeProfit } = pricePoints.value
                 const value = Number(formData.TPPrice)
-                const isInvalid = props.selectedRow.buyorsell === BuyOrSell.Buy ? value < pricePoints.value.takeProfit : value > pricePoints.value.takeProfit
+                const isInvalid = props.selectedRow.buyorsell === BuyOrSell.Buy ? value < takeProfit.toNumber() : value > takeProfit.toNumber()
                 return isInvalid ? '价格不在有效范围内' : true
             }
             return true
@@ -169,8 +171,9 @@ const formRules: { [key: string]: FieldRule[] } = {
         message: '请输入止损价格',
         validator: () => {
             if (formData.SLFlag) {
+                const { stopLoss } = pricePoints.value
                 const value = Number(formData.SLPrice)
-                const isInvalid = props.selectedRow.buyorsell === BuyOrSell.Buy ? value > pricePoints.value.stopLoss : value < pricePoints.value.stopLoss
+                const isInvalid = props.selectedRow.buyorsell === BuyOrSell.Buy ? value > stopLoss.toNumber() : value < stopLoss.toNumber()
                 return isInvalid ? '价格不在有效范围内' : true
             }
             return true
@@ -205,8 +208,8 @@ const closed = () => {
 }
 
 onMounted(() => {
-    formData.TPPrice = Number(props.selectedRow.tpsl_tpprice) || pricePoints.value.takeProfit
-    formData.SLPrice = Number(props.selectedRow.tpsl_slprice) || pricePoints.value.stopLoss
+    formData.TPPrice = Number(props.selectedRow.tpsl_tpprice) || pricePoints.value.takeProfit.toNumber()
+    formData.SLPrice = Number(props.selectedRow.tpsl_slprice) || pricePoints.value.stopLoss.toNumber()
 })
 
 // 暴露组件属性给父组件调用

+ 6 - 10
src/packages/digital/views/contract/goods/detail/index.vue

@@ -63,18 +63,17 @@
         </Form>
         <Row class="g-layout-block g-layout-block--inset">
             <Col span="24">
-            <Button :type="formData.BuyOrSell === BuyOrSell.Buy ? 'success' : 'danger'" block
-                @click="formRef?.submit">{{
-                    formData.BuyOrSell === BuyOrSell.Buy ? $t('digital.buy') : $t('digital.sell') }}{{ quote?.goodscode
-                }}</Button>
+            <Button :type="formData.BuyOrSell === BuyOrSell.Buy ? 'success' : 'danger'" block @click="formRef?.submit">
+                {{ formData.BuyOrSell === BuyOrSell.Buy ? $t('digital.buy') : $t('digital.sell') }}{{ quote?.goodscode }}
+            </Button>
             </Col>
         </Row>
         <Tabs v-model:active="tabIndex">
             <Tab :title="t('digital.position')">
-                <contract-position ref="positionRef" :params="{ goodsid: goodsId }" />
+                <contract-position :params="{ goodsid: goodsId }" v-if="tabIndex === 0" />
             </Tab>
             <Tab :title="t('digital.order')">
-                <contract-order :params="{ goodsID: goodsId, orderStatus: '3,7' }" />
+                <contract-order :params="{ goodsID: goodsId, orderStatus: '3,7' }" v-if="tabIndex === 1" />
             </Tab>
             <Tab :title="t('digital.account')">
                 <contract-account v-bind="{ goodsId }" />
@@ -107,7 +106,6 @@ const tabIndex = shallowRef(0)
 const { global: { t } } = i18n
 
 const formRef = shallowRef<FormInstance>()
-const positionRef = shallowRef()
 const showModal = shallowRef(true)
 
 const userStore = useUserStore()
@@ -159,7 +157,7 @@ const calculations = computed(() => {
     // 保证金设置(固定) 时:可开数量 = 可用余额 / (合约乘数 * 固定值)
     // 保证金设置(比率) 时:可开数量 = 可用余额 / (价格 * 合约乘数 * 比率值)
     // 账户可用余额为负的情况下,合约商品交易界面的可开数量应显示为0
-    const maxBuyQty = maxBalance <= 0 ? 0 : (marketmarginalgorithm === 2 ? maxBalance/(agreeunit*marketmarginvalue) : maxBalance/(price*agreeunit*marketmarginvalue))
+    const maxBuyQty = maxBalance <= 0 ? 0 : (marketmarginalgorithm === 2 ? maxBalance / (agreeunit * marketmarginvalue) : maxBalance / (price * agreeunit * marketmarginvalue))
 
     return {
         estimatedAmount,
@@ -226,8 +224,6 @@ const onSubmit = () => {
         fullloading((hideLoading) => {
             formSubmit().then(() => {
                 hideLoading(t('quote.goods.tips3'), 'success')
-                // 刷新订单列表
-                positionRef.value?.refresh()
             }).catch((err) => {
                 hideLoading(err, 'fail')
             })

+ 2 - 2
src/packages/digital/views/wallet/components/spot/index.vue

@@ -5,7 +5,7 @@
             <div class="card" @click="onClick(item)">
                 <div class="card-section">
                     <div class="card-section__image">
-                        <image-icon :url="getCurrencyIconUrl(item.currencycode)" />
+                        <app-image-icon :url="getCurrencyIconUrl(item.currencycode)" />
                     </div>
                     <div class="card-section__info">
                         <span>
@@ -40,7 +40,7 @@ import { formatDecimal,getCurrencyIconUrl } from '@/filters'
 import { getDigitalCurrencyName } from '@/constants/order'
 import { useSpotAccountStore } from './composables'
 import { i18n } from '@/stores'
-import ImageIcon from '@mobile/components/base/image-icon/index.vue'
+import AppImageIcon from '@mobile/components/base/image-icon/index.vue'
 
 const emit = defineEmits(['click'])
 const { global: { t } } = i18n

+ 26 - 77
src/packages/digital/views/wallet/deposit/index.vue

@@ -6,22 +6,12 @@
         </template>
         <Form ref="formRef" class="g-form__container g-layout-block" @submit="onSubmit">
             <CellGroup inset>
-                <Field name="currenty" label="币种" label-align="top" :rules="formRules.currenty" arrow-direction="down"
-                    center is-link>
-                    <template #input>
-                        <image-icon :url="getCurrencyIconUrl(currentyItem.label)" size="small" v-if="currentyItem" />
-                        <app-select v-model="state.currentyId" :options="digitalCurrentyList"
-                            @confirm="onCurrentyChange" />
-                    </template>
-                </Field>
+                <app-field-currency name="currency" label="币种" label-align="top" :rules="formRules.currency"
+                    v-model="state.currencyId" @change="onCurrencyChange" />
             </CellGroup>
             <CellGroup inset>
-                <Field name="token" label="存款网络" label-align="top" placeholder="请选择" :rules="formRules.token"
-                    arrow-direction="down" is-link readonly @click="state.showSheet = true">
-                    <template #input v-if="tokenItem">
-                        {{ tokenItem.name }} ({{ tokenItem.chain_id }})
-                    </template>
-                </Field>
+                <app-field-token name="token" label="存款网络" label-align="top" :rules="formRules.token"
+                    v-model="state.tokenId" :currency="state.currencyName" @change="onTokenChange" />
             </CellGroup>
         </Form>
         <CellGroup inset v-if="tokenItem">
@@ -30,7 +20,7 @@
                 <dl class="g-layout-block g-layout-block--inset">
                     <dt>
                         <h3>存款地址</h3>
-                        <span>*仅将 {{ currentyItem?.label }} 存入此地址</span>
+                        <span>*仅将 {{ state.currencyName }} 存入此地址</span>
                     </dt>
                     <dd v-for="(item, index) in addressList" :key="index">
                         <span>{{ item.address }}</span>
@@ -43,24 +33,6 @@
                 </div>
             </div>
         </CellGroup>
-        <ActionSheet v-model:show="state.showSheet" title="选择存款网络">
-            <CellGroup style="min-height: 200px;">
-                <RadioGroup v-model="state.tokenId" v-if="walletTokens.length">
-                    <template v-for="(item, index) in walletTokens" :key="index">
-                        <Cell :title="item.name" :label="item.chain_id" :border="false" clickable center
-                            @click="onRadioClick(item.id)">
-                            <!-- <template #icon>
-                                <image-icon :url="item.icon_url" style="margin-right: 8px;" />
-                            </template> -->
-                            <template #right-icon>
-                                <Radio :name="item.id" />
-                            </template>
-                        </Cell>
-                    </template>
-                </RadioGroup>
-                <Empty description="暂无数据" v-else />
-            </CellGroup>
-        </ActionSheet>
         <Dialog v-model:show="state.showDialog" :show-confirm-button="false" cancel-button-text="关闭" show-cancel-button
             destroy-on-close>
             <div class="wallet-deposit__qrcode">
@@ -71,44 +43,40 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, computed, reactive, onMounted } from 'vue'
-import { FormInstance, FieldRule, Form, Button, CellGroup, Field, Cell, ActionSheet, RadioGroup, Radio, Icon, showSuccessToast, showFailToast, Dialog, Empty } from 'vant'
+import { shallowRef, computed, reactive } from 'vue'
+import { FormInstance, FieldRule, Form, Button, CellGroup, Cell, Icon, showSuccessToast, showFailToast, Dialog } from 'vant'
 import { dialog, fullloading } from '@/utils/vant'
-import { formatDecimal, getCurrencyIconUrl } from '@/filters'
-import { getDigitalCurrencyList } from '@/constants/order'
+import { formatDecimal } from '@/filters'
 import { useRequest } from '@/hooks/request'
-import { queryWalletAddress, queryWalletTokens, createDigitalWalletAddress } from '@/services/api/digital'
+import { queryWalletAddress, createDigitalWalletAddress } from '@/services/api/digital'
 import { useNavigation } from '@mobile/router/navigation'
 import { useSpotAccountStore } from '../components/spot/composables'
 import AppQrcode from '@/components/base/qrcode/index.vue'
-import AppSelect from '@mobile/components/base/select/index.vue'
-import ImageIcon from '@mobile/components/base/image-icon/index.vue'
+import AppFieldCurrency from '@/packages/digital/components/field-currency/index.vue'
+import AppFieldToken from '@/packages/digital/components/field-token/index.vue'
 
 const { getQueryStringToNumber } = useNavigation()
 
+const spotAccountStore = useSpotAccountStore()
 const formRef = shallowRef<FormInstance>()
 const currencyId = getQueryStringToNumber('id')
 
-const spotAccountStore = useSpotAccountStore()
-const digitalCurrentyList = getDigitalCurrencyList()
-
 const state = reactive({
     showSheet: false,
     showDialog: false,
     qrContent: '',
-    currentyId: currencyId,
+    currencyId: currencyId,
+    currencyName: '',
     tokenId: 0
 })
 
-const addressList = computed(() => walletAddress.value.filter((e) => e.chain_id === tokenItem.value?.chain_id))
+const { dataList: walletAddress, run: getWalletAddress } = useRequest(queryWalletAddress)
 
-const currentyItem = computed(() => digitalCurrentyList.find((e) => e.enumitemname === state.currentyId))
+const tokenItem = shallowRef<Model.WalletTokensRsp>()
 
-const tokenItem = computed(() => walletTokens.value.find((e) => e.id === state.tokenId))
+const addressList = computed(() => walletAddress.value.filter((e) => e.chain_id === tokenItem.value?.chain_id))
 
-const accountItem = computed(() => spotAccountStore.getAccountItem({
-    currencyid: currencyId
-}))
+const accountItem = computed(() => spotAccountStore.getAccountItem({ currencyid: currencyId }))
 
 // 可用余额
 const balance = computed(() => {
@@ -116,20 +84,11 @@ const balance = computed(() => {
     return formatDecimal(balance, accountItem.value?.currencydecimalplace)
 })
 
-const { dataList: walletAddress, run: getWalletAddress } = useRequest(queryWalletAddress)
-
-const { dataList: walletTokens, run: getWalletTokens } = useRequest(queryWalletTokens, {
-    manual: true,
-    onSuccess: () => {
-        walletTokens.value.filter((e) => e.can_deposit === 1)
-    }
-})
-
 // 表单验证规则
 const formRules: { [key: string]: FieldRule[] } = {
-    currenty: [{
+    currency: [{
         message: '请选择币种',
-        validator: () => !!state.currentyId
+        validator: () => !!state.currencyId
     }],
     token: [{
         message: '请选择网络',
@@ -137,21 +96,15 @@ const formRules: { [key: string]: FieldRule[] } = {
     }],
 }
 
-const onCurrentyChange = () => {
+const onCurrencyChange = (item: { label: string; }) => {
     state.tokenId = 0
-
-    if (currentyItem.value) {
-        getWalletTokens({
-            currency: currentyItem.value.label
-        })
-    } else {
-        walletTokens.value = []
-    }
+    state.currencyName = item.label
+    tokenItem.value = undefined
 }
 
-const onRadioClick = (value: number) => {
-    state.tokenId = value
-    state.showSheet = false
+const onTokenChange = (item: Model.WalletTokensRsp) => {
+    tokenItem.value = item
+    formRef.value?.validate('token')
 }
 
 const openQRcode = (address: string) => {
@@ -190,10 +143,6 @@ const onSubmit = () => {
         })
     })
 }
-
-onMounted(() => {
-    onCurrentyChange()
-})
 </script>
 
 <style lang="less">

+ 1 - 1
src/packages/digital/views/wallet/transfer/index.vue

@@ -134,7 +134,7 @@ const onSubmit = () => {
 }
 
 onMounted(() => {
-    formData.CurrencyID = currencyOptions[0].enumitemname
+    formData.CurrencyID = currencyOptions[0]?.enumitemname
 })
 </script>
 

+ 19 - 67
src/packages/digital/views/wallet/withdraw/index.vue

@@ -6,21 +6,12 @@
         </template>
         <Form ref="formRef" class="g-form__container g-layout-block" @submit="onSubmit">
             <CellGroup inset>
-                <Field name="currenty" label="币种" label-align="top" :rules="formRules.currenty" arrow-direction="down"
-                    is-link>
-                    <template #input>
-                        <app-select v-model="formData.CurrencyID" :options="digitalCurrentyList"
-                            @confirm="onCurrentyChange" />
-                    </template>
-                </Field>
+                <app-field-currency name="currency" label="币种" label-align="top" :rules="formRules.currency"
+                    v-model="formData.CurrencyID" @change="onCurrencyChange" />
             </CellGroup>
             <CellGroup inset>
-                <Field name="token" label="网络" label-align="top" placeholder="请选择" :rules="formRules.token"
-                    arrow-direction="down" is-link readonly @click="state.showSheet = true">
-                    <template #input v-if="tokenItem">
-                        {{ tokenItem.name }} ({{ tokenItem.chain_id }})
-                    </template>
-                </Field>
+                <app-field-token name="token" label="网络" label-align="top" :rules="formRules.token"
+                    v-model="state.tokenId" :currency="state.currencyName" @change="onTokenChange" />
             </CellGroup>
             <CellGroup inset>
                 <Field name="Address" v-model="formData.Address" label="地址" label-align="top" placeholder="请输入"
@@ -38,50 +29,30 @@
         <div class="g-form__footer inset">
             <Button type="primary" block @click="formRef?.submit">提现</Button>
         </div>
-        <ActionSheet v-model:show="state.showSheet" title="选择网络">
-            <CellGroup style="min-height: 200px;">
-                <RadioGroup v-model="state.tokenId" v-if="walletTokens.length">
-                    <template v-for="(item, index) in walletTokens" :key="index">
-                        <Cell :title="item.name" :label="item.chain_id" :border="false" clickable center
-                            @click="onRadioClick(item.id)">
-                            <!-- <template #icon>
-                                <Image fit="contain" :src="item.icon_url" width="28" height="28" round style="margin-right: 10px;" />
-                            </template> -->
-                            <template #right-icon>
-                                <Radio :name="item.id" />
-                            </template>
-                        </Cell>
-                    </template>
-                </RadioGroup>
-                <Empty description="暂无数据" v-else />
-            </CellGroup>
-        </ActionSheet>
     </app-view>
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, computed, reactive, onMounted } from 'vue'
-import { FormInstance, FieldRule, Form, Button, CellGroup, Field, Cell, ActionSheet, RadioGroup, Radio, Empty } from 'vant'
+import { shallowRef, computed, reactive } from 'vue'
+import { FormInstance, FieldRule, Form, Button, CellGroup, Field, Cell } from 'vant'
 import { fullloading } from '@/utils/vant'
 import { formatDecimal } from '@/filters'
-import { getDigitalCurrencyList } from '@/constants/order'
-import { useRequest } from '@/hooks/request'
-import { queryWalletTokens, digitalAccountWithdrawApply } from '@/services/api/digital'
+import { digitalAccountWithdrawApply } from '@/services/api/digital'
 import { useNavigation } from '@mobile/router/navigation'
 import { useSpotAccountStore } from '../components/spot/composables'
-import AppSelect from '@mobile/components/base/select/index.vue'
 import AppStepper from '@mobile/components/base/stepper/index.vue'
+import AppFieldCurrency from '@/packages/digital/components/field-currency/index.vue'
+import AppFieldToken from '@/packages/digital/components/field-token/index.vue'
 
 const { getQueryStringToNumber } = useNavigation()
 
+const spotAccountStore = useSpotAccountStore()
 const formRef = shallowRef<FormInstance>()
 const currencyId = getQueryStringToNumber('id')
 
-const spotAccountStore = useSpotAccountStore()
-const digitalCurrentyList = getDigitalCurrencyList()
-
 const state = reactive({
     showSheet: false,
+    currencyName: '',
     tokenId: 0
 })
 
@@ -89,9 +60,7 @@ const formData = reactive<Partial<Proto.DigitalAccountWithdrawApplyReq>>({
     CurrencyID: currencyId
 })
 
-const currentyItem = computed(() => digitalCurrentyList.find((e) => e.enumitemname === formData.CurrencyID))
-
-const tokenItem = computed(() => walletTokens.value.find((e) => e.id === state.tokenId))
+const tokenItem = shallowRef<Model.WalletTokensRsp>()
 
 const accountItem = computed(() => spotAccountStore.getAccountItem({
     currencyid: formData.CurrencyID
@@ -100,16 +69,9 @@ const accountItem = computed(() => spotAccountStore.getAccountItem({
 // 可用余额
 const balance = computed(() => spotAccountStore.getAvailableBalance(accountItem.value))
 
-const { dataList: walletTokens, run: getWalletTokens } = useRequest(queryWalletTokens, {
-    manual: true,
-    onSuccess: () => {
-        walletTokens.value.filter((e) => e.can_withdraw === 1)
-    }
-})
-
 // 表单验证规则
 const formRules: { [key: string]: FieldRule[] } = {
-    currenty: [{
+    currency: [{
         message: '请选择币种',
         validator: () => !!formData.CurrencyID
     }],
@@ -127,21 +89,15 @@ const formRules: { [key: string]: FieldRule[] } = {
     }],
 }
 
-const onCurrentyChange = () => {
+const onCurrencyChange = (item: { label: string; }) => {
     state.tokenId = 0
-
-    if (currentyItem.value) {
-        getWalletTokens({
-            currency: currentyItem.value.label
-        })
-    } else {
-        walletTokens.value = []
-    }
+    state.currencyName = item.label
+    tokenItem.value = undefined
 }
 
-const onRadioClick = (value: number) => {
-    state.tokenId = value
-    state.showSheet = false
+const onTokenChange = (item: Model.WalletTokensRsp) => {
+    tokenItem.value = item
+    formRef.value?.validate('token')
 }
 
 const onSubmit = () => {
@@ -162,8 +118,4 @@ const onSubmit = () => {
         })
     })
 }
-
-onMounted(() => {
-    onCurrentyChange()
-})
 </script>

+ 10 - 0
src/services/api/goods/index.ts

@@ -197,4 +197,14 @@ export function getTCEGoodsCollections(config: RequestConfig = {}) {
         url: '/Goods/GetTCEGoodsCollections',
         params: config.data,
     })
+}
+
+/**
+ * 查询热门商品(按上日成交额,持仓额倒序)
+ */
+export function getHotGoodses(config: RequestConfig) {
+    return http.commonRequest<Model.HotGoodsesRsp[]>({
+        url: '/Common/GetHotGoodses',
+        params: config.data,
+    })
 }

+ 25 - 0
src/types/model/goods.d.ts

@@ -647,4 +647,29 @@ declare namespace Model {
         // 缩略图片(1:1)(1张)
         thumurls: string;
     }
+
+    /** 查询热门商品(按上日成交额,持仓额倒序) 响应 */
+    interface HotGoodsesRsp {
+        bannerurls: string; // Banner图片(2:1)(逗号分隔)
+        buyholdamount: number; // 买持仓额
+        currencyid: number; // 报价货币ID(80:计价货币)
+        decimalplace: number; // 报价小数位
+        goodscode: string; // 商品代码(内部)
+        goodscurrencyid: number; // 合约货币ID(80:基础货币)
+        goodsid: number; // 商品ID
+        goodsname: string; // 商品名称
+        goodsnameen: string; // 期货合约名称(英文)
+        goodsnameth: string; // 期货合约名称泰文)
+        goodsnametw: string; // 期货合约名称(繁体)
+        goodsnamevi: string; // 期货合约名称(越南语)
+        marketid: number; // 市场ID
+        outgoodscode: string; // 商品代码(外部)
+        pictureurl: string; // 商品图片
+        quoteminunit: number; // 行情最小变动单位 [整数,报价小数位一起使用]
+        reckondate: string; // 日期
+        sellholdamount: number; // 卖持仓额
+        thumurls: string; // 缩略图片(1:1)(逗号分隔)
+        tradeamount: number; // 成交额
+        trademode: number; // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
+    }
 }