Files
qhmes/jeecgboot-vue3/src/components/ApprovalDesign/index.vue

114 lines
3.7 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.
<!--
全局审批流程设计悬浮按钮
拥有 approval:flow:design 权限的用户在任意功能页点击即可
1后端按当前页路由反查绑定的业务表
2解析该表字段识别校对/审核/审批/分发/抄送等阶段字段不存在不报错
3进入可视化设计器可点选识别到的阶段字段按顺序生成审批流程并保存发布
@author GHT
@date 2026-05-29 forQH-MES审批流设计全局审批流程设计悬浮按钮
-->
<template>
<div v-if="show" class="approval-design-float" :style="floatStyle">
<div class="approval-design-btn" :class="{ 'is-loading': loading }" title="审批流程设计" @click="openDesigner">
<Icon :icon="loading ? 'ant-design:loading-outlined' : 'ant-design:partition-outlined'" :size="20" :spin="loading" />
<span class="approval-design-text">流程设计</span>
</div>
<!-- 流程设计器全屏 -->
<FlowDesign @register="registerDesign" @success="onSuccess" />
</div>
</template>
<script lang="ts" setup>
import { computed, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { useMessage } from '/@/hooks/web/useMessage';
import { usePermission } from '/@/hooks/web/usePermission';
import { useModal } from '/@/components/Modal';
import { getApprovalDesignContext } from '/@/views/approval/flow/approvalFlow.api';
import FlowDesign from '/@/views/approval/flow/components/FlowDesign.vue';
defineOptions({ name: 'ApprovalDesignFloat' });
const { createMessage } = useMessage();
const { currentRoute } = useRouter();
const { hasPermission } = usePermission();
const [registerDesign, { openModal: openDesign }] = useModal();
const loading = ref(false);
// 悬浮位置(位于「发起审批」按钮上方)
const floatStyle = reactive({ right: '24px', bottom: '190px' });
// 仅拥有设计权限的用户可见
const show = computed(() => hasPermission('approval:flow:design'));
function normalizePath(p?: string) {
return (p || '').trim().replace(/\/+$/, '');
}
async function openDesigner() {
if (loading.value) return;
const path = normalizePath(currentRoute.value?.path);
if (!path) return;
try {
loading.value = true;
const ctx: any = await getApprovalDesignContext(path);
if (!ctx || !ctx.bizTable || !ctx.flow) {
createMessage.info('当前页面未能识别到可绑定的业务单据,无法设计审批流程');
return;
}
openDesign(true, {
record: ctx.flow,
readonly: false,
paletteStages: ctx.stages || [],
});
} catch (e: any) {
createMessage.error(e?.message || '获取设计上下文失败');
} finally {
loading.value = false;
}
}
function onSuccess() {
createMessage.success('审批流程已保存');
}
</script>
<style lang="less" scoped>
.approval-design-float {
position: fixed;
z-index: 999;
.approval-design-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(135deg, #15bca3, #0e9e88);
color: #fff;
cursor: pointer;
box-shadow: 0 4px 14px rgba(21, 188, 163, 0.45);
transition: transform 0.18s, box-shadow 0.18s;
user-select: none;
.approval-design-text {
font-size: 11px;
line-height: 1;
transform: scale(0.92);
}
&:hover {
transform: scale(1.08);
box-shadow: 0 6px 20px rgba(21, 188, 163, 0.6);
}
&.is-loading {
cursor: progress;
}
}
}
</style>