@qilitt-mickey/vue3-temp-skill 1.0.12 → 1.1.2
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 +66 -214
- package/SKILL.md +165 -527
- package/package.json +2 -2
- package/references/api-check.md +187 -128
- package/references/base-code-dict.md +49 -48
- package/references/chart-echarts.md +61 -0
- package/references/code-quality.md +44 -15
- package/references/core-kernel.md +305 -0
- package/references/crud-pages.md +87 -261
- package/references/data-compare.md +502 -501
- package/references/data-mapping.md +218 -213
- package/references/data-screen.md +94 -79
- package/references/data-writeback.md +104 -104
- package/references/detail-page.md +100 -99
- package/references/directives-advanced.md +27 -4
- package/references/download-export.md +70 -68
- package/references/feedback-loading.md +62 -60
- package/references/feedback-ui.md +125 -111
- package/references/file-management.md +28 -7
- package/references/flowchart-g6.md +249 -244
- package/references/form-advanced.md +264 -26
- package/references/graph-relation.md +12 -7
- package/references/http-api.md +138 -103
- package/references/icons.md +326 -0
- package/references/layout-theme.md +1 -1
- package/references/mobile-h5.md +20 -0
- package/references/particles.md +143 -0
- package/references/permission-auth.md +8 -31
- package/references/project-inventory.md +175 -120
- package/references/qrcode-barcode.md +107 -92
- package/references/rich-text.md +85 -73
- package/references/seamless-scroll.md +40 -38
- package/references/table-vxe.md +114 -0
- package/references/tree-table.md +2 -1
- package/references/ui-components.md +5 -1
- package/references/verify-captcha.md +110 -96
- package/references/websocket-realtime.md +2 -1
- package/references/wechat-js.md +58 -0
- package/references/workflow-bpmn.md +207 -206
- package/references/advanced-ui.md +0 -302
- package/references/build-optim.md +0 -282
- package/references/vue-core.md +0 -209
|
@@ -1,244 +1,249 @@
|
|
|
1
|
-
# G6 流程图(@antv/g6 v5)
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
graph
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
graph.
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
1
|
+
# G6 流程图(@antv/g6 v5)
|
|
2
|
+
|
|
3
|
+
> 按本文件示例编写;必须使用选型表中的 `@antv/g6`(见 project-inventory),勿改用同类其他流程图库;新依赖须待确认。
|
|
4
|
+
|
|
5
|
+
## 依赖(缺则先装)
|
|
6
|
+
|
|
7
|
+
| 包 | 版本 |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `@antv/g6` | `5.1.1` |
|
|
10
|
+
| `g6-extension-vue` | `0.1.0` |
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add @antv/g6@5.1.1 g6-extension-vue@0.1.0
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
大体积依赖模板侧已拆包为 `antv-g6` / `antv-vendor`。支持在节点中渲染 Vue 组件。
|
|
17
|
+
|
|
18
|
+
## 组件结构
|
|
19
|
+
|
|
20
|
+
```vue
|
|
21
|
+
<!-- G6Flow.vue -->
|
|
22
|
+
<script setup lang="tsx">
|
|
23
|
+
import { ExtensionCategory, register, treeToGraphData } from '@antv/g6'
|
|
24
|
+
import { useResizeObserver } from '@vueuse/core'
|
|
25
|
+
import { VueNode } from 'g6-extension-vue'
|
|
26
|
+
import { getG6WorkflowData } from '@/api/common'
|
|
27
|
+
import { useApp } from '@/hooks/useApp'
|
|
28
|
+
|
|
29
|
+
defineOptions({ name: 'G6Flow' })
|
|
30
|
+
|
|
31
|
+
const props = withDefaults(defineProps<{
|
|
32
|
+
nodeWidth?: number
|
|
33
|
+
nodeHeight?: number
|
|
34
|
+
getHGap?: number
|
|
35
|
+
getVGap?: number
|
|
36
|
+
resize?: boolean
|
|
37
|
+
fitCenterOnResize?: boolean
|
|
38
|
+
onBizClick?: (id: string) => void
|
|
39
|
+
onNodeClick?: (id: string) => void
|
|
40
|
+
}>(), {
|
|
41
|
+
nodeWidth: 260,
|
|
42
|
+
nodeHeight: 190,
|
|
43
|
+
hGap: 80,
|
|
44
|
+
getVGap: 80,
|
|
45
|
+
resize: true,
|
|
46
|
+
fitCenterOnResize: true,
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const containerRef = ref<HTMLElement>()
|
|
50
|
+
const treeData = ref<any>(null)
|
|
51
|
+
const loading = ref(false)
|
|
52
|
+
const { svgLoading } = useApp()
|
|
53
|
+
let graph: any = null
|
|
54
|
+
</script>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 初始化图实例
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const initGraph = async () => {
|
|
61
|
+
if (!containerRef.value) return
|
|
62
|
+
const { Graph } = await import('@antv/g6')
|
|
63
|
+
register(ExtensionCategory.NODE, 'vue-node', VueNode)
|
|
64
|
+
|
|
65
|
+
// 定义 Vue 节点组件
|
|
66
|
+
const FlowNodeComp = defineComponent({
|
|
67
|
+
name: 'FlowNodeComp',
|
|
68
|
+
props: ['treeData'],
|
|
69
|
+
setup(p: any) {
|
|
70
|
+
const nodeData = computed(() => p.treeData)
|
|
71
|
+
const isSelected = computed(() =>
|
|
72
|
+
Array.isArray(p.treeData?.states) && p.treeData.states.includes('selected')
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
function handleNodeClick(e: Event) {
|
|
76
|
+
e.preventDefault()
|
|
77
|
+
e.stopPropagation()
|
|
78
|
+
const id = nodeData.value?.id
|
|
79
|
+
if (!id || !graph) return
|
|
80
|
+
// 切换选中状态
|
|
81
|
+
const data = graph.getData?.() || {}
|
|
82
|
+
data.nodes.forEach((n: any) => {
|
|
83
|
+
graph.setElementState?.(n.id, n.id === id ? ['selected'] : [])
|
|
84
|
+
})
|
|
85
|
+
// 展开/折叠
|
|
86
|
+
const current = data.nodes.find((n: any) => n.id === id)
|
|
87
|
+
if (current?.collapsed) {
|
|
88
|
+
graph.expandElement?.(id, { animation: false })
|
|
89
|
+
current.collapsed = false
|
|
90
|
+
} else {
|
|
91
|
+
graph.collapseElement?.(id, { animation: false })
|
|
92
|
+
current.collapsed = true
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return () => (
|
|
97
|
+
<div style={{
|
|
98
|
+
width: `${props.nodeWidth}px`, height: `${props.nodeHeight}px`,
|
|
99
|
+
border: '2px solid', borderColor: isSelected.value ? 'red' : '#9DC5EA',
|
|
100
|
+
borderRadius: '8px', background: '#EAF4FF', cursor: 'pointer',
|
|
101
|
+
}} onClick={handleNodeClick}>
|
|
102
|
+
<div style={{ background: '#CFE7FF', padding: '8px', fontWeight: 600 }}>
|
|
103
|
+
{nodeData.value?.title ?? ''}
|
|
104
|
+
</div>
|
|
105
|
+
<div style={{ padding: '8px' }}>
|
|
106
|
+
<div>业务号:{nodeData.value?.caseNo ?? ''}</div>
|
|
107
|
+
<div>{nodeData.value?.handler ?? ''}</div>
|
|
108
|
+
<div style={{ color: '#409eff' }}>状态:{nodeData.value?.status ?? ''}</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
)
|
|
112
|
+
},
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
graph = new Graph({
|
|
116
|
+
container: containerRef.value,
|
|
117
|
+
width: containerRef.value.clientWidth || 800,
|
|
118
|
+
height: containerRef.value.clientHeight || 600,
|
|
119
|
+
autoFit: 'view',
|
|
120
|
+
behaviors: ['drag-canvas', 'zoom-canvas'],
|
|
121
|
+
node: {
|
|
122
|
+
type: 'vue-node',
|
|
123
|
+
style: {
|
|
124
|
+
component: d => <FlowNodeComp treeData={Object.assign({}, d)} />,
|
|
125
|
+
size: [props.nodeWidth, props.nodeHeight],
|
|
126
|
+
ports: [
|
|
127
|
+
{ key: 'top', placement: 'top' },
|
|
128
|
+
{ key: 'bottom', placement: 'bottom' },
|
|
129
|
+
],
|
|
130
|
+
cursor: 'pointer',
|
|
131
|
+
},
|
|
132
|
+
animation: { enter: false },
|
|
133
|
+
},
|
|
134
|
+
edge: { type: 'line', style: { stroke: '#9DC5EA' }, animation: { enter: false } },
|
|
135
|
+
layout: {
|
|
136
|
+
type: 'compact-box',
|
|
137
|
+
direction: 'TB',
|
|
138
|
+
getHeight: () => props.nodeHeight,
|
|
139
|
+
getWidth: () => props.nodeWidth,
|
|
140
|
+
getVGap: () => props.getVGap,
|
|
141
|
+
getHGap: () => props.getHGap,
|
|
142
|
+
},
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
// 点击画布取消选中
|
|
146
|
+
graph.on('canvas:click', () => {
|
|
147
|
+
const data = graph.getData?.() || {}
|
|
148
|
+
data.nodes?.forEach((n: any) => graph.setElementState?.(n.id, []))
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## 数据加载与渲染
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const setGraphData = () => {
|
|
157
|
+
if (!graph || !treeData.value) return
|
|
158
|
+
const graphData = treeToGraphData(treeData.value) // 树结构 → 图数据
|
|
159
|
+
graph.setData(graphData)
|
|
160
|
+
graph.render()
|
|
161
|
+
graph.fitView?.() // 缩放至合适大小并居中
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const loadData = async () => {
|
|
165
|
+
loading.value = true
|
|
166
|
+
const { data } = await getG6WorkflowData()
|
|
167
|
+
treeData.value = data
|
|
168
|
+
setGraphData()
|
|
169
|
+
loading.value = false
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 缩放控制
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const handleZoomIn = () => {
|
|
177
|
+
if (!graph) return
|
|
178
|
+
const current = graph.getZoom?.() ?? 1
|
|
179
|
+
graph.zoomTo?.(current + 0.1)
|
|
180
|
+
}
|
|
181
|
+
const handleZoomOut = () => {
|
|
182
|
+
if (!graph) return
|
|
183
|
+
const current = graph.getZoom?.() ?? 1
|
|
184
|
+
graph.zoomTo?.(Math.max(0.1, current - 0.1))
|
|
185
|
+
}
|
|
186
|
+
const handleFitView = () => {
|
|
187
|
+
if (!graph) return
|
|
188
|
+
graph.fitView?.()
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## 响应式尺寸
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const resize = () => {
|
|
196
|
+
if (!graph || !containerRef.value || !props.resize) return
|
|
197
|
+
const w = containerRef.value.clientWidth
|
|
198
|
+
const h = containerRef.value.clientHeight
|
|
199
|
+
graph.resize(w, h)
|
|
200
|
+
if (props.fitCenterOnResize) {
|
|
201
|
+
graph.render()
|
|
202
|
+
graph.fitView?.()
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
useResizeObserver(containerRef, () => resize())
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## 生命周期
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
onMounted(async () => {
|
|
212
|
+
await initGraph()
|
|
213
|
+
await loadData()
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
onBeforeUnmount(() => {
|
|
217
|
+
graph?.destroy?.()
|
|
218
|
+
graph = null
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
defineExpose({ getInstance: () => graph })
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## 页面用法
|
|
225
|
+
|
|
226
|
+
```vue
|
|
227
|
+
<!-- g6 页面示例 -->
|
|
228
|
+
<template>
|
|
229
|
+
<div :style="{ height: `calc(100vh - 2 * var(--vts-margin) - ${headerHeight}px)` }"
|
|
230
|
+
class="pos-relative bg-[#fff] p-5 overflow-hidden">
|
|
231
|
+
<div class="toolbar">
|
|
232
|
+
<el-alert title="antv/g6流程图展示" type="info" :closable="false" />
|
|
233
|
+
</div>
|
|
234
|
+
<div class="g6-container">
|
|
235
|
+
<G6Flow ref="flowRef" :node-width="260" :node-height="190" :get-v-gap="80" :get-h-gap="80" />
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</template>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## 关键约定
|
|
242
|
+
|
|
243
|
+
1. G6 5.x 必须配合 `g6-extension-vue` 才能在节点中渲染 Vue 组件。
|
|
244
|
+
2. `@antv/g6` 使用动态 `import()` 按需加载,避免首屏性能问题。
|
|
245
|
+
3. 布局使用 `compact-box`(紧凑树盒布局),方向 `TB`(从上到下)。
|
|
246
|
+
4. 图容器必须有明确宽高,否则初始化失败。
|
|
247
|
+
5. `onBeforeUnmount` 中必须调用 `graph.destroy()` 释放资源。
|
|
248
|
+
6. `treeToGraphData` 将树结构转为 G6 图数据格式。
|
|
249
|
+
7. 节点选中状态通过 `setElementState` 管理,CSS 通过 `states` 属性判断。
|