@qilitt-mickey/vue3-temp-skill 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +229 -0
- package/SKILL.md +621 -0
- package/bin/cli.js +579 -0
- package/package.json +46 -0
- package/references/advanced-ui.md +302 -0
- package/references/api-check.md +272 -0
- package/references/base-code-dict.md +48 -0
- package/references/build-optim.md +282 -0
- package/references/code-quality.md +235 -0
- package/references/crud-pages.md +316 -0
- package/references/data-compare.md +501 -0
- package/references/data-mapping.md +213 -0
- package/references/data-screen.md +79 -0
- package/references/data-writeback.md +104 -0
- package/references/detail-page.md +99 -0
- package/references/directives-advanced.md +93 -0
- package/references/download-export.md +68 -0
- package/references/feedback-loading.md +60 -0
- package/references/feedback-ui.md +111 -0
- package/references/file-management.md +132 -0
- package/references/flowchart-g6.md +244 -0
- package/references/form-advanced.md +137 -0
- package/references/graph-relation.md +253 -0
- package/references/http-api.md +188 -0
- package/references/layout-theme.md +540 -0
- package/references/mobile-h5.md +271 -0
- package/references/permission-auth.md +235 -0
- package/references/project-inventory.md +326 -0
- package/references/qrcode-barcode.md +92 -0
- package/references/rich-text.md +73 -0
- package/references/seamless-scroll.md +38 -0
- package/references/tree-table.md +111 -0
- package/references/ui-components.md +161 -0
- package/references/verify-captcha.md +96 -0
- package/references/vue-core.md +209 -0
- package/references/websocket-realtime.md +176 -0
- package/references/workflow-bpmn.md +206 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# BPMN 工作流查看器
|
|
2
|
+
|
|
3
|
+
## 依赖
|
|
4
|
+
|
|
5
|
+
`bpmn-js/lib/Viewer` — BPMN 流程图的只读查看器(不含建模器)。
|
|
6
|
+
|
|
7
|
+
## 类型定义
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// src/views/workflow/types/bpmn.ts
|
|
11
|
+
|
|
12
|
+
export type BpmnElementType =
|
|
13
|
+
| 'bpmn:StartEvent' | 'bpmn:EndEvent'
|
|
14
|
+
| 'bpmn:UserTask' | 'bpmn:ServiceTask'
|
|
15
|
+
| 'bpmn:ExclusiveGateway' | 'bpmn:SequenceFlow' | 'bpmn:Process'
|
|
16
|
+
|
|
17
|
+
export interface BpmnElement {
|
|
18
|
+
id: string
|
|
19
|
+
type: string | BpmnElementType
|
|
20
|
+
name?: string
|
|
21
|
+
businessObject?: any
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ProcessInfo {
|
|
25
|
+
finishedTasks?: string[]
|
|
26
|
+
finishedTaskSet?: Set<string>
|
|
27
|
+
activeTasks?: string[]
|
|
28
|
+
activeTaskSet?: Set<string>
|
|
29
|
+
unfinishedTasks?: string[]
|
|
30
|
+
unfinishedTaskSet?: Set<string>
|
|
31
|
+
finishedSequenceFlows?: string[]
|
|
32
|
+
finishedSequenceFlowSet?: Set<string>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface BpmnWorkflowData {
|
|
36
|
+
xml: string
|
|
37
|
+
processInfo?: ProcessInfo
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface WorkflowViewerProps {
|
|
41
|
+
xml?: string
|
|
42
|
+
processInfo?: ProcessInfo
|
|
43
|
+
height?: string | number
|
|
44
|
+
showToolbar?: boolean
|
|
45
|
+
allowExport?: boolean
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 组件结构
|
|
50
|
+
|
|
51
|
+
```vue
|
|
52
|
+
<!-- src/views/workflow/components/WorkflowViewer.vue -->
|
|
53
|
+
<script setup lang="ts">
|
|
54
|
+
import Viewer from 'bpmn-js/lib/Viewer'
|
|
55
|
+
import type { BpmnWorkflowData, ProcessInfo } from '../types/bpmn'
|
|
56
|
+
|
|
57
|
+
defineOptions({ name: 'WorkflowViewer' })
|
|
58
|
+
|
|
59
|
+
const props = withDefaults(defineProps<WorkflowViewerProps>(), {
|
|
60
|
+
height: '500px',
|
|
61
|
+
showToolbar: true,
|
|
62
|
+
allowExport: false,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const containerRef = ref<HTMLElement>()
|
|
66
|
+
let viewer: Viewer | null = null
|
|
67
|
+
|
|
68
|
+
// 初始化查看器
|
|
69
|
+
const initViewer = async () => {
|
|
70
|
+
if (!containerRef.value) return
|
|
71
|
+
viewer = new Viewer({ container: containerRef.value })
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 导入 BPMN XML
|
|
75
|
+
const importXml = async (xml: string) => {
|
|
76
|
+
if (!viewer) return
|
|
77
|
+
try {
|
|
78
|
+
await viewer.importXML(xml)
|
|
79
|
+
// 缩放适配
|
|
80
|
+
const canvas = viewer.get('canvas') as any
|
|
81
|
+
canvas.zoom('fit-viewport')
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.error('BPMN XML 导入失败', err)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 高亮已完成/活动节点
|
|
88
|
+
const highlightProcess = (processInfo: ProcessInfo) => {
|
|
89
|
+
if (!viewer) return
|
|
90
|
+
const canvas = viewer.get('canvas') as any
|
|
91
|
+
const elementRegistry = viewer.get('elementRegistry') as any
|
|
92
|
+
|
|
93
|
+
// 高亮已完成任务
|
|
94
|
+
processInfo.finishedTaskSet?.forEach((id: string) => {
|
|
95
|
+
const element = elementRegistry.get(id)
|
|
96
|
+
if (element) canvas.addMarker(id, 'bpmn-finished')
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// 高亮当前活动任务
|
|
100
|
+
processInfo.activeTaskSet?.forEach((id: string) => {
|
|
101
|
+
const element = elementRegistry.get(id)
|
|
102
|
+
if (element) canvas.addMarker(id, 'bpmn-active')
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// 高亮已完成序列流
|
|
106
|
+
processInfo.finishedSequenceFlowSet?.forEach((id: string) => {
|
|
107
|
+
const element = elementRegistry.get(id)
|
|
108
|
+
if (element) canvas.addMarker(id, 'bpmn-flow-finished')
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 导出 SVG
|
|
113
|
+
const exportSvg = async () => {
|
|
114
|
+
if (!viewer) return null
|
|
115
|
+
const svgResult = await viewer.saveSVG()
|
|
116
|
+
return svgResult.svg
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
onMounted(async () => {
|
|
120
|
+
await initViewer()
|
|
121
|
+
if (props.xml) await importXml(props.xml)
|
|
122
|
+
if (props.processInfo) highlightProcess(props.processInfo)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
onBeforeUnmount(() => {
|
|
126
|
+
viewer?.destroy()
|
|
127
|
+
viewer = null
|
|
128
|
+
})
|
|
129
|
+
</script>
|
|
130
|
+
|
|
131
|
+
<template>
|
|
132
|
+
<div class="workflow-viewer">
|
|
133
|
+
<div v-if="showToolbar" class="viewer-toolbar">
|
|
134
|
+
<el-button size="small" @click="handleZoomIn">放大</el-button>
|
|
135
|
+
<el-button size="small" @click="handleZoomOut">缩小</el-button>
|
|
136
|
+
<el-button size="small" @click="handleFitView">适配</el-button>
|
|
137
|
+
<el-button v-if="allowExport" size="small" @click="handleExportSvg">导出 SVG</el-button>
|
|
138
|
+
</div>
|
|
139
|
+
<div ref="containerRef" :style="{ height: typeof height === 'number' ? height + 'px' : height }" />
|
|
140
|
+
</div>
|
|
141
|
+
</template>
|
|
142
|
+
|
|
143
|
+
<style>
|
|
144
|
+
/* BPMN 高亮样式(全局,不加 scoped) */
|
|
145
|
+
:deep(.bpmn-active) .djs-visual > :nth-child(1) {
|
|
146
|
+
fill: #409eff !important;
|
|
147
|
+
stroke: #409eff !important;
|
|
148
|
+
}
|
|
149
|
+
:deep(.bpmn-finished) .djs-visual > :nth-child(1) {
|
|
150
|
+
fill: #67c23a !important;
|
|
151
|
+
stroke: #67c23a !important;
|
|
152
|
+
}
|
|
153
|
+
:deep(.bpmn-flow-finished) .djs-visual > :nth-child(1) {
|
|
154
|
+
stroke: #67c23a !important;
|
|
155
|
+
}
|
|
156
|
+
</style>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 页面调用
|
|
160
|
+
|
|
161
|
+
```vue
|
|
162
|
+
<!-- src/views/workflow/bpmn/index.vue -->
|
|
163
|
+
<script setup lang="ts">
|
|
164
|
+
import { ReDialog } from '@/components/ReDialog'
|
|
165
|
+
import WorkflowViewer from '../components/WorkflowViewer.vue'
|
|
166
|
+
|
|
167
|
+
defineOptions({ name: 'WorkflowBpmn' })
|
|
168
|
+
const showDialog = ref(false)
|
|
169
|
+
</script>
|
|
170
|
+
|
|
171
|
+
<template>
|
|
172
|
+
<el-button type="primary" size="large" @click="showDialog = true">查看流程图</el-button>
|
|
173
|
+
<ReDialog v-model="showDialog" title="BPMN流程图查看器">
|
|
174
|
+
<WorkflowViewer />
|
|
175
|
+
<template #footer>
|
|
176
|
+
<el-button @click="showDialog = false">关闭</el-button>
|
|
177
|
+
</template>
|
|
178
|
+
</ReDialog>
|
|
179
|
+
</template>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 数据获取
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// API 返回格式
|
|
186
|
+
interface WorkflowApiResponse {
|
|
187
|
+
data: BpmnWorkflowData // { xml: string, processInfo?: ProcessInfo }
|
|
188
|
+
code?: number
|
|
189
|
+
message?: string
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 关键约定
|
|
194
|
+
|
|
195
|
+
1. 使用 `bpmn-js/lib/Viewer`(只读),不使用 `Modeler`(可编辑)除非有流程设计需求。
|
|
196
|
+
2. 组件销毁时必须调用 `viewer.destroy()` 释放资源。
|
|
197
|
+
3. 高亮通过 `canvas.addMarker(id, className)` 实现,CSS 使用 `:deep()` 穿透 BPMN 内部 SVG。
|
|
198
|
+
4. 流程数据(已完成/活动任务)由后端接口统一返回,前端只负责渲染。
|
|
199
|
+
5. 弹窗内使用时注意容器高度,BPMN 需要明确的宽高才能正确渲染。
|
|
200
|
+
6. `canvas.zoom('fit-viewport')` 自动缩放适配视口。
|
|
201
|
+
|
|
202
|
+
## 关联文件
|
|
203
|
+
|
|
204
|
+
- [src/views/workflow/bpmn/index.vue](file:///e:/work/vue3-web-temp/src/views/workflow/bpmn/index.vue)
|
|
205
|
+
- [src/views/workflow/components/WorkflowViewer.vue](file:///e:/work/vue3-web-temp/src/views/workflow/components/WorkflowViewer.vue)
|
|
206
|
+
- [src/views/workflow/types/bpmn.ts](file:///e:/work/vue3-web-temp/src/views/workflow/types/bpmn.ts)
|