withdraw.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <route lang="json5" type="page">
  2. {
  3. layout: 'default',
  4. style: {
  5. navigationStyle: 'custom',
  6. navigationBarTitleText: '%wallet.withdraw.title%',
  7. },
  8. }
  9. </route>
  10. <script lang="ts" setup>
  11. import { getConfigByCode } from '@/api/common'
  12. import { withdrawAdd } from '@/api/wallet'
  13. import { t } from '@/locale'
  14. import { useUserStore } from '@/store'
  15. import { formatNumber } from '@/utils'
  16. import { goBack, toPage } from '@/utils/page'
  17. import { toast } from '@/utils/toast'
  18. defineOptions({
  19. name: 'Withdraw', // 提现
  20. })
  21. const userStore = useUserStore()
  22. const userInfo = computed(() => getUserInfoHook())
  23. const queryParams = ref<any>({})
  24. // 表单数据
  25. const formData = ref({
  26. amount: '',
  27. bank: userInfo.value.bank,
  28. bankAccountName: userInfo.value.bankAccountName,
  29. bankAccount: userInfo.value.bankAccount,
  30. currency: 'BDT',
  31. })
  32. const bankColumns = [
  33. { label: 'BKASH', value: 'BKASH' },
  34. { label: 'NAGAD', value: 'NAGAD' },
  35. { label: 'ROCKET', value: 'ROCKET' },
  36. ]
  37. // 提现限制(从配置中获取)
  38. const withdrawMinAmount = ref<number>(300)
  39. const withdrawMaxAmount = ref<number>(20000)
  40. const loading = ref<boolean>(false)
  41. async function submit() {
  42. if (!formData.value.bank) {
  43. toast.info(t('wallet.withdraw.error.bankName'))
  44. return
  45. }
  46. if (!formData.value.bankAccountName) {
  47. toast.info(t('wallet.withdraw.error.bankAccountName'))
  48. return
  49. }
  50. if (!formData.value.bankAccount) {
  51. toast.info(t('wallet.withdraw.error.bankAccountNo'))
  52. return
  53. }
  54. if (!formData.value.amount) {
  55. toast.info(t('wallet.withdraw.error.amount'))
  56. return
  57. }
  58. // 校验金额是否为有效数字
  59. const amount = Number(formData.value.amount)
  60. if (Number.isNaN(amount)) {
  61. toast.info(t('wallet.withdraw.error.amount'))
  62. return
  63. }
  64. // 校验金额范围
  65. if (amount < withdrawMinAmount.value) {
  66. toast.info(t('wallet.withdraw.notes.4', [formatNumber(withdrawMinAmount.value), formatNumber(withdrawMaxAmount.value)]))
  67. return
  68. }
  69. if (amount > withdrawMaxAmount.value) {
  70. toast.info(t('wallet.withdraw.notes.4', [formatNumber(withdrawMinAmount.value), formatNumber(withdrawMaxAmount.value)]))
  71. return
  72. }
  73. // 校验余额是否充足
  74. const balance = Number(queryParams.value.balance)
  75. if (amount > balance) {
  76. toast.info(t('wallet.withdraw.error.amount'))
  77. return
  78. }
  79. loading.value = true
  80. try {
  81. const res = await withdrawAdd({ ...formData.value, accountType: queryParams.value.type, channel: formData.value.bank })
  82. console.log(res)
  83. if (res.code === '200') {
  84. userStore.getUserInfo()
  85. toast.success(t('wallet.withdraw.success'))
  86. setTimeout(() => {
  87. goBack()
  88. }, 1500)
  89. }
  90. else {
  91. toast.error(res.message || t('wallet.withdraw.fail'))
  92. }
  93. }
  94. finally {
  95. loading.value = false
  96. }
  97. }
  98. const withdrawRate = ref<any>()
  99. async function getConfig() {
  100. try {
  101. // 获取提现费率
  102. const rateRes = await getConfigByCode({ code: queryParams.value.type === '2' ? 'earning_withdraw_rate' : 'withdraw_rate' })
  103. withdrawRate.value = rateRes.data.valueInfo
  104. // 获取最小提现金额
  105. const minRes = await getConfigByCode({ code: 'min_withdraw_amount' })
  106. if (minRes.code === '200' && minRes.data.valueInfo) {
  107. withdrawMinAmount.value = Number(minRes.data.valueInfo)
  108. }
  109. // 获取最大提现金额
  110. const maxRes = await getConfigByCode({ code: 'max_withdraw_amount' })
  111. if (maxRes.code === '200' && maxRes.data.valueInfo) {
  112. withdrawMaxAmount.value = Number(maxRes.data.valueInfo)
  113. }
  114. }
  115. catch {
  116. }
  117. }
  118. // 计算服务费
  119. const serviceFee = computed(() => {
  120. const amount = Number(formData.value.amount)
  121. if (!amount || Number.isNaN(amount) || !withdrawRate.value) {
  122. return '0.00'
  123. }
  124. const rate = Number(withdrawRate.value)
  125. return formatNumber(amount * (rate / 100))
  126. })
  127. onLoad((options) => {
  128. queryParams.value = options
  129. getConfig()
  130. })
  131. </script>
  132. <template>
  133. <view class="min-h-100vh flex flex-col bg-#FEE750">
  134. <wd-navbar
  135. custom-class="bg-#FEE750!"
  136. :bordered="false"
  137. safe-area-inset-top placeholder fixed
  138. :title="t('wallet.withdraw.title')"
  139. >
  140. <template #left>
  141. <wd-icon name="thin-arrow-left" size="32rpx" @click="() => goBack()" />
  142. </template>
  143. <template #right>
  144. <text class="text-28rpx" @click="toPage({ url: '/pages/wallet/withdrawRecord', params: { type: queryParams.type } })">
  145. {{ $t('wallet.withdraw.record') }}
  146. </text>
  147. </template>
  148. </wd-navbar>
  149. <view class="px-28rpx pb-28rpx pt-40rpx">
  150. <view class="text-28rpx">
  151. {{ $t(queryParams.type === '2' ? 'wallet.withdraw.balanceRevenue' : 'wallet.withdraw.balanceWallet') }}
  152. </view>
  153. <view>
  154. <text class="text-28rpx">
  155. </text>
  156. <text class="text-48rpx font-bold">
  157. {{ formatNumber(queryParams.balance) }}
  158. </text>
  159. </view>
  160. </view>
  161. <view class="flex-1 rounded-t-24rpx bg-white p-24rpx">
  162. <view class="mb-28rpx text-32rpx">
  163. {{ $t('wallet.withdraw.info') }}
  164. </view>
  165. <wd-form ref="form" :model="formData" custom-class="mb-28rpx">
  166. <view class="mb-40rpx space-y-32rpx">
  167. <wd-picker v-model="formData.bank" :disabled="Boolean(userInfo.bank)" :columns="bankColumns" use-default-slot>
  168. <wd-input
  169. v-model="formData.bank"
  170. :placeholder="t('wallet.withdraw.form.bankName')"
  171. no-border
  172. readonly
  173. custom-class="bandhu-auth-input-field"
  174. :disabled="Boolean(userInfo.bank)"
  175. />
  176. </wd-picker>
  177. <wd-input
  178. v-model="formData.bankAccountName"
  179. :placeholder="t('wallet.withdraw.form.bankAccountName')"
  180. no-border
  181. custom-class="bandhu-auth-input-field"
  182. :disabled="Boolean(userInfo.bankAccountName)"
  183. />
  184. <wd-input
  185. v-model="formData.bankAccount"
  186. :placeholder="t('wallet.withdraw.form.bankAccountNo')"
  187. no-border
  188. custom-class="bandhu-auth-input-field"
  189. :disabled="Boolean(userInfo.bankAccountName)"
  190. />
  191. <view class="flex items-center gap-20rpx">
  192. <wd-input
  193. v-model="formData.amount"
  194. :placeholder="t('wallet.withdraw.form.amount')"
  195. no-border
  196. custom-class="flex-1 bandhu-auth-input-field"
  197. type="digit"
  198. />
  199. <wd-button
  200. type="error"
  201. plain
  202. custom-class="bandhu-auth-secondary-btn"
  203. @click="formData.amount = queryParams.balance"
  204. >
  205. {{ $t('wallet.withdraw.form.allAmount') }}
  206. </wd-button>
  207. </view>
  208. <view class="text-24rpx">
  209. Service Fee:৳{{ serviceFee }}
  210. </view>
  211. </view>
  212. <wd-button plain block custom-class="h-80rpx!" :loading="loading" @click="submit">
  213. {{ $t('wallet.withdraw.form.submit') }}
  214. </wd-button>
  215. </wd-form>
  216. <view class="text-24rpx text-#5A5A5A line-height-48rpx">
  217. {{ $t('wallet.withdraw.notes.title') }}
  218. <br>
  219. {{ $t('wallet.withdraw.notes.1') }}
  220. <br>
  221. {{ $t('wallet.withdraw.notes.2') }}
  222. <br>
  223. {{ $t('wallet.withdraw.notes.3') }}
  224. <br>
  225. {{ t('wallet.withdraw.notes.4', [formatNumber(withdrawMinAmount), formatNumber(withdrawMaxAmount)]) }}
  226. <br>
  227. {{ t('wallet.withdraw.notes.5', [withdrawRate]) }}
  228. </view>
  229. </view>
  230. </view>
  231. </template>
  232. <style lang="scss" scoped>
  233. //
  234. </style>