260 lines
6.3 KiB
Vue
Raw Normal View History

2024-04-28 10:10:03 +08:00
<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`,
2024-05-25 13:53:36 +08:00
header: {
//大家在这里传自定义的token这里默认wflow的
Authorization: "Bearer " + uni.getStorageSync('wflow-token'),
TenantId: JSON.parse(uni.getStorageSync("loginUser")).sn
},
2024-04-28 10:10:03 +08:00
filePath: filePath,
file: file,
name: 'file',
formData: {
isImg: 'true',
isSign: 'true'
},
success: (rsp) => {
if (rsp.statusCode === 200) {
const img = JSON.parse(rsp.data)
2024-05-25 13:53:36 +08:00
// _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}`)
2024-04-28 10:10:03 +08:00
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>