Vue3 + Ant Design 工作流低代码开发包:拖拽设计流程图,支持会签、并行、自由流审批
简介:基于 Vue3 和 ant-design-vue 深度封装的工作流前端解决方案,内置可视化流程设计器,支持节点拖拽、连线配置、属性面板实时编辑。开箱即用钉钉风格审批界面,覆盖流程发起、任务办理、驳回退回等核心操作。完整兼容多种流程模式:串行流转、并行分支、会签(多人同时审批)、自由流(无固定路径)及服务任务调用。提供统一状态管理(Pinia)、响应式布局组件、主题变量定制和样式隔离方案,适配中后台系统快速接入。配套资源齐全:含 demo.jpg 展示效果、setting.jpg 设计参考图、多环境变量配置(.env.development)、ESLint/Stylelint/Prettier 代码规范、VS Code 推荐插件与调试配置(extensions. / launch.)、构建配置(vue.config.js / babel.config.js)以及完整项目结构(router、store、views、utils 等模块清晰划分),支持团队协作开发与按需二次扩展。
1. 项目概述:这不是又一个“画流程图”的组件,而是一套能真正跑起来的审批系统前端骨架
你有没有遇到过这样的场景:业务方拿着一张手绘的审批流程图来找你,“张工,这个报销要先部门负责人批,再财务复核,但财务如果觉得金额超限,得拉上分管副总一起会签;如果副总出差了,就自动转给代理副总——下周上线,能搞定吗?”你翻遍 npm,搜“vue workflow designer”,出来的全是只能拖拽连线、双击改个节点名字的 demo 级库。画得挺美,一跑流程就卡在“怎么把这张图变成可执行逻辑”这一步。我去年在三个中后台项目里反复踩坑,最后干脆把整套东西从头拧出来——不是封装一个设计器,而是把“设计→发布→运行→监控”整个闭环的前端部分,用 Vue3 和 ant-design-vue 深度咬合,做成了一套开箱即用的开发包。
核心关键词就五个:Vue3工作流、流程设计器、会签审批、ant-design-vue、并行流程。注意,这里说的“工作流”不是指 BPMN 标准那种重型引擎的前端界面,而是面向国内中后台真实业务场景的轻量级落地方案。它默认就长成钉钉审批那个味儿:顶部进度条+步骤卡片+操作按钮组+附件区+评论流,所有样式、交互、状态流转都预置好了。你不用再为“驳回后流程怎么跳转”、“会签人全部点完同意按钮才进下一环节”这种细节写一堆 if-else。它内置的状态管理(Pinia)已经按“流程实例生命周期”做了分层:processInstance 存全局上下文(如当前节点ID、发起人、创建时间),taskList 管当前待办任务池(含会签任务聚合),nodeStatus 记每个节点的实时状态(待处理/已通过/被驳回/超时)。连“自由流”这种反模式需求都考虑到了——不是放任用户乱连,而是提供“动态分支决策节点”,允许在节点配置面板里写一段 JS 表达式(比如 form.amount > 50000 ? 'vp_approve' : 'finance_review'),运行时由前端解析执行,真正实现“所见即所得”的逻辑闭环。
这套东西的目标用户非常明确:中后台系统的前端工程师,尤其是那些需要快速交付审批类模块、又不想自己从零搭状态机、不希望被 BPMN 复杂规范绑架的团队。它不替代后端流程引擎(比如 Flowable 或自研服务),而是做最薄、最稳的那一层——把后端返回的 JSON 流程定义,精准翻译成用户可理解、可操作、可追溯的 UI。配套的 demo.jpg 不是效果图,是真实运行截图;setting.jpg 也不是 UI 设计稿,是设计器属性面板的实拍,连“并行分支数”滑块的默认值都标出来了;.env.development 里甚至预置了 mock 接口开关和本地调试 token。这不是一个玩具,是你明天就能 git clone 进去,改两行配置,下午就提测的生产级脚手架。
2. 整体架构与设计思路:为什么放弃 BPMN,选择“JSON Schema + 前端状态机”?
很多人第一反应是:“为什么不直接集成 bpmn-js?它多标准啊。” 我试过,在三个项目里都推不动。原因很实在:BPMN 是给流程建模专家用的,不是给业务方和前端工程师用的。我们让业务方画 BPMN 图,结果他画了个带泳道的复杂图,然后问:“这个‘事件子流程’怎么在钉钉里显示成一个弹窗?”——问题不在技术,而在语义鸿沟。所以这套方案的核心设计哲学就一条:流程定义必须是前端可读、可维护、可调试的 JSON,而不是 XML 或二进制 blob。
整个架构分三层,像三明治一样压得特别紧:
第一层是 可视化设计器(smart-flow-designer)。它没用任何第三方 canvas 库,而是基于 antd 的 Draggable 和 Droppable 做的纯 DOM 拖拽。节点不是 SVG 元素,而是 <a-card> 包裹的 FlowNode 组件;连线不是贝塞尔曲线,而是用 CSS transform: rotate() + position: absolute 实现的箭头 div。好处是什么?调试时你能直接在 Elements 面板里看到每个节点对应的真实 Vue 组件实例,console.log(nodeRef) 就能看到它的 props 和 emits。连线数据结构极其简单:{ from: 'nodeA', to: 'nodeB', type: 'parallel' }。没有 bpmn:SequenceFlow 这种冗余命名空间,只有业务语言。
第二层是 流程定义 Schema(flow-definition-schema.json)。这是整个方案的“宪法”。它规定了合法流程图的 JSON 结构,比如:
{
"id": "leave_approval_v2",
"name": "请假审批",
"nodes": [
{
"id": "start",
"type": "startEvent",
"name": "发起申请"
},
{
"id": "dept_leader",
"type": "userTask",
"name": "部门负责人审批",
"assignee": "deptLeader"
},
{
"id": "parallel_branch",
"type": "parallelGateway",
"name": "并行分支",
"branches": ["finance", "hr"]
}
],
"edges": [
{"from": "start", "to": "dept_leader"},
{"from": "dept_leader", "to": "parallel_branch"}
]
}
注意 parallelGateway 节点里的 branches 字段——它不是 BPMN 里的“出边集合”,而是明确声明“接下来要同时激活 finance 和 hr 两个任务”。后端只要按这个结构返回 JSON,前端就能立刻渲染出并行审批的待办列表。会签节点同理,type: "multiUserTask" 加 minApprove: 2,状态管理器就知道“等两个人点同意才算通过”。
第三层是 运行时状态机(flow-runtime-store)。这是 Pinia store 的核心,它不依赖任何外部库,只做三件事:
1. 解析 Schema:把上面的 JSON 转成内存中的节点拓扑图,构建邻接表;
2. 驱动流转:当用户点击“提交”或“同意”,store 根据当前节点类型(串行/并行/会签)计算下一个任务集;
3. 同步 UI:触发 taskList 和 nodeStatus 的响应式更新,antd 组件自动重绘。
为什么不用 Vuex 或更重的状态库?因为流程状态天然就是树状、不可变、有明确生命周期的。Pinia 的 defineStore + computed 足够干净。比如会签完成判断,store 里就一行:
const isMultiTaskApproved = computed(() =>
currentTask.value?.type === 'multiUserTask' &&
(currentTask.value.approvedUsers?.length || 0) >= (currentTask.value.minApprove || 1)
)
没有魔法,全是可读、可断点、可单测的代码。
这套架构放弃“标准兼容性”,换来了“交付确定性”。业务方改个会签人数,前端只需要改 minApprove 字段,不用重新部署后端、不用学 BPMN 建模工具、不用等运维发版。这才是中后台开发该有的节奏。
3. 核心组件与实操要点:从拖拽设计器到钉钉风审批页,每一步都在解决真问题
3.1 可视化设计器:拖拽不是目的,精准配置才是关键
设计器 (SmartFlowDesigner.vue) 的 UI 分三栏:左侧节点库、中间画布、右侧属性面板。但重点不在布局,而在几个反直觉的设计细节:
-
节点库不是静态图标:
<a-icon type="solution" />这种图标下面,实际绑定了nodeType和defaultConfig。比如“并行网关”节点,拖进去时自动注入:js { id: `gateway_${Date.now()}`, type: 'parallelGateway', name: '并行分支', branches: ['task1', 'task2'] // 默认两个分支 }
这样业务方第一次拖拽,就得到一个可运行的并行结构,而不是一个空壳。 -
连线逻辑强制校验:不允许
startEvent → endEvent直连,也不允许userTask → userTask(缺少网关)。画布上每建立一条线,都会调用validateEdge(from, to)函数:ts const validateEdge = (from: string, to: string) => { const fromNode = getNodeById(from) const toNode = getNodeById(to) // 串行流:userTask → userTask 允许 // 并行流:parallelGateway → userTask 允许,反之不行 // 会签流:multiUserTask → parallelGateway 允许(用于会签后分叉) return rules[fromNode.type]?.includes(toNode.type) ?? false }
这个规则表是硬编码在设计器里的,比 BPMN 的元模型校验快十倍,且完全可控。 -
属性面板实时双向绑定:右侧面板不是简单的
v-model,而是深度监听nodeConfig的每一个 key。比如修改“会签最小通过数”,面板立刻触发:ts watch(() => nodeConfig.value.minApprove, (newVal) => { // 同步更新画布上该节点的 badge 显示 updateNodeBadge(nodeId, `需${newVal}人`) // 如果当前是运行态,立即通知 runtime store 重新计算状态 if (isRunning.value) flowRuntimeStore.recalcCurrentStatus() })
这意味着你在设计器里调参数,就像在调试一个活的系统,而不是在配一个静态图。
3.2 钉钉风格审批页:不是像素级还原,而是交互逻辑复刻
ApprovalView.vue 是这套方案的门面。它没用任何 CSS-in-JS 库,而是基于 antd 的 theme 变量和 @import '~ant-design-vue/lib/style/themes/default.less' 做的深度定制。关键在于三个“钉钉味儿”交互:
-
顶部进度条(ProgressStepper):不是简单的
a-steps。它根据flowRuntimeStore.nodeStatus动态生成步骤:vue <a-steps :current="currentStepIndex"> <a-step v-for="(node, idx) in orderedNodes" :key="node.id" :title="node.name" :status="getNodeStatus(node.id)" :description="getNodeDesc(node.id)" /> </a-steps>getNodeStatus返回'wait' | 'process' | 'finish' | 'error',其中process状态会高亮当前节点,并在右侧卡片区聚焦显示该任务表单。 -
任务卡片(TaskCard):每个卡片包含三块:基础信息(申请人、时间)、表单域(
<a-form-item>动态渲染)、操作区(同意/驳回/转交)。难点在“表单域动态渲染”。我们没用v-for遍历字段,而是用defineAsyncComponent按字段类型懒加载组件:ts const fieldComponents = { text: () => import('./fields/TextField.vue'), number: () => import('./fields/NumberField.vue'), select: () => import('./fields/SelectField.vue'), attachment: () => import('./fields/AttachmentField.vue') }
这样即使一个流程有 50 个字段,首屏也只加载当前卡片需要的那几个组件,性能不崩。 -
会签任务聚合显示(MultiTaskAggregator):这是最体现业务洞察的设计。当一个会签任务有 5 个人待处理,页面不会显示 5 张重复卡片,而是:
```vue【会签任务】请与以下同事共同审批: {{ user.name }}
`` 用户点“同意”,进度条实时增长;点“驳回”,直接终止整个会签分支。所有逻辑都在MultiTaskAggregator.vue` 里,与主流程解耦。
3.3 自由流(Free Flow)的务实实现:不放任,而是提供“决策锚点”
自由流常被误解为“随便连”,但真实业务里它意味着“路径由运行时数据决定”。我们的方案叫它 Dynamic Branching(动态分支),实现方式极其简单:
- 在设计器里,提供一种特殊节点:
DecisionNode; - 它的属性面板只有一个输入框:“分支表达式”,示例:
form.leaveType === 'annual' ? 'hr_review' : 'manager_review'; - 运行时,
flowRuntimeStore在到达此节点时,执行:ts const nextNodeId = new Function('form', 'return ' + decisionExpr)(formData) // 然后跳转到 nextNodeId 对应的任务
安全吗?当然做沙箱。我们用 vm2 库隔离执行环境,只暴露 form(当前表单数据)和 utils(预置的日期格式化、金额计算等函数)。业务方写错表达式,顶多报个 ReferenceError,不会污染全局作用域。这个设计比 BPMN 的“条件序列流”更贴近前端工程师的思维——你写的不是 XML 属性,就是一段 JS。
4. 实操过程与核心环节实现:从初始化到上线,一份可抄作业的完整路径
4.1 初始化项目:5 分钟接入现有中后台系统
假设你已有基于 Vue3 + ant-design-vue 的中后台项目(src/views/workflow/ 下为空),按以下步骤接入:
第一步:安装依赖
# 注意:必须使用 ant-design-vue 4.x(Vue3 版本)
npm install ant-design-vue@^4.3.0 pinia@^2.1.7
# 安装本工作流包(假设已发布到私有 registry)
npm install @your-company/smart-flow-core@1.2.0
第二步:注册插件与 Store
在 main.ts 中:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/reset.css'
import App from './App.vue'
// 导入工作流核心插件
import { SmartFlowPlugin } from '@your-company/smart-flow-core'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.use(Antd)
// 关键:注册工作流插件,传入后端 API 基础配置
app.use(SmartFlowPlugin, {
apiBase: '/api/workflow', // 所有流程接口前缀
mockMode: import.meta.env.DEV // 开发环境启用 mock
})
app.mount('#app')
第三步:创建流程设计器页面
新建 src/views/workflow/Designer.vue:
<template>
<div class="designer-container">
<!-- 顶部工具栏 -->
<a-row class="toolbar" :gutter="16">
<a-col><a-button @click="saveFlow">保存流程</a-button></a-col>
<a-col><a-button @click="publishFlow" type="primary">发布上线</a-button></a-col>
<a-col><a-button @click="previewFlow">预览效果</a-button></a-col>
</a-row>
<!-- 主设计器 -->
<SmartFlowDesigner
ref="designerRef"
v-model="flowDefinition"
@change="onDefinitionChange"
/>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { SmartFlowDesigner } from '@your-company/smart-flow-core'
import { useFlowStore } from '@your-company/smart-flow-core/store'
const flowDefinition = ref({}) // 初始为空流程
const designerRef = ref()
const flowStore = useFlowStore()
onMounted(() => {
// 从后端加载已存在的流程定义(可选)
flowStore.loadFlowById('leave_approval').then(def => {
flowDefinition.value = def
})
})
const saveFlow = () => {
flowStore.saveFlow(flowDefinition.value)
}
const publishFlow = () => {
flowStore.publishFlow(flowDefinition.value.id)
}
const previewFlow = () => {
// 跳转到审批页,传入当前定义的 JSON
window.open(`/approval?flow=${encodeURIComponent(JSON.stringify(flowDefinition.value))}`)
}
</script>
第四步:创建审批页路由
在 router/index.ts 中添加:
{
path: '/approval',
name: 'ApprovalView',
component: () => import('@/views/workflow/ApprovalView.vue'),
meta: { title: '流程审批' }
}
就这么四步,一个可编辑、可发布、可预览的流程系统前端就跑起来了。demo.jpg 里展示的所有功能,此刻已在你的浏览器里可用。
4.2 配置并行与会签:参数背后的业务含义
并行和会签是高频需求,但配置不当极易引发线上事故。我们把它们拆解成可量化的参数:
| 参数名 | 类型 | 默认值 | 业务含义 | 实操建议 |
|---|---|---|---|---|
parallelGateway.branches |
string[] | ['task1', 'task2'] |
并行分支的目标节点 ID 数组 | 至少填 2 个,最多 5 个(避免待办爆炸) |
multiUserTask.minApprove |
number | 1 |
会签通过所需的最少同意人数 | 若设为 totalUsers,则为“全票通过”;设为 1,则为“一人通过即走” |
multiUserTask.timeoutHours |
number | 72 |
会签任务超时小时数 | 建议设为业务 SLA 的 1.5 倍,如财务审核 SLA 是 24h,则填 36 |
userTask.assignee |
string | string[] | '' |
任务分配人(支持单人或多人数组) | 多人时自动转为会签,无需额外配 multiUserTask |
举个真实案例:某客户要求“采购合同审批,法务和财务必须都看过,但只需一人同意即可进入下一步”。配置如下:
{
"id": "legal_finance_review",
"type": "multiUserTask",
"name": "法务与财务联合评审",
"assignee": ["legal_dept", "finance_dept"],
"minApprove": 1,
"timeoutHours": 48
}
运行时,系统会为 legal_dept 和 finance_dept 各生成一个待办任务,任意一人点“同意”,流程立刻进入下一环节;若两人均未操作满 48 小时,则自动触发超时提醒。
4.3 主题定制与样式隔离:如何不污染你的主系统?
很多团队不敢接入第三方 UI 库,怕样式冲突。本方案提供三级隔离:
- 第一级:CSS Scoped:所有组件
<style scoped>,确保SmartFlowDesigner的.node类不会影响你全局的.node; - 第二级:Antd Theme Override:在
styles/smart-flow-design.less中,只覆盖工作流相关变量:less @primary-color: #1890ff; // 流程高亮色 @border-radius-base: 4px; // 流程卡片圆角 @font-size-base: 14px; // 流程字体大小
不动你主系统的@link-color或@heading-color; - 第三级:Shadow DOM(可选):对极度敏感的场景,可在
main.ts中启用:ts app.component('SmartFlowDesigner', defineCustomElement(SmartFlowDesigner))
这样设计器会以 Web Component 形式渲染,样式彻底隔离。
配套的 stylelint.config.js 里还加了严格规则:禁止在工作流组件内使用 !important,禁止使用 body 或 html 选择器。这是对协作团队的基本尊重。
5. 常见问题与排查技巧实录:那些文档里不会写的坑,我都替你踩过了
5.1 “流程发布后,审批页一片空白” —— 90% 是 API 返回结构不匹配
这是新手最高频的问题。后端返回的 JSON 必须严格符合 flow-definition-schema.json。常见错误:
-
错误1:节点 ID 包含空格或特殊字符
❌"id": "部门负责人审批"
✅"id": "dept_leader_approve"
原因:前端用id作为 Vue key 和状态映射索引,空格会导致document.getElementById()失败。 -
错误2:
edges数组里from或to指向不存在的节点
❌"edges": [{"from": "start", "to": "nonexistent"}]
✅ 发布前,设计器会自动校验并高亮报错节点。
排查技巧:打开浏览器控制台,过滤flow:validate,看是否有Edge 'xxx' points to non-existent node日志。 -
错误3:
assignee字段类型错误
❌"assignee": "zhangsan"(字符串)
✅"assignee": ["zhangsan"](数组)
原因:会签逻辑统一按数组处理,单人也必须是长度为 1 的数组,否则multiUserTask的approvedUsers更新会出错。
5.2 “并行任务只显示一个,另一个不见了” —— 权限与数据加载时机问题
并行分支会为每个 branches 项生成一个独立任务,但前提是:
1. 当前用户有权限查看该任务(assignee 包含当前用户或其角色);
2. 任务列表接口 /api/workflow/tasks 返回的数据里,该任务的 status 是 'pending'。
实操心得:我们在 useFlowStore 的 fetchTaskList 方法里加了日志埋点:
console.log('[FlowStore] Fetched tasks:', tasks)
tasks.forEach(t => {
console.log(`[Task ${t.id}] assignee:`, t.assignee, 'hasPermission:', hasPermission(t.assignee))
})
这样一眼就能看出是权限拦截了,还是后端漏返回了任务。
5.3 “自由流表达式报错:Cannot read property ‘xxx’ of undefined” —— 表单数据延迟加载
动态分支表达式 form.xxx 报错,往往是因为表单数据还没加载完,流程就走到决策节点了。
解决方案:在 ApprovalView.vue 的 onMounted 里,强制等待表单加载:
onMounted(async () => {
await formStore.loadFormData(route.query.flowId as string)
// 确保 formStore.formData 已就绪,再启动流程引擎
flowRuntimeStore.startProcess(formStore.formData)
})
5.4 “设计器里连线歪了,拖拽卡顿” —— 性能优化实战
当流程节点超过 30 个,原生 DOM 拖拽会明显卡顿。我们用了三个优化:
- 虚拟滚动画布:只渲染可视区域内的节点,其余用占位 div;
- 防抖连线计算:
mousemove事件加lodash.debounce(50),避免高频重绘; - CSS 硬件加速:给所有节点加
transform: translateZ(0),触发 GPU 渲染。
验证方法:打开 Chrome DevTools → Rendering → 勾选 “FPS Meter”,拖拽时 FPS 应稳定在 55+。
5.5 常见问题速查表
| 问题现象 | 可能原因 | 快速定位命令 | 解决方案 |
|---|---|---|---|
| 审批页“同意”按钮点击无反应 | flowRuntimeStore 未正确注入 |
console.log($store.flowRuntimeStore) |
检查 main.ts 中 app.use(SmartFlowPlugin) 是否执行 |
| 会签进度条卡在 50%,实际两人已同意 | minApprove 配置为 2,但后端返回的 approvedUsers 数组里有重复用户 |
console.log(flowRuntimeStore.currentTask.value.approvedUsers) |
后端需保证 approvedUsers 是去重后的数组 |
| 设计器属性面板修改不生效 | v-model 绑定的 flowDefinition 是深拷贝对象 |
console.log(flowDefinition.value === designerRef.value.definition) |
改用 v-model:definition,确保引用一致 |
多环境构建后,.env.production 的 apiBase 未生效 |
Vite 的 import.meta.env 在构建时已替换,但 SmartFlowPlugin 初始化太早 |
console.log(import.meta.env.VUE_APP_API_BASE) |
在 app.use() 前,用 import.meta.env 构造配置对象 |
6. 团队协作与二次开发指南:如何让新同学三天上手,老司机高效扩展
6.1 开箱即用的工程化配置
资源包里的每一个配置文件,都不是摆设:
.vscode/extensions.json:预装了ESLint,Prettier,Vue Language Features,新同学git clone后打开 VS Code,自动提示安装;.vscode/launch.json:配置了Debug Workflow启动项,F5 直接启动带 mock 数据的审批页,断点打在flowRuntimeStore.ts里,秒级调试状态流转;commitlint.config.js:约束提交信息为feat(workflow): add parallel gateway support格式,配合husky的pre-commit钩子,保证 Git 历史可读;eslint/stylelint/prettier三件套:规则已调优,比如eslint-plugin-vue的vue/multi-word-component-names关闭(因SmartFlowDesigner是合法组件名),prettier的semi设为false(适配团队习惯)。
6.2 二次开发的黄金路径
想加一个新节点类型?比如“短信通知节点”:
- 在
src/components/nodes/下新建SmsNotifyNode.vue,实现render()和getConfig()方法; - 在
src/components/designer/node-library.ts中注册:ts export const nodeLibrary = [ ...defaultNodes, { id: 'smsNotify', name: '短信通知', icon: 'message', component: () => import('./nodes/SmsNotifyNode.vue'), defaultConfig: { templateId: '', receivers: [] } } ] - 在
flow-definition-schema.json的nodes类型定义里,增加smsNotify枚举值; - 在
flow-runtime-store.ts的handleNodeExecution里,增加case 'smsNotify': sendSms(config); break;
全程不碰核心引擎,所有扩展都遵循“注册即用”原则。我们内部已用此方式扩展了 7 种业务节点(邮件、钉钉机器人、数据校验、定时触发等),平均每人每天可交付 1~2 个。
6.3 最后分享一个小技巧:用 demo.jpg 反向生成流程定义
demo.jpg 不仅是效果图,更是测试用例。我们写了个小脚本 scripts/generate-from-demo.js:
# 输入 demo.jpg,输出一个近似结构的 JSON 流程定义
node scripts/generate-from-demo.js --input demo.jpg --output src/mock/leave_demo.json
它用 OpenCV 识别图片中的节点位置和连线,再结合 OCR 提取文字,生成可运行的初始定义。新同学第一天,就能对着 demo.jpg 点几下,生成一个能跑的流程,成就感拉满。
这套方案没有试图成为通用工作流平台,它只是把中后台里最痛的那根刺——“审批流程前端开发”——打磨成一把趁手的刀。它不追求炫技,只求让每个点击、每次拖拽、每行配置,都精准落在业务需求的靶心上。当你下次再听到“这个流程下周上线”,可以笑着打开终端,敲下 npm run serve,然后泡杯茶,等它自己跑起来。
简介:基于 Vue3 和 ant-design-vue 深度封装的工作流前端解决方案,内置可视化流程设计器,支持节点拖拽、连线配置、属性面板实时编辑。开箱即用钉钉风格审批界面,覆盖流程发起、任务办理、驳回退回等核心操作。完整兼容多种流程模式:串行流转、并行分支、会签(多人同时审批)、自由流(无固定路径)及服务任务调用。提供统一状态管理(Pinia)、响应式布局组件、主题变量定制和样式隔离方案,适配中后台系统快速接入。配套资源齐全:含 demo.jpg 展示效果、setting.jpg 设计参考图、多环境变量配置(.env.development)、ESLint/Stylelint/Prettier 代码规范、VS Code 推荐插件与调试配置(extensions. / launch.)、构建配置(vue.config.js / babel.config.js)以及完整项目结构(router、store、views、utils 等模块清晰划分),支持团队协作开发与按需二次扩展。
更多推荐


所有评论(0)