| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- <template>
- <uni-popup ref="kycRef" type="center" background-color="#fff" style="z-index: 9999">
- <view class="dialog-container">
- <view class="dialog-header">
- <text class="dialog-title">{{ t('blockchain.item2') }}</text>
- <view class="dialog-close" @click="close">
- <text>×</text>
- </view>
- </view>
- <view class="qrcode-page">
- <view class="container">
- <view class="title">{{ t('ApplicationDialog.Des11') }}</view>
- <!-- 二维码 -->
- <view class="qrcode-wrapper">
- <QrCode v-if="qrCodeUrl" :text="qrCodeUrl"></QrCode>
- </view>
- <!-- 说明 -->
- <view class="notice">
- <view class="notice-title">
- <text class="icon">ⓘ</text>
- <text>{{ t('PersonalManagement.KYCVerify.NoticeTitle') }}</text>
- </view>
- <view class="notice-list">
- <text v-for="(item, index) in noticeItems" :key="index" class="notice-item">
- {{ index + 1 }}. {{ item }}
- </text>
- </view>
- </view>
- <!-- 演示视频 -->
- <cwg-video-player :video-url="videoUrl"></cwg-video-player>
- </view>
- </view>
- </view>
- </uni-popup>
- </template>
- <script setup lang="ts">
- import { ref, computed, nextTick } from 'vue'
- import { useI18n } from 'vue-i18n'
- import { customApi } from '@/service/custom';
- import QrCode from "@/components/QrCode.vue";
- const { t, locale } = useI18n()
- // 二维码链接
- const qrCodeUrl = ref("");
- // API 响应码
- const responseCode = ref(200);
- // 设备元信息
- const metaInfo = ref<Record<string, any> | null>(null);
- /**
- * 获取设备元信息
- */
- function getMetaInfo() {
- try {
- // 安全获取 metaInfo,兼容不同环境
- if (typeof window !== "undefined" && (window as any).getMetaInfo) {
- metaInfo.value = (window as any).getMetaInfo();
- metaInfo.value = { ...metaInfo.value, deviceType: "h5" };
- } else {
- // 默认值
- metaInfo.value = { deviceType: "h5" };
- }
- } catch (error) {
- // console.warn("获取设备信息失败:", error);
- metaInfo.value = { deviceType: "h5" };
- }
- }
- /**
- * 获取 WebSDK 链接
- * @param cardId 卡片ID
- */
- async function getWebsdkLink(bankId) {
- if (!bankId) {
- console.warn("bankId 为空,无法获取 WebSDK 链接");
- return;
- }
- try {
- // 获取设备信息
- getMetaInfo();
- // 调用 API
- const res = await customApi.getWebsdkLink2({
- bankId,
- metaInfo: metaInfo.value,
- });
- responseCode.value = res.code || 201;
- if (res.code === 200 && res.data) {
- try {
- // 安全解析 JSON
- const data = typeof res.data === "string" ? JSON.parse(res.data) : res.data;
- qrCodeUrl.value = data.url || data.link || "";
- } catch (parseError) {
- console.error("解析响应数据失败:", parseError);
- responseCode.value = 201;
- }
- } else {
- qrCodeUrl.value = "";
- }
- } catch (error: any) {
- console.error("获取 WebSDK 链接失败:", error);
- responseCode.value = 201;
- qrCodeUrl.value = "";
- }
- }
- // 视频URL
- const videoUrl = computed(() => {
- const lang = locale.value || 'en'
- const videos = {
- cn: "https://player.vimeo.com/video/1153328212?badge=0&autopause=0&player_id=0&app_id=58479",
- zh: "https://player.vimeo.com/video/1153328237?badge=0&autopause=0&player_id=0&app_id=58479",
- en: "https://player.vimeo.com/video/1153328184?badge=0&autopause=0&player_id=0&app_id=58479"
- }
- return videos[lang] || videos.en
- })
- // 说明项
- const noticeItems = computed(() => [
- t('PersonalManagement.KYCVerify.NoticeItem1'),
- t('PersonalManagement.KYCVerify.NoticeItem2'),
- t('PersonalManagement.KYCVerify.NoticeItem3'),
- t('PersonalManagement.KYCVerify.NoticeItem4'),
- t('PersonalManagement.KYCVerify.NoticeItem5'),
- t('PersonalManagement.KYCVerify.NoticeItem6')
- ])
- // 视频错误处理
- const onVideoError = (e) => {
- console.error('视频加载失败', e)
- uni.showToast({
- title: '视频加载失败',
- icon: 'none'
- })
- }
- const kycRef = ref(null)
- // 打开弹窗
- const open = async (e) => {
- await nextTick();
- getWebsdkLink(e)
- kycRef.value?.open();
- };
- // 关闭弹窗
- const close = () => {
- kycRef.value?.close();
- };
- // 暴露方法
- defineExpose({
- open,
- close
- });
- </script>
- <style lang="scss" scoped>
- .dialog-container {
- width: 90vw;
- max-width: px2rpx(800);
- max-height: 85vh;
- background: #fff;
- overflow: hidden;
- display: flex;
- flex-direction: column;
- .dialog-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: px2rpx(20) px2rpx(24);
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- flex-shrink: 0;
- .dialog-title {
- font-size: px2rpx(20);
- font-weight: 700;
- color: #fff;
- letter-spacing: 0.5px;
- }
- .dialog-close {
- width: px2rpx(36);
- height: px2rpx(36);
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: px2rpx(32);
- color: rgba(255, 255, 255, 0.9);
- cursor: pointer;
- transition: all 0.3s;
- border-radius: 50%;
- background: rgba(255, 255, 255, 0.1);
- &:hover {
- background: rgba(255, 255, 255, 0.2);
- transform: rotate(90deg);
- }
- &:active {
- transform: rotate(90deg) scale(0.9);
- }
- }
- }
- }
- .qrcode-page {
- flex: 1;
- overflow-y: auto;
- background: #f8f9fa;
- .container {
- padding: px2rpx(32);
- .title {
- font-size: px2rpx(18);
- font-weight: 600;
- color: #2c3e50;
- text-align: center;
- margin-bottom: px2rpx(24);
- padding-bottom: px2rpx(16);
- border-bottom: 2px solid #e9ecef;
- }
- .qrcode-wrapper {
- display: flex;
- justify-content: center;
- align-items: center;
- margin-bottom: px2rpx(32);
- padding: px2rpx(24);
- background: #fff;
- border-radius: px2rpx(12);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
- .qrcode {
- width: px2rpx(240);
- height: px2rpx(240);
- }
- }
- .notice {
- background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
- border-radius: px2rpx(12);
- padding: px2rpx(24);
- margin-bottom: px2rpx(32);
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
- border-left: 4px solid #667eea;
- .notice-title {
- display: flex;
- align-items: center;
- gap: px2rpx(8);
- font-size: px2rpx(16);
- font-weight: 700;
- color: #2c3e50;
- margin-bottom: px2rpx(16);
- .icon {
- width: px2rpx(24);
- height: px2rpx(24);
- display: flex;
- align-items: center;
- justify-content: center;
- background: #667eea;
- color: #fff;
- border-radius: 50%;
- font-size: px2rpx(16);
- font-weight: bold;
- }
- }
- .notice-list {
- .notice-item {
- display: block;
- font-size: px2rpx(14);
- color: #495057;
- line-height: 1.8;
- margin-bottom: px2rpx(10);
- padding-left: px2rpx(8);
- position: relative;
- &:last-child {
- margin-bottom: 0;
- }
- &::before {
- content: '';
- position: absolute;
- left: 0;
- top: px2rpx(10);
- width: px2rpx(4);
- height: px2rpx(4);
- background: #667eea;
- border-radius: 50%;
- }
- }
- }
- }
- .video-section {
- background: #fff;
- border-radius: px2rpx(12);
- padding: px2rpx(24);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
- .video-title {
- font-size: px2rpx(16);
- font-weight: 600;
- color: #2c3e50;
- margin-bottom: px2rpx(16);
- display: flex;
- align-items: center;
- gap: px2rpx(8);
- &::before {
- content: '';
- width: px2rpx(4);
- height: px2rpx(18);
- background: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
- border-radius: px2rpx(2);
- }
- }
- .video-wrapper {
- width: 100%;
- border-radius: px2rpx(8);
- overflow: hidden;
- background: #000;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
- video {
- width: 100%;
- height: px2rpx(300);
- display: block;
- }
- }
- }
- }
- }
- /* 移动端优化 */
- @media screen and (max-width: 768px) {
- .dialog-container {
- width: 95vw;
- max-height: 90vh;
- }
- .qrcode-page .container {
- padding: px2rpx(20);
- .qrcode-wrapper .qrcode {
- width: px2rpx(200);
- height: px2rpx(200);
- }
- .video-section .video-wrapper video {
- height: px2rpx(240);
- }
- }
- }
- /* 滚动条美化 */
- .qrcode-page::-webkit-scrollbar {
- width: px2rpx(6);
- }
- .qrcode-page::-webkit-scrollbar-track {
- background: #f1f1f1;
- }
- .qrcode-page::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border-radius: px2rpx(3);
- &:hover {
- background: #a8a8a8;
- }
- }
- </style>
|