223 lines
5.0 KiB
Vue
223 lines
5.0 KiB
Vue
<script setup lang="ts">
|
||
import { computed, watch } from 'vue';
|
||
import { useI18n } from "vue-i18n";
|
||
import c1 from "@/assets/img/b4f258fb3fcfa.svg";
|
||
import c2 from "@/assets/img/d9f501073fcfa.svg";
|
||
import c3 from "@/assets/img/761998023fcfa.svg";
|
||
import c4 from "@/assets/img/272b931f3fcfa.svg";
|
||
import c5 from "@/assets/img/d2820b3b3fcfa.svg";
|
||
import c6 from "@/assets/img/e62e66803fcfa.svg";
|
||
import c7 from "@/assets/img/c8e88e5f3fcfa.svg";
|
||
import c8 from "@/assets/img/1a32e1333fcfa.svg";
|
||
import c9 from "@/assets/img/mir.jpg";
|
||
const { t } = useI18n(); // 解构出t方法
|
||
|
||
interface Props {
|
||
cardNumber: string;
|
||
showModal: boolean;
|
||
}
|
||
|
||
interface Emits {
|
||
(e: 'update:showModal', value: boolean): void;
|
||
}
|
||
|
||
const props = defineProps<Props>();
|
||
const emit = defineEmits<Emits>();
|
||
|
||
const price = 'Gs. 294.000';
|
||
|
||
const formattedPrice = computed(() => {
|
||
return price.replace(/\.(\d{3})$/, '$1');
|
||
});
|
||
|
||
const cardType = computed(() => {
|
||
const num = props.cardNumber.replace(/\D/g, '');
|
||
if (/^4/.test(num)) return 'Visa';
|
||
if (/^(5[1-5]|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[0-1][0-9]|2720)/.test(num)) return 'Mastercard';
|
||
if (/^(62|81)/.test(num)) return 'UnionPay';
|
||
if (/^3[347]/.test(num)) return 'Amex';
|
||
if (/^(6011|64[4-9]|65|62212[6-9]|6221[3-9][0-9]|622[2-8][0-9]{2}|6229[0-2][0-5])/.test(num)) return 'Discover';
|
||
if (/^35(2[8-9]|[3-8][0-9])/.test(num)) return 'JCB';
|
||
if (/^(30|36|38|39)/.test(num)) return 'DinersClub';
|
||
if (/^(50|5[6-8]|6[^2])/.test(num)) return 'Maestro';
|
||
if (/^220[0-4]/.test(num)) return 'Mir';
|
||
return 'Generic';
|
||
});
|
||
|
||
// 监听 showModal,触发支付逻辑
|
||
watch(
|
||
() => props.showModal,
|
||
(newVal) => {
|
||
if (newVal && props.cardNumber) {
|
||
|
||
}
|
||
}
|
||
);
|
||
</script>
|
||
|
||
<template>
|
||
<div class="payment-modal1">
|
||
<div v-if="showModal" class="modal1">
|
||
<div class="modal1-content">
|
||
<div class="card-logo">
|
||
<img
|
||
v-if="cardType === 'Visa'"
|
||
:src="c1"
|
||
alt="Visa"
|
||
/>
|
||
<img
|
||
v-else-if="cardType === 'Mastercard'"
|
||
:src="c2"
|
||
alt="Mastercard"
|
||
/>
|
||
<img
|
||
v-else-if="cardType === 'UnionPay'"
|
||
:src="c4"
|
||
alt="UnionPay"
|
||
/>
|
||
<img
|
||
v-else-if="cardType === 'Amex'"
|
||
:src="c5"
|
||
alt="Amex"
|
||
/>
|
||
<img
|
||
v-else-if="cardType === 'Discover'"
|
||
:src="c6"
|
||
alt="Discover"
|
||
/>
|
||
<img
|
||
v-else-if="cardType === 'JCB'"
|
||
:src="c3"
|
||
alt="JCB"
|
||
/>
|
||
<img
|
||
v-else-if="cardType === 'DinersClub'"
|
||
:src="c8"
|
||
alt="Diners Club"
|
||
/>
|
||
<img
|
||
v-else-if="cardType === 'Maestro'"
|
||
:src="c7"
|
||
alt="Maestro"
|
||
/>
|
||
<img
|
||
v-else-if="cardType === 'Mir'"
|
||
:src="c9"
|
||
alt="Mir"
|
||
/>
|
||
<svg
|
||
v-else
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
viewBox="0 0 64 40"
|
||
fill="none"
|
||
stroke="#3498db"
|
||
stroke-width="1.5"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<rect x="2" y="2" width="60" height="36" rx="4" fill="#f5f5f5" />
|
||
<rect x="8" y="8" width="14" height="10" fill="#d4a017" />
|
||
<path d="M8 23 h48" />
|
||
<path d="M8 27 h32" />
|
||
<path d="M8 31 h24" />
|
||
<circle cx="50" cy="12" r="3" fill="#ccc" />
|
||
</svg>
|
||
</div>
|
||
<h3 class="title">{{ t("Processing payment") }}</h3>
|
||
<p class= "desc">{{ t("Please do not refresh or close the page") }}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.payment-modal1 {
|
||
font-family: Arial, sans-serif;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.modal1 {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 1000;
|
||
}
|
||
|
||
.modal1-content {
|
||
background-color: white;
|
||
padding: 50px 20px;
|
||
border-radius: 8px;
|
||
text-align: center;
|
||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||
max-width: 300px;
|
||
width: 100%;
|
||
}
|
||
|
||
.card-logo {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-bottom: 15px;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.card-logo img {
|
||
height: 70px;
|
||
object-fit: contain;
|
||
}
|
||
|
||
.card-logo svg {
|
||
height: 50px;
|
||
width: 80px;
|
||
}
|
||
|
||
.card-logo::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: -100%;
|
||
width: 30%;
|
||
height: 100%;
|
||
background: linear-gradient(
|
||
90deg,
|
||
transparent,
|
||
rgba(255, 255, 255, 0.7),
|
||
transparent
|
||
);
|
||
animation: scan 2s infinite;
|
||
}
|
||
|
||
@keyframes scan {
|
||
0% {
|
||
left: -100%;
|
||
}
|
||
100% {
|
||
left: 100%;
|
||
}
|
||
}
|
||
|
||
.price {
|
||
font-size: 1.2em;
|
||
color: #333;
|
||
margin-bottom: 10px;
|
||
}
|
||
.title {
|
||
font-size: 1.2em;
|
||
font-weight: 400;
|
||
}
|
||
|
||
.desc {
|
||
font-size: 0.9em;
|
||
color: #666;
|
||
margin-top: 5px;
|
||
margin-bottom: 0;
|
||
}
|
||
</style> |