mirror of
https://gitee.com/myxzgzs/boyue-ui-admin-vue3
synced 2025-08-08 16:32:43 +08:00
增加流程图 小手功能
This commit is contained in:
parent
6b6b634f49
commit
0212ef4851
@ -26,7 +26,15 @@
|
|||||||
</el-button-group>
|
</el-button-group>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-process-model" :style="`transform: scale(${scaleValue / 100});`">
|
<div
|
||||||
|
class="simple-process-model"
|
||||||
|
:style="`transform: translate(${currentX}px, ${currentY}px) scale(${scaleValue / 100});`"
|
||||||
|
@mousedown="startDrag"
|
||||||
|
@mousemove="onDrag"
|
||||||
|
@mouseup="stopDrag"
|
||||||
|
@mouseleave="stopDrag"
|
||||||
|
@mouseenter="setGrabCursor"
|
||||||
|
>
|
||||||
<ProcessNodeTree v-if="processNodeTree" v-model:flow-node="processNodeTree" />
|
<ProcessNodeTree v-if="processNodeTree" v-model:flow-node="processNodeTree" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -80,24 +88,41 @@ let scaleValue = ref(100)
|
|||||||
const MAX_SCALE_VALUE = 200
|
const MAX_SCALE_VALUE = 200
|
||||||
const MIN_SCALE_VALUE = 50
|
const MIN_SCALE_VALUE = 50
|
||||||
|
|
||||||
// 放大
|
const isDragging = ref(false)
|
||||||
const zoomIn = () => {
|
const startX = ref(0)
|
||||||
if (scaleValue.value == MAX_SCALE_VALUE) {
|
const startY = ref(0)
|
||||||
return
|
const currentX = ref(0)
|
||||||
}
|
const currentY = ref(0)
|
||||||
scaleValue.value += 10
|
|
||||||
|
const setGrabCursor = () => {
|
||||||
|
document.body.style.cursor = 'grab';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缩小
|
const resetCursor = () => {
|
||||||
const zoomOut = () => {
|
document.body.style.cursor = 'default';
|
||||||
if (scaleValue.value == MIN_SCALE_VALUE) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
scaleValue.value -= 10
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const processReZoom = () => {
|
const startDrag = (e: MouseEvent) => {
|
||||||
scaleValue.value = 100
|
isDragging.value = true;
|
||||||
|
startX.value = e.clientX - currentX.value;
|
||||||
|
startY.value = e.clientY - currentY.value;
|
||||||
|
setGrabCursor(); // 设置小手光标
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDrag = (e: MouseEvent) => {
|
||||||
|
if (!isDragging.value) return;
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// 使用 requestAnimationFrame 优化性能
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
currentX.value = e.clientX - startX.value;
|
||||||
|
currentY.value = e.clientY - startY.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopDrag = () => {
|
||||||
|
isDragging.value = false;
|
||||||
|
resetCursor(); // 重置光标
|
||||||
}
|
}
|
||||||
|
|
||||||
const errorDialogVisible = ref(false)
|
const errorDialogVisible = ref(false)
|
||||||
@ -193,6 +218,39 @@ const importLocalFile = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 放大
|
||||||
|
const zoomIn = () => {
|
||||||
|
if (scaleValue.value == MAX_SCALE_VALUE) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
scaleValue.value += 10
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缩小
|
||||||
|
const zoomOut = () => {
|
||||||
|
if (scaleValue.value == MIN_SCALE_VALUE) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
scaleValue.value -= 10
|
||||||
|
}
|
||||||
|
|
||||||
|
const processReZoom = () => {
|
||||||
|
scaleValue.value = 100
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.simple-process-model-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple-process-model {
|
||||||
|
position: relative; // 确保相对定位
|
||||||
|
min-width: 100%; // 确保宽度为100%
|
||||||
|
min-height: 100%; // 确保高度为100%
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,19 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" class="process-viewer-container">
|
<div v-loading="loading" class="process-viewer-container">
|
||||||
<div
|
<SimpleProcessViewer
|
||||||
ref="wrapperRef"
|
:flow-node="simpleModel"
|
||||||
class="process-viewer-wrapper"
|
:tasks="tasks"
|
||||||
@mousedown="startDrag"
|
:process-instance="processInstance"
|
||||||
@mousemove="onDrag"
|
/>
|
||||||
@mouseup="stopDrag"
|
|
||||||
@mouseleave="stopDrag"
|
|
||||||
>
|
|
||||||
<SimpleProcessViewer
|
|
||||||
:flow-node="simpleModel"
|
|
||||||
:tasks="tasks"
|
|
||||||
:process-instance="processInstance"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -34,32 +25,6 @@ const tasks = ref([])
|
|||||||
// 流程实例
|
// 流程实例
|
||||||
const processInstance = ref()
|
const processInstance = ref()
|
||||||
|
|
||||||
const wrapperRef = ref<HTMLElement>()
|
|
||||||
const isDragging = ref(false)
|
|
||||||
const startX = ref(0)
|
|
||||||
const startY = ref(0)
|
|
||||||
const currentX = ref(0)
|
|
||||||
const currentY = ref(0)
|
|
||||||
|
|
||||||
const startDrag = (e: MouseEvent) => {
|
|
||||||
if (!wrapperRef.value) return
|
|
||||||
isDragging.value = true
|
|
||||||
startX.value = e.clientX - currentX.value
|
|
||||||
startY.value = e.clientY - currentY.value
|
|
||||||
}
|
|
||||||
|
|
||||||
const onDrag = (e: MouseEvent) => {
|
|
||||||
if (!isDragging.value || !wrapperRef.value) return
|
|
||||||
e.preventDefault()
|
|
||||||
currentX.value = e.clientX - startX.value
|
|
||||||
currentY.value = e.clientY - startY.value
|
|
||||||
wrapperRef.value.style.transform = `translate(${currentX.value}px, ${currentY.value}px)`
|
|
||||||
}
|
|
||||||
|
|
||||||
const stopDrag = () => {
|
|
||||||
isDragging.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 监控模型视图 包括任务列表、进行中的活动节点编号等 */
|
/** 监控模型视图 包括任务列表、进行中的活动节点编号等 */
|
||||||
watch(
|
watch(
|
||||||
() => props.modelView,
|
() => props.modelView,
|
||||||
@ -119,7 +84,8 @@ const setSimpleModelNodeTaskStatus = (
|
|||||||
// 审批节点
|
// 审批节点
|
||||||
if (
|
if (
|
||||||
simpleModel.type === NodeType.START_USER_NODE ||
|
simpleModel.type === NodeType.START_USER_NODE ||
|
||||||
simpleModel.type === NodeType.USER_TASK_NODE
|
simpleModel.type === NodeType.USER_TASK_NODE ||
|
||||||
|
simpleModel.type === NodeType.TRANSACTOR_NODE
|
||||||
) {
|
) {
|
||||||
simpleModel.activityStatus = TaskStatusEnum.NOT_START
|
simpleModel.activityStatus = TaskStatusEnum.NOT_START
|
||||||
if (rejectedTaskActivityIds.includes(simpleModel.id)) {
|
if (rejectedTaskActivityIds.includes(simpleModel.id)) {
|
||||||
@ -205,24 +171,4 @@ const setSimpleModelNodeTaskStatus = (
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.process-viewer-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.process-viewer-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
cursor: grab;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user