对接完毕下单

This commit is contained in:
gyq
2024-03-04 15:48:40 +08:00
parent 6e796c1855
commit 27721ca096
21 changed files with 1010 additions and 237 deletions

View File

@@ -0,0 +1,311 @@
<template>
<div class="card">
<div class="header">
<div class="t1">
<span class="title">应收:</span>
<span class="num">{{ props.amount }}</span>
</div>
<div class="t2">
<span>已付:0.00</span>
<span>优惠:0.00</span>
</div>
</div>
<div class="number_wrap">
<div class="menus">
<div class="item" :class="{ active: payActive == index }" v-for="(item, index) in payList"
:key="item.id" @click="payTypeChange(index, item)">
<div class="icon">
<el-image :src="item.icon" style="width: 50px;height: 50px;"></el-image>
</div>
<span class="title">{{ item.payName }}</span>
</div>
</div>
<div class="input_wrap">
<div class="input" style="flex: 1;">储值:{{ money }}</div>
<div class="input" v-if="waitPayMoney > 0">待支付:{{ waitPayMoney }}</div>
</div>
<div class="blance">
<!-- 可用余额0.00 -->
</div>
<div class="keybord_wrap">
<div class="left">
<div class="item" v-for="item in 9" :key="item" @click="amountInput(`${item}`)">{{ item }}</div>
<div class="item" @click="amountInput('.')">.</div>
<div class="item" @click="amountInput('0')">0</div>
<div class="item" @click="delHandle">
<el-icon>
<CloseBold />
</el-icon>
</div>
</div>
<div class="pay_btn" v-loading="payLoading" @click="confirmOrder">
<span></span>
<span></span>
</div>
</div>
</div>
</div>
<scanModal ref="scanModalRef" :amount="props.amount" :orderId="props.orderId" @success="scanCodeSuccess" />
</template>
<script setup>
import { onMounted, ref, computed, watch } from 'vue'
import { queryPayType, accountPay, cashPay } from '@/api/pay'
import { useUser } from "@/store/user.js"
import { clearNoNum } from '@/utils'
import scanModal from '@/components/payCard/scanModal.vue'
import { ElMessage } from "element-plus";
const store = useUser()
const props = defineProps({
amount: {
type: Number,
default: 0
},
orderId: {
type: [String, Number],
default: ''
}
})
const emit = defineEmits(['paySuccess'])
const money = ref('0')
const scanModalRef = ref(null)
watch(props, (value) => {
money.value = `${props.amount}`
})
const waitPayMoney = computed(() => {
let num = JSON.stringify(props.amount - money.value)
num = Math.floor(num * 100) / 100
return num
})
const payActive = ref(0)
const payList = ref([])
const payLoading = ref(false)
// 获得扫码值
function scanCodeSuccess() {
emit('paySuccess')
}
// 切换支付类型
function payTypeChange(index, item) {
payActive.value = index
if (item.payType == 'scanCode') {
scanModalRef.value.show()
}
}
// 结算支付
async function confirmOrder() {
try {
if (money.value < props.amount) return
payLoading.value = true
switch (payList.value[payActive.value].payType) {
case 'deposit':
await accountPay({
orderId: props.orderId,
memberId: 1
})
break;
case 'cash':
await cashPay({
orderId: props.orderId
})
break;
default:
break;
}
ElMessage.success('支付成功')
emit('paySuccess')
payLoading.value = false
} catch (error) {
console.log(error)
payLoading.value = false
scanModalRef.value.loading = false
}
}
// 输入
function amountInput(num) {
if (money.value + num <= props.amount) {
money.value = clearNoNum({ value: (money.value += num) })
} else {
money.value = clearNoNum({ value: `${props.amount}` })
}
}
// 删除
function delHandle() {
if (!money.value) return
money.value = money.value.substring(0, money.value.length - 1)
if (!money.value) {
money.value = '0'
}
}
// 获取支付方式
async function queryPayTypeAjax() {
try {
const res = await queryPayType({
shopId: store.userInfo.shopId
})
payList.value = res
} catch (error) {
console.log(error)
}
}
onMounted(() => {
money.value = `${props.amount}`
queryPayTypeAjax()
})
</script>
<style scoped lang="scss">
.card {
padding: 20px;
height: 100%;
}
.header {
padding-bottom: 30px;
border-bottom: 1px solid #ececec;
.t1 {
display: flex;
color: var(--el-color-danger);
font-weight: bold;
.title {
font-size: 24px;
position: relative;
top: 14px;
}
.num {
font-size: 40px;
}
}
.t2 {
display: flex;
gap: 20px;
color: #999;
padding-top: 10px;
}
}
.number_wrap {
padding: 20px 0;
.menus {
display: flex;
gap: 20px;
.item {
height: 196px;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #efefef;
padding: 50px 0;
border-radius: 10px;
position: relative;
$lineHeight: 4px;
&.active {
&::after {
content: "";
width: 60%;
height: $lineHeight;
background-color: var(--primary-color);
position: absolute;
bottom: 0;
left: 20%;
border-radius: $lineHeight;
}
}
.icon {
font-size: 30px;
}
.title {
padding-top: 10px;
}
}
}
.input_wrap {
display: flex;
gap: 20px;
padding: 20px 0;
.input {
display: flex;
align-items: center;
height: 80px;
border-radius: 10px;
border: 1px solid var(--primary-color);
font-size: 26px;
font-weight: 400;
padding: 0 30px;
}
}
.blance {
color: var(--el-color-danger);
font-size: 26px;
}
}
.keybord_wrap {
display: flex;
padding-top: 20px;
.left {
--item-height: calc((100vh - 650px) / 4);
flex: 1;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: var(--item-height) var(--item-height) var(--item-height) var(--item-height);
gap: 20px;
.item {
background-color: #efefef;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
font-size: 28px;
&:active {
background-color: #dbdbdb;
}
}
}
.pay_btn {
border-radius: 6px;
width: 200px;
color: #fff;
background-color: var(--el-color-warning);
margin-left: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 26px;
}
}
</style>