liveh5-nuxt/app/pages/signature/panel/index.vue
xingyy 4bb0f318e3 feat(signature): 实现离线签名功能并优化相关页面
- 新增离线签名 API 接口
- 实现离线签名面板页面,包括签名、清空、确认等功能
- 添加屏幕旋转检测和处理逻辑
- 优化签名协议页面,增加同意并签字按钮
- 移除冗余组件和代码
2025-02-14 15:01:20 +08:00

173 lines
3.8 KiB
Vue

<script setup>
import {showToast} from 'vant';
import {onMounted, onUnmounted, ref} from 'vue';
import {signOffline} from "~/api/goods/index.js";
const router = useRouter();
definePageMeta({
layout: ''
})
const signaturePadRef = 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('请将手机横屏使用');
}
};
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 = () => {
signaturePadRef.value?.resize();
signaturePadRef.value?.clear();
};
const submitSignature = () => {
signaturePadRef.value?.submit();
};
const handleSignatureSubmit = async (data) => {
imgUrl.value = data.image
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 signOffline({
signImgFileData: data.image
})
console.log('res', res)
}
const goBack = () => {
router.back()
}
</script>
<template>
<div class="signature-container">
<template v-if="isLandscapeMode">
<div class="signature-content">
<van-signature
class="signature-pad"
ref="signaturePadRef"
@submit="handleSignatureSubmit"
/>
<div class="control-buttons">
<van-button
class="control-button"
size="mini"
type="primary"
@click="goBack"
>
返回
</van-button>
<van-button
class="control-button"
size="mini"
type="warning"
@click="clearSignature"
>
清空
</van-button>
<van-button
class="control-button"
size="mini"
type="primary"
@click="submitSignature"
>
确认
</van-button>
</div>
</div>
</template>
<template v-else>
<div class="orientation-hint">
<p>请将手机横屏使用</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;
background-color: #fff;
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%;
}
:deep(.van-overlay) {
/* left: initial;*/
}
.signature-pad {
flex-grow: 1;
}
.control-buttons {
display: flex;
flex-direction: column;
padding: 20px 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;
}
:deep(.van-signature__footer) {
display: none;
}
</style>