400 lines
8.9 KiB
Vue
400 lines
8.9 KiB
Vue
<template>
|
||
<div class="card">
|
||
<div class="header">
|
||
<div class="return" @click="returnHandle">
|
||
<el-icon class="icon">
|
||
<ArrowLeftBold />
|
||
</el-icon>
|
||
</div>
|
||
<div class="right">
|
||
<div class="t1" v-if="props.type == 0">
|
||
<span class="title">应收:¥</span>
|
||
<span class="num">{{ money }}</span>
|
||
</div>
|
||
<div class="t1" v-else>
|
||
<span class="title">会员:</span>
|
||
<span class="num">{{
|
||
props.userInfo.id && props.userInfo.telephone
|
||
}}</span>
|
||
</div>
|
||
<div class="t2">
|
||
<span>已付:¥0.00</span>
|
||
<span>优惠:¥0.00</span>
|
||
</div>
|
||
</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" class="img"></el-image>
|
||
</div>
|
||
<span class="title">{{ item.payName }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="input_wrap">
|
||
<div class="input" style="flex: 1">储值:¥{{ money }}</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" fast :amount="money" :selecttype="props.type" :orderId="props.userInfo.id"
|
||
@success="scanCodeSuccess" />
|
||
<takeFoodCode ref="takeFoodCodeRef" title="支付密码" :type="2" input-type="password" placeholder="请输入支付密码"
|
||
@success="passwordSuccess" />
|
||
</template>
|
||
|
||
<script setup>
|
||
import { onMounted, ref } from "vue";
|
||
import { queryPayType, quickPay } from "@/api/pay";
|
||
import {
|
||
queryMembermember,
|
||
createMembermember,
|
||
membermemberScanPay,
|
||
accountPaymember,
|
||
} from "@/api/member/index.js";
|
||
import { useUser } from "@/store/user.js";
|
||
import { clearNoNum } from "@/utils";
|
||
import md5 from "js-md5";
|
||
|
||
import scanModal from "@/components/payCard/scanModal.vue";
|
||
import { ElMessage } from "element-plus";
|
||
import takeFoodCode from "@/components/takeFoodCode.vue";
|
||
const takeFoodCodeRef = ref(null);
|
||
|
||
const props = defineProps({
|
||
type: {
|
||
type: [String, Number],
|
||
default: 0, // 1快捷收银 2会员支付
|
||
},
|
||
userInfo: {
|
||
type: Object,
|
||
default: {},
|
||
},
|
||
});
|
||
|
||
const store = useUser();
|
||
|
||
const emit = defineEmits(["paySuccess", "close"]);
|
||
|
||
const money = ref("0");
|
||
const scanModalRef = ref(null);
|
||
|
||
const payActive = ref(0);
|
||
const payList = ref([]);
|
||
const payLoading = ref(false);
|
||
|
||
function returnHandle() {
|
||
emit("close");
|
||
}
|
||
|
||
// 获得扫码值
|
||
function scanCodeSuccess() {
|
||
emit("paySuccess");
|
||
}
|
||
|
||
// 切换支付类型
|
||
function payTypeChange(index, item) {
|
||
if (item.payType == "scanCode") {
|
||
if (money.value > 0) {
|
||
scanModalRef.value.show();
|
||
} else {
|
||
ElMessage.error("请输入金额");
|
||
return;
|
||
}
|
||
}
|
||
payActive.value = index;
|
||
}
|
||
|
||
// 获取支付密码
|
||
async function passwordSuccess(e) {
|
||
try {
|
||
payLoading.value = true;
|
||
await accountPaymember({
|
||
shopId: store.userInfo.shopId,
|
||
memberId: props.userInfo.id,
|
||
amount: money.value,
|
||
pwd: md5(e),
|
||
});
|
||
payLoading.value = false;
|
||
ElMessage.success("支付成功");
|
||
emit("paySuccess");
|
||
} catch (error) {
|
||
payLoading.value = false;
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
// 结算支付
|
||
async function confirmOrder() {
|
||
if (payLoading.value) return;
|
||
try {
|
||
if (payList.value[payActive.value].payType == "scanCode") {
|
||
if (money.value <= 0) {
|
||
ElMessage.error("请输入金额");
|
||
return;
|
||
}
|
||
scanModalRef.value.show();
|
||
} else {
|
||
if (money.value <= 0) {
|
||
ElMessage.error("请输入金额");
|
||
return;
|
||
}
|
||
switch (payList.value[payActive.value].payType) {
|
||
case "cash": //现金
|
||
if (props.type == 0) {
|
||
payLoading.value = true;
|
||
await quickPay({
|
||
amount: money.value,
|
||
authCode: "",
|
||
payType: payList.value[payActive.value].payType,
|
||
});
|
||
payLoading.value = false;
|
||
ElMessage.success("支付成功");
|
||
emit("paySuccess");
|
||
} else {
|
||
// 会员充值
|
||
takeFoodCodeRef.value.show();
|
||
// passwordSuccess()
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
payLoading.value = false;
|
||
scanModalRef.value.loading = false;
|
||
}
|
||
}
|
||
|
||
// 输入
|
||
function amountInput(num) {
|
||
money.value = clearNoNum({ value: (money.value += num) });
|
||
}
|
||
|
||
// 删除
|
||
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,
|
||
});
|
||
|
||
const arr = [];
|
||
res.map((item) => {
|
||
if (item.payType == "cash" || item.payType == "scanCode") {
|
||
arr.push(item);
|
||
}
|
||
});
|
||
|
||
payList.value = arr;
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
function reset() {
|
||
money.value = 0;
|
||
payActive.value = 0;
|
||
}
|
||
|
||
defineExpose({ reset });
|
||
|
||
onMounted(() => {
|
||
queryPayTypeAjax();
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.card {
|
||
padding: var(--el-font-size-base);
|
||
height: 100%;
|
||
}
|
||
|
||
.header {
|
||
padding-bottom: var(--el-font-size-base);
|
||
border-bottom: 1px solid #ececec;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.return {
|
||
$size: 50px;
|
||
width: $size;
|
||
height: $size;
|
||
border-radius: 50%;
|
||
border: 2px solid #333;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 20px;
|
||
|
||
.icon {
|
||
color: #333;
|
||
font-size: var(--el-font-size-base);
|
||
}
|
||
}
|
||
|
||
.right {
|
||
.t1 {
|
||
display: flex;
|
||
color: var(--el-color-danger);
|
||
font-weight: bold;
|
||
|
||
.title {
|
||
font-size: var(--el-font-size-base);
|
||
position: relative;
|
||
top: 14px;
|
||
}
|
||
|
||
.num {
|
||
font-size: 30px;
|
||
}
|
||
}
|
||
|
||
.t2 {
|
||
display: flex;
|
||
gap: var(--el-font-size-base);
|
||
color: #999;
|
||
padding-top: 10px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.number_wrap {
|
||
padding: var(--el-font-size-base) 0;
|
||
|
||
.menus {
|
||
display: flex;
|
||
gap: var(--el-font-size-base);
|
||
|
||
.item {
|
||
height: 130px;
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background-color: #efefef;
|
||
padding: 10px 0;
|
||
border-radius: 10px;
|
||
position: relative;
|
||
$lineHeight: 4px;
|
||
|
||
&.active {
|
||
&::after {
|
||
content: "";
|
||
width: 50%;
|
||
height: $lineHeight;
|
||
background-color: var(--primary-color);
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 25%;
|
||
border-radius: $lineHeight;
|
||
}
|
||
}
|
||
|
||
.img {
|
||
$size: 40px;
|
||
width: $size;
|
||
height: $size;
|
||
}
|
||
|
||
.title {
|
||
padding-top: 10px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.input_wrap {
|
||
display: flex;
|
||
gap: var(--el-font-size-base);
|
||
padding: var(--el-font-size-base) 0;
|
||
|
||
.input {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 60px;
|
||
border-radius: 6px;
|
||
border: 1px solid var(--primary-color);
|
||
font-size: calc(var(--el-font-size-base) + 6px);
|
||
padding: 0 var(--el-font-size-base);
|
||
}
|
||
}
|
||
|
||
.blance {
|
||
color: var(--el-color-danger);
|
||
font-size: calc(var(--el-font-size-base) + 10px);
|
||
}
|
||
}
|
||
|
||
.keybord_wrap {
|
||
display: flex;
|
||
|
||
.left {
|
||
--item-height: calc((100vh - 440px) / 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: var(--el-font-size-base);
|
||
|
||
.item {
|
||
background-color: #efefef;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 6px;
|
||
font-size: calc(var(--el-font-size-base) + 10px);
|
||
|
||
&:active {
|
||
background-color: #dbdbdb;
|
||
}
|
||
}
|
||
}
|
||
|
||
.pay_btn {
|
||
flex: 0.3;
|
||
border-radius: 6px;
|
||
color: #fff;
|
||
background-color: var(--el-color-warning);
|
||
margin-left: var(--el-font-size-base);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: calc(var(--el-font-size-base) + 10px);
|
||
}
|
||
}
|
||
</style>
|