166 lines
4.1 KiB
Vue
166 lines
4.1 KiB
Vue
<script setup>
|
|
import {showToast} from 'vant';
|
|
import {onMounted, onUnmounted, ref} from 'vue';
|
|
import {signOffline, signOnline} from "~/api/goods/index.js";
|
|
import {VueSignaturePad} from "vue-signature-pad";
|
|
import {authStore} from "~/stores/auth/index.js";
|
|
const router = useRouter();
|
|
definePageMeta({
|
|
layout: ''
|
|
})
|
|
const { userInfo ,payment} = authStore()
|
|
const signaturePad = ref(null);
|
|
const isLandscapeMode = ref(false);
|
|
|
|
const checkScreenOrientation = () => {
|
|
|
|
const orientation = screen.orientation?.type || window.orientation;
|
|
if (orientation === 'landscape-primary' || orientation === 'landscape-secondary' ||
|
|
orientation === 90 || orientation === -90) {
|
|
isLandscapeMode.value = true;
|
|
} else {
|
|
isLandscapeMode.value = false;
|
|
showToast($t('common.landscape'));
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
|
|
nextTick(() => {
|
|
checkScreenOrientation();
|
|
});
|
|
window.addEventListener('orientationchange', checkScreenOrientation);
|
|
screen.orientation?.addEventListener('change', checkScreenOrientation);
|
|
});
|
|
onUnmounted(() => {
|
|
window.removeEventListener('orientationchange', checkScreenOrientation);
|
|
screen.orientation?.removeEventListener('change', checkScreenOrientation);
|
|
});
|
|
const imgUrl = ref('')
|
|
const show = ref(false)
|
|
const clearSignature = () => {
|
|
signaturePad.value?.clearSignature();
|
|
};
|
|
const submitSignature = () => {
|
|
if (signaturePad.value?.isEmpty()) {
|
|
showToast($t('signature.pleaseSign'));
|
|
return;
|
|
}
|
|
const { data } = signaturePad.value?.saveSignature(); // 返回 base64 格式的图片数据
|
|
imgUrl.value = data;
|
|
show.value = true;
|
|
nextTick(() => {
|
|
const overlay = document.querySelector('.signature-container .van-overlay');
|
|
if (overlay) {
|
|
overlay.style.width = '100vw';
|
|
overlay.style.left = '0';
|
|
overlay.style.right = '0';
|
|
}
|
|
})
|
|
};
|
|
const confirm = async () => {
|
|
const res = await signOnline({
|
|
auctionArtworkUuid:payment.value.auctionArtworkUuid,
|
|
signImgFileData: imgUrl.value
|
|
})
|
|
if (res.status===0){
|
|
router.push('/payment')
|
|
}
|
|
}
|
|
const goBack = () => {
|
|
router.back()
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="signature-container bg-gray ">
|
|
<template v-if="isLandscapeMode">
|
|
<div class="signature-content px-10px py-10px">
|
|
<VueSignaturePad
|
|
width="100%"
|
|
class="signature bg-#fff rounded-10px mb-10px"
|
|
ref="signaturePad"
|
|
/>
|
|
<div class="control-buttons justify-evenly">
|
|
<van-button
|
|
class="control-button"
|
|
size="mini"
|
|
type="primary"
|
|
@click="goBack"
|
|
>
|
|
{{ $t('signature.back') }}
|
|
</van-button>
|
|
<van-button
|
|
class="control-button"
|
|
size="mini"
|
|
type="warning"
|
|
@click="clearSignature"
|
|
>
|
|
{{ $t('signature.clear') }}
|
|
</van-button>
|
|
<van-button
|
|
class="control-button"
|
|
size="mini"
|
|
type="primary"
|
|
@click="submitSignature"
|
|
>
|
|
{{ $t('signature.confirm') }}
|
|
</van-button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<div class="orientation-hint">
|
|
<p>{{$t('common.landscape')}}</p>
|
|
</div>
|
|
</template>
|
|
<van-dialog v-model:show="show" class="signature-dialog" show-cancel-button @confirm="confirm">
|
|
<img class="h-100px" :src="imgUrl"/>
|
|
</van-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.signature-container {
|
|
position: fixed;
|
|
inset: 0;
|
|
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) 0;
|
|
}
|
|
|
|
:deep(.van-button--mini+.van-button--mini) {
|
|
margin: 0;
|
|
}
|
|
|
|
:deep(.van-dialog__content) {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.signature-content {
|
|
display: flex;
|
|
height: 100%;
|
|
}
|
|
|
|
|
|
.control-buttons {
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: 0 10px 0;
|
|
gap: 10px;
|
|
}
|
|
|
|
.control-button {
|
|
width: 40px;
|
|
}
|
|
|
|
.orientation-hint {
|
|
position: fixed;
|
|
inset: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background-color: #fff;
|
|
font-size: 18px;
|
|
}
|
|
|
|
</style> |