feat:合同列表

This commit is contained in:
李伊帆
2026-09-17 15:48:51 +08:00
parent 8394da7ecb
commit 0e80de4548
15 changed files with 1369 additions and 7 deletions

View File

@@ -0,0 +1,168 @@
<script setup lang="ts">
import { getCurrentInstance, nextTick, ref, watch } from 'vue'
const props = defineProps<{
visible: boolean
}>()
const emit = defineEmits<{
close: []
confirm: [imagePath: string]
}>()
const instance = getCurrentInstance()
const hasStroke = ref(false)
const canvasWidth = ref(300)
const canvasHeight = ref(500)
let ctx: UniApp.CanvasContext | null = null
let drawing = false
let lastX = 0
let lastY = 0
watch(
() => props.visible,
async (visible) => {
if (!visible)
return
await nextTick()
const query = uni.createSelectorQuery().in(instance)
query.select('#signature-canvas').boundingClientRect((rect) => {
if (rect && !Array.isArray(rect)) {
canvasWidth.value = rect.width
canvasHeight.value = rect.height
}
initCanvas()
}).exec()
},
)
function initCanvas() {
ctx = uni.createCanvasContext('signature-canvas', instance)
ctx.setStrokeStyle('#1a1a1a')
ctx.setLineWidth(3)
ctx.setLineCap('round')
ctx.setLineJoin('round')
clearCanvas()
}
function clearCanvas() {
if (!ctx)
return
ctx.clearRect(0, 0, canvasWidth.value, canvasHeight.value)
ctx.draw()
hasStroke.value = false
}
function getTouchPoint(event: TouchEvent) {
const touch = event.touches[0] || event.changedTouches[0]
return { x: touch.x, y: touch.y }
}
function handleTouchStart(event: TouchEvent) {
if (!ctx)
return
const point = getTouchPoint(event)
lastX = point.x
lastY = point.y
drawing = true
}
function handleTouchMove(event: TouchEvent) {
if (!drawing || !ctx)
return
const point = getTouchPoint(event)
ctx.beginPath()
ctx.moveTo(lastX, lastY)
ctx.lineTo(point.x, point.y)
ctx.stroke()
ctx.draw(true)
lastX = point.x
lastY = point.y
hasStroke.value = true
}
function handleTouchEnd() {
drawing = false
}
function handleConfirm() {
if (!hasStroke.value) {
uni.showToast({ title: '请先签名', icon: 'none' })
return
}
uni.canvasToTempFilePath({
canvasId: 'signature-canvas',
success: (res) => {
emit('confirm', res.tempFilePath)
},
fail: () => {
emit('confirm', '')
},
}, instance)
}
function handleClose() {
emit('close')
}
</script>
<template>
<view
v-if="visible"
class="signature-pad"
>
<view class="signature-pad__body">
<view class="signature-pad__actions">
<view
class="signature-pad__action-btn"
@tap="clearCanvas"
>
清除重写
</view>
<view
class="signature-pad__action-btn"
@tap="handleConfirm"
>
确认签署
</view>
</view>
<view class="signature-pad__canvas-wrap">
<canvas
id="signature-canvas"
canvas-id="signature-canvas"
class="signature-pad__canvas"
disable-scroll
@touchstart.stop.prevent="handleTouchStart"
@touchmove.stop.prevent="handleTouchMove"
@touchend.stop.prevent="handleTouchEnd"
/>
<text
v-if="!hasStroke"
class="signature-pad__placeholder"
>
我是签名
</text>
</view>
</view>
<view
class="signature-pad__close"
@tap="handleClose"
>
<text class="signature-pad__close-icon">
×
</text>
</view>
</view>
</template>
<style scoped lang="scss">
@import './SignaturePad.scss';
</style>