2024-05-25 13:53:36 +08:00

260 lines
6.3 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.

<template>
<view>
<view class="w-form-input-rv" v-if="readonly">
<image v-if="(_value || '') !== ''" :src="_value" mode="aspectFit" style="width: 250rpx; height: 150rpx;">
</image>
<text v-else style="color: #8b8b8b;">未签字</text>
</view>
<view v-else-if="(props.modelValue || '').length < 10" @click="show"
class="w-sign-init">
<uni-icons type="compose" color="#B3B3B3" size="20"></uni-icons>
<text>{{formProps.placeholder ? formProps.placeholder:'点击签名'}}</text>
</view>
<view v-else>
<image :src="_value" mode="aspectFit" style="width: 250rpx; height: 150rpx;"
@click="show"></image>
<text>点击签名重签</text>
</view>
<uni-popup v-if="!readonly" ref="signatureRef">
<view class="w-sign" :style="{height: wheight + 'px'}">
<view>
<text class="w-sign-tip">请签字</text>
<l-signature ref="SignPanel" v-if="showPanel" class="w-sign-panel"
disableScroll :landscape="true" :beforeDelay="300" :maxLineWidth="10"
:penSize="formProps.thickness + 3" :penColor="formProps.color" :openSmooth="true">
</l-signature>
</view>
<view :class="{'w-sign-opration': true, 'w-landscape': landscape}">
<view @click="SignPanel.clear()" hover-class="w-sop">
<uni-icons type="trash" color="#E79467" :size="30"></uni-icons>
<text style="color: #E79467;">清空</text>
</view>
<view @click="SignPanel.undo()" hover-class="w-sop">
<uni-icons type="undo" color="#5B6AF7" :size="30"></uni-icons>
<text>撤销</text>
</view>
<view @click="SignPanel.redo()" hover-class="w-sop">
<uni-icons type="redo" color="#5B6AF7" :size="30"></uni-icons>
<text>恢复</text>
</view>
<view @click="save" hover-class="w-sop">
<uni-icons type="checkmarkempty" color="#5B6AF7" :size="30"></uni-icons>
<text>保存</text>
</view>
<view @click="signatureRef.close()" hover-class="w-sop">
<uni-icons type="closeempty" color="#8b8b8b" :size="30"></uni-icons>
<text style="color: #8b8b8b;">关闭</text>
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { ref, computed, getCurrentInstance } from 'vue'
import { compressBase64Image } from "@/utils/imageUtil";
import { BASE_URL } from '@/api/request.js'
import { base64ToPath } from '@/uni_modules/lime-signature/components/l-signature/utils.js'
const props = defineProps({
formProps: {
type: Object,
default: () => {
return {}
}
},
modelValue: String,
readonly: Boolean,
position: {
type: String,
default: 'right'
}
})
const wheight = uni.getSystemInfoSync().windowHeight
const _value = computed({
get() {
return props.modelValue
},
set(val) {
emits('update:modelValue', val)
}
})
const emits = defineEmits(['update:modelValue'])
const signatureRef = ref()
const SignPanel = ref()
const landscape = ref(true)
const showPanel = ref(false)
function show(){
signatureRef.value.open(props.position)
showPanel.value = true
}
function save(call) {
SignPanel.value.canvasToTempFilePath({
quality: 0.2,
success: (res) => {
// 是否为空画板 无签名
if (res.isEmpty) {
uni.showToast({
icon: 'none',
title: '您没有签字哦'
})
return
}
console.log('签字图片路径',res.tempFilePath)
if(res.tempFilePath.startsWith('data:image/')){
// #ifdef H5
const file = base64ToFile(res.tempFilePath, `${new Date().getTime()}.png`)
uploadSign(file)
// #endif
// #ifndef H5
base64ToPath(res.tempFilePath).then(tp => {
uploadSign(null, tp)
})
// #endif
}else {
uploadSign(null, res.tempFilePath)
}
}
})
}
function uploadSign(file, filePath) {
uni.uploadFile({
url: `${BASE_URL}/wflow/res`,
header: {
//大家在这里传自定义的token这里默认wflow的
Authorization: "Bearer " + uni.getStorageSync('wflow-token'),
TenantId: JSON.parse(uni.getStorageSync("loginUser")).sn
},
filePath: filePath,
file: file,
name: 'file',
formData: {
isImg: 'true',
isSign: 'true'
},
success: (rsp) => {
if (rsp.statusCode === 200) {
const img = JSON.parse(rsp.data)
// _value.value = `${BASE_URL}/wflow/res/${img.id}?isSign=true`
_value.value = `${BASE_URL}/image/${img.id}?isSign=true`
// openLocalFile(file.name, `${BASE_URL}/image/${file.id}?name=${file.name}`)
signatureRef.value.close()
} else {
uni.showToast({
icon: 'none',
title: '签名失败:' + rsp.data
})
}
},
fail: (err) => {
console.log(err)
uni.showToast({
icon: 'none',
title: '签名上传异常'
})
}
});
}
function base64ToFile(base64, name) {
if (typeof base64 != 'string') {
return;
}
var arr = base64.split(',')
var type = arr[0].match(/:(.*?);/)
if (type && type.length > 1) {
type = type[1]
}else{
type = 'image/png'
}
var fileExt = type.split('/')[1]
var bstr = atob(arr[1])
var n = bstr.length
var u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], `${name}.` + fileExt, {
type: type
})
}
</script>
<style lang="less" scoped>
.w-sop {
background-color: #e5e5e5;
}
.w-sign-init {
padding: 16rpx;
display: flex;
color: #a7a7a7;
align-items: center;
justify-content: center;
background-color: #F7F7F7;
border-radius: 5px;
}
.w-sign-panel {
width: 100%;
height: 100%;
}
.w-sign {
width: 100vw;
//height: 100vh;
display: flex;
align-items: center;
flex-direction: column;
position: relative;
background-color: white;
.w-sign-tip {
position: absolute;
transform: rotate(90deg);
color: #CDCDCD;
font-size: 64rpx;
}
&>view:first-child {
width: 80%;
height: 80%;
border: 2px dashed #CDCDCD;
display: flex;
justify-content: center;
align-items: center;
background-color: #F6F6F6;
}
.w-sign-opration {
background-color: white;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
view {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: #5B6AF7;
margin: 10px;
transform: rotate(90deg);
padding: 10px;
border-radius: 5px;
}
}
}
</style>