钱包转账
This commit is contained in:
1 parent
fb82c9d3a1
commit
03adc25ca2
10 files changed
+722
-481
No files matched your search
@@ -9,63 +9,7 @@
|
||||
</tm-sheet>
|
||||
<tm-button class="mt-40" :block="true" @click="disabled ? '' : handlePay()" :disabled="disabled">支付</tm-button>
|
||||
|
||||
<view class="bg-[#f5f5f5] px-1 py-2 rounded-4 absolute bottom-0 w-full">
|
||||
<view class="flex mb-2.5" v-for="(row, rowIndex) in keyboardLayout" :key="rowIndex">
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
v-for="(key, keyIndex) in row"
|
||||
:key="keyIndex"
|
||||
@click="handleKeyPress(key)"
|
||||
>
|
||||
{{ key }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex mb-0">
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleKeyPress('.')"
|
||||
>
|
||||
.
|
||||
</view>
|
||||
<view
|
||||
class="flex-auto h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleKeyPress('0')"
|
||||
>
|
||||
0
|
||||
</view>
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleDelete"
|
||||
>
|
||||
<svg
|
||||
t="1742457305987"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="4499"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path
|
||||
d="M897.706667 831.146667H286.72c-8.533333 0-15.36-3.413333-20.48-10.24L39.253333 527.36c-6.826667-8.533333-6.826667-22.186667 0-30.72l226.986667-293.546667c5.12-6.826667 11.946667-10.24 20.48-10.24h610.986667c51.2 0 92.16 40.96 92.16 92.16v453.973334c0 51.2-40.96 92.16-92.16 92.16z m-599.04-51.2h599.04c22.186667 0 40.96-18.773333 40.96-40.96V285.013333c0-22.186667-18.773333-40.96-40.96-40.96H298.666667L92.16 512l206.506667 267.946667z"
|
||||
fill="#333333"
|
||||
p-id="4500"
|
||||
></path>
|
||||
<path
|
||||
d="M670.72 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667L426.666667 416.426667c-10.24-10.24-10.24-25.6 0-35.84 10.24-10.24 25.6-10.24 35.84 0l226.986666 226.986666c10.24 10.24 10.24 25.6 0 35.84-6.826667 5.12-11.946667 6.826667-18.773333 6.826667z"
|
||||
fill="#333333"
|
||||
p-id="4501"
|
||||
></path>
|
||||
<path
|
||||
d="M443.733333 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667-10.24-10.24-10.24-25.6 0-35.84l226.986667-226.986666c10.24-10.24 25.6-10.24 35.84 0 10.24 10.24 10.24 25.6 0 35.84L462.506667 643.413333c-5.12 5.12-11.946667 6.826667-18.773334 6.826667z"
|
||||
fill="#333333"
|
||||
p-id="4502"
|
||||
></path>
|
||||
</svg>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<numberKeyboard v-model="amount" />
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -78,13 +22,9 @@ import payApi from "@@/api/pay"
|
||||
import { storePrice } from "@/sheep/utils/formatMoney"
|
||||
import { router } from "@/sheep"
|
||||
import { merchantApi } from "@/sheep/api"
|
||||
import numberKeyboard from "@/sheep/components/numberKeyboard.vue"
|
||||
|
||||
const amount = ref("")
|
||||
const keyboardLayout = ref([
|
||||
["1", "2", "3"],
|
||||
["4", "5", "6"],
|
||||
["7", "8", "9"],
|
||||
])
|
||||
const scanData = ref<{ id?: string; name?: string }>({})
|
||||
const disabled = ref(false)
|
||||
|
||||
@@ -113,27 +53,6 @@ const displayAmount = computed(() => {
|
||||
)
|
||||
})
|
||||
|
||||
// 按下键盘
|
||||
const handleKeyPress = (key) => {
|
||||
if (key === "." && amount.value.includes(".")) return
|
||||
if (key === "." && !amount.value) {
|
||||
amount.value = "0."
|
||||
return
|
||||
}
|
||||
|
||||
if (amount.value.includes(".")) {
|
||||
const decimalPlaces = amount.value.split(".")[1]
|
||||
if (decimalPlaces && decimalPlaces.length >= 2) return
|
||||
}
|
||||
|
||||
amount.value += key
|
||||
}
|
||||
|
||||
// 点击删除
|
||||
const handleDelete = () => {
|
||||
amount.value = amount.value.slice(0, -1)
|
||||
}
|
||||
|
||||
// 点击支付
|
||||
const handlePay = () => {
|
||||
if (!scanData.value.id || !scanData.value.name) return uni.showToast({ title: "扫码信息不存在", icon: "none" })
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
<template>
|
||||
<view class="bg-gray-100 flex-col min-h-screen">
|
||||
<view class="flex-row items-center justify-center my-2">
|
||||
<text class="text-lg font-bold">转入{{ state.targetWalletTypeName }}</text>
|
||||
</view>
|
||||
|
||||
<tm-cell
|
||||
title="转入方式"
|
||||
icon="money-cny-circle-fill"
|
||||
icon-color="#0779FD"
|
||||
iconSize="64"
|
||||
:label="state.sourceWalletTypeName"
|
||||
labelColor="#7f7f7f"
|
||||
labelSize="30"
|
||||
@click="sourceWalletSelect"
|
||||
/>
|
||||
|
||||
<tm-sheet>
|
||||
<text class="text-gray-700 font-bold text-lg">转入金额</text>
|
||||
<view class="flex-row items-center">
|
||||
<text class="text-3xl text-[#333] mr-2">¥</text>
|
||||
<text v-if="!amount" class="text-xl text-gray-300">转入金额</text>
|
||||
<text v-else class="text-3xl">{{ formattedAmount }}</text>
|
||||
</view>
|
||||
</tm-sheet>
|
||||
<!-- 金额限制提示 -->
|
||||
<view class="h-30rpx">
|
||||
<view v-if="storePrice(amount) > curSourceWallet?.balance" class="text-xs c-red px-8">注:转账金额不能超过钱包余额</view>
|
||||
</view>
|
||||
|
||||
<view class="p-4 font-bold mt-10">
|
||||
<tm-button block @click="confirmTransfer">确定转入</tm-button>
|
||||
</view>
|
||||
|
||||
<number-keyboard v-model="amount" />
|
||||
|
||||
<!-- 选择转入方式 -->
|
||||
<tm-drawer
|
||||
v-model:show="show"
|
||||
title="选择转入方式"
|
||||
size="50%"
|
||||
bg-color="#efefef"
|
||||
position="bottom"
|
||||
:show-footer="true"
|
||||
:showClose="true"
|
||||
>
|
||||
<view class="m-4">
|
||||
<view
|
||||
v-for="(v, index) in state.walletList"
|
||||
:key="index"
|
||||
class="card mb-2 overflow-hidden relative border-4 border-solid border-white duration-200 flex justify-between items-center p-4"
|
||||
:class="{ 'border-4 border-solid border-blue!': state.sourceWalletTypeId == v.walletTypeId }"
|
||||
@click="state.sourceWalletTypeId = v.walletTypeId"
|
||||
>
|
||||
<view class="flex items-center">
|
||||
<image class="w-70 h-70 mr-2" :src="filePath(v.walletTypeIcon)" />
|
||||
<view class="flex flex-col">
|
||||
<view class="main-text-32">{{ v.walletTypeName }}</view>
|
||||
<view class="text-gray-500 text-sm">{{ v.cardNumber }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="main-text-32">余额:{{ hooks.useMoney(v.balance) + "元" }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<template #footer>
|
||||
<tm-button block @click="confirmSourceWallet" class="flex-1 font-bold">确定</tm-button>
|
||||
</template>
|
||||
</tm-drawer>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import NumberKeyboard from "@/sheep/components/numberKeyboard.vue"
|
||||
import { payApi, walletApi } from "@/sheep/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
import { storePrice } from "@/sheep/utils/formatMoney"
|
||||
|
||||
const amount = ref("")
|
||||
const show = ref(false)
|
||||
const state = reactive<any>({
|
||||
targetWalletTypeId: "",
|
||||
targetWalletTypeName: "",
|
||||
walletList: [],
|
||||
sourceWalletTypeId: "",
|
||||
sourceWalletTypeName: "",
|
||||
})
|
||||
const curSourceWallet = computed(() => {
|
||||
if (!state.sourceWalletTypeId) {
|
||||
state.sourceWalletTypeId = state.walletList[0]?.walletTypeId
|
||||
state.sourceWalletTypeName = state.walletList[0]?.walletTypeName
|
||||
return state.walletList[0]
|
||||
}
|
||||
return state.walletList.find((item: any) => item.walletTypeId == state.sourceWalletTypeId)
|
||||
})
|
||||
|
||||
onLoad(async (options) => {
|
||||
if (options?.walletTypeId) {
|
||||
state.targetWalletTypeId = options.walletTypeId
|
||||
state.targetWalletTypeName = options.walletTypeName
|
||||
} else {
|
||||
uni.showToast({ title: "钱包id不存在", icon: "none" })
|
||||
}
|
||||
const res = await walletApi.all()
|
||||
if (res.code == 0) {
|
||||
state.walletList = res.data.records.filter((item: any) => item.walletTypeId != state.targetWalletTypeId)
|
||||
}
|
||||
})
|
||||
|
||||
// 源钱包选择
|
||||
const sourceWalletSelect = () => {
|
||||
state.sourceWalletTypeId = ""
|
||||
show.value = true
|
||||
}
|
||||
|
||||
// 确认源钱包
|
||||
const confirmSourceWallet = () => {
|
||||
show.value = false
|
||||
state.sourceWalletTypeName = state.walletList.find((item: any) => item.walletTypeId == state.sourceWalletTypeId).walletTypeName
|
||||
}
|
||||
|
||||
// 格式化金额显示
|
||||
const formattedAmount = computed(() => {
|
||||
if (!amount.value) return ""
|
||||
|
||||
// 处理小数点情况
|
||||
if (amount.value.endsWith(".")) {
|
||||
return amount.value
|
||||
}
|
||||
|
||||
const parts = amount.value.split(".")
|
||||
// 添加千位分隔符
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")
|
||||
|
||||
// 处理小数部分
|
||||
if (parts.length > 1) {
|
||||
// 如果小数部分不足两位,不自动补零
|
||||
return `${parts[0]}.${parts[1]}`
|
||||
}
|
||||
|
||||
return parts[0]
|
||||
})
|
||||
|
||||
// 确认转账
|
||||
const confirmTransfer = async () => {
|
||||
if (!amount.value || amount.value === "0" || amount.value === "0." || parseFloat(amount.value) === 0) {
|
||||
return uni.showToast({ title: "金额不能为零", icon: "none" })
|
||||
}
|
||||
const numAmount = storePrice(parseFloat(amount.value.endsWith(".") ? amount.value.slice(0, -1) : amount.value))
|
||||
if (numAmount > curSourceWallet.value.balance) {
|
||||
return uni.showToast({ title: "转账金额不能超过钱包余额", icon: "none" })
|
||||
}
|
||||
|
||||
// console.log("state.sourceWalletTypeId", state.sourceWalletTypeId)
|
||||
// console.log("state.targetWalletTypeId", state.targetWalletTypeId)
|
||||
// console.log("金额", numAmount)
|
||||
|
||||
uni.showModal({
|
||||
title: "确定转入吗?",
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
uni.showLoading({ title: "正在转入...", mask: true })
|
||||
const res = await payApi.transferMoney({
|
||||
sourceWalletTypeId: state.sourceWalletTypeId,
|
||||
targetWalletTypeId: state.targetWalletTypeId,
|
||||
balance: numAmount,
|
||||
})
|
||||
if (res.code == 0) {
|
||||
uni.showToast({ title: "转账成功", icon: "success" })
|
||||
router.jump("/pages/wallet/list", {}, 2)
|
||||
} else {
|
||||
uni.showToast({ title: res.msg, icon: "none" })
|
||||
}
|
||||
} catch (error: any) {
|
||||
uni.showToast({
|
||||
title: error.message,
|
||||
icon: "none",
|
||||
})
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -119,6 +119,11 @@ const doFreeze = async () => {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 转账
|
||||
const doTransferMoney = (v: any) => {
|
||||
router.jump("/pages/pay/transferMoney", { walletTypeId: v.walletTypeId, walletTypeName: v.walletTypeName }, 2)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -173,6 +178,7 @@ const doFreeze = async () => {
|
||||
</view>
|
||||
<view class="flex-row items-center justify-end space-x-20rpx m-t-10rpx">
|
||||
<!-- <view v-if="v.walletTypeUniqueCode == 1 && !v.cardNumber" class="botder_btn" @tap.stop="openBindDialog(v)">绑定</view> -->
|
||||
<view class="botder_btn" @tap.stop="doTransferMoney(v)">转入</view>
|
||||
<view v-if="v.walletTypeUniqueCode == 1 && v.cardNumber && v.isFreeze != 1" class="botder_btn" @tap.stop="openFreezeDialog(v)">
|
||||
申请冻结
|
||||
</view>
|
||||
|
||||
Reference in new issue
Block a user