mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-08-13 15:55:43 +08:00
perf SQL查询和流程图设计移植
This commit is contained in:
@@ -34,8 +34,6 @@
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons-vue": "^6.1.0",
|
||||
"@iconify/iconify": "^2.2.1",
|
||||
"@logicflow/core": "^1.1.13",
|
||||
"@logicflow/extension": "^1.1.13",
|
||||
"@vue/runtime-core": "^3.2.33",
|
||||
"@vue/shared": "^3.2.33",
|
||||
"@vueuse/core": "^8.3.0",
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
<a-layout style="height: 100%">
|
||||
<a-layout style="align-items: stretch">
|
||||
<div ref="canvas" class="canvas" :style="{ minHeight: height + 'px' }"></div>
|
||||
<a-drawer :visible="drawerVisible" title="流程信息" :width="450" placement="right" :closable="true" @close="drawerVisible = false">
|
||||
<a-timeline>
|
||||
<a-timeline-item v-for="o in currentTaskList" :key="o.id">
|
||||
<p>开始时间: {{ o.startTime }}</p>
|
||||
<p>状态:{{ stateNameConvert(o.state) }}</p>
|
||||
<p>处理结果:{{ dictConvert('BpmTaskResult', o.result) }}</p>
|
||||
<p>处理人: {{ o.userName }}</p>
|
||||
<p>结束时间: {{ o.endTime ? o.endTime : '' }}</p>
|
||||
<p>审批意见:{{ o.reason ? o.reason : '' }}</p>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
</a-drawer>
|
||||
<!-- <a-drawer :visible="drawerVisible" title="流程信息" :width="450" placement="right" :closable="true" @close="drawerVisible = false">-->
|
||||
<!-- <a-timeline>-->
|
||||
<!-- <a-timeline-item v-for="o in currentTaskList" :key="o.id">-->
|
||||
<!-- <p>开始时间: {{ o.startTime }}</p>-->
|
||||
<!-- <p>状态:{{ stateNameConvert(o.state) }}</p>-->
|
||||
<!-- <p>处理结果:{{ dictConvert('BpmTaskResult', o.result) }}</p>-->
|
||||
<!-- <p>处理人: {{ o.userName }}</p>-->
|
||||
<!-- <p>结束时间: {{ o.endTime ? o.endTime : '' }}</p>-->
|
||||
<!-- <p>审批意见:{{ o.reason ? o.reason : '' }}</p>-->
|
||||
<!-- </a-timeline-item>-->
|
||||
<!-- </a-timeline>-->
|
||||
<!-- </a-drawer>-->
|
||||
<a-layout-sider
|
||||
class="sider"
|
||||
style="
|
||||
@@ -37,7 +37,11 @@
|
||||
import Modeler from 'bpmn-js/lib/Modeler'
|
||||
// 引入flowable的节点文件
|
||||
import flowableModdle from './flowable/flowable.json'
|
||||
|
||||
import { addArrow } from './processViewerUtils'
|
||||
import { useDict } from '/@/hooks/bootx/useDict'
|
||||
|
||||
const { dictConvert } = useDict()
|
||||
|
||||
export default {
|
||||
name: 'WorkflowBpmnModeler',
|
||||
@@ -88,24 +92,26 @@
|
||||
* 生成实例
|
||||
*/
|
||||
initModeler() {
|
||||
console.log(this.$refs.canvas)
|
||||
this.modeler = new Modeler({
|
||||
container: this.$refs.canvas,
|
||||
additionalModules: [
|
||||
{
|
||||
translate: ['value', customTranslate],
|
||||
paletteProvider: ['value', ''], // 禁用/清空左侧工具栏
|
||||
labelEditingProvider: ['value', ''], // 禁用节点编辑
|
||||
contextPadProvider: ['value', ''], // 禁用图形菜单
|
||||
bendpoints: ['value', {}], // 禁用连线拖动
|
||||
// paletteProvider: ['value', ''], // 禁用/清空左侧工具栏
|
||||
// labelEditingProvider: ['value', ''], // 禁用节点编辑
|
||||
// contextPadProvider: ['value', ''], // 禁用图形菜单
|
||||
// bendpoints: ['value', {}], // 禁用连线拖动
|
||||
// zoomScroll: ['value', ''], // 禁用滚动
|
||||
// moveCanvas: ['value', ''], // 禁用拖动整个流程图
|
||||
move: ['value', ''], // 禁用单个图形拖动
|
||||
},
|
||||
],
|
||||
moddleExtensions: {
|
||||
flowable: flowableModdle,
|
||||
},
|
||||
// moddleExtensions: {
|
||||
// flowable: flowableModdle,
|
||||
// },
|
||||
})
|
||||
console.log(this.modeler)
|
||||
},
|
||||
/**
|
||||
* 创建流程图
|
||||
@@ -282,9 +288,6 @@
|
||||
stateNameConvert(state) {
|
||||
return dictConvert('BpmTaskState', state)
|
||||
},
|
||||
dictConvert(dictCode, code) {
|
||||
return dictConvert(dictCode, code)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -293,10 +296,10 @@
|
||||
// Font class
|
||||
@import './icon/iconfont.css';
|
||||
/*左边工具栏以及编辑节点的样式*/
|
||||
@import '~bpmn-js/dist/assets/diagram-js.css';
|
||||
@import '~bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
|
||||
@import '~bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
|
||||
@import '~bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
|
||||
@import 'bpmn-js/dist/assets/diagram-js.css';
|
||||
@import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
|
||||
@import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
|
||||
@import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
|
||||
|
||||
@import './css/ProcessViewerHighlight.less';
|
||||
.view-mode {
|
||||
|
||||
@@ -7,12 +7,9 @@ export default function customTranslate(template, replacements) {
|
||||
template = translations[template] || template
|
||||
|
||||
// Replace
|
||||
return template.replace(/{([^}]+)}/g, function(_, key) {
|
||||
return template.replace(/{([^}]+)}/g, function (_, key) {
|
||||
var str = replacements[key]
|
||||
if (
|
||||
translations[replacements[key]] !== null &&
|
||||
translations[replacements[key]] !== 'undefined'
|
||||
) {
|
||||
if (translations[replacements[key]] !== null && translations[replacements[key]] !== 'undefined') {
|
||||
str = translations[replacements[key]]
|
||||
}
|
||||
return str || '{' + key + '}'
|
||||
|
||||
@@ -4,7 +4,7 @@ import { query as domQuery } from 'min-dom'
|
||||
/**
|
||||
* 添加箭头
|
||||
*/
|
||||
export function addArrow () {
|
||||
export function addArrow() {
|
||||
const todo = svgCreate('marker')
|
||||
// 追加箭头svg元素 通过
|
||||
svgAttr(todo, {
|
||||
@@ -14,12 +14,12 @@ export function addArrow () {
|
||||
refY: '10',
|
||||
markerWidth: '10',
|
||||
markerHeight: '10',
|
||||
orient: 'auto'
|
||||
orient: 'auto',
|
||||
})
|
||||
const todoPath = svgCreate('path')
|
||||
svgAttr(todoPath, {
|
||||
d: 'M 1 5 L 11 10 L 1 15 Z',
|
||||
class: 'highlight-todo-arrow'
|
||||
class: 'highlight-todo-arrow',
|
||||
})
|
||||
svgAppend(todo, todoPath)
|
||||
// 追加箭头svg元素 通过
|
||||
@@ -31,12 +31,12 @@ export function addArrow () {
|
||||
refY: '10',
|
||||
markerWidth: '10',
|
||||
markerHeight: '10',
|
||||
orient: 'auto'
|
||||
orient: 'auto',
|
||||
})
|
||||
const passPath = svgCreate('path')
|
||||
svgAttr(passPath, {
|
||||
d: 'M 1 5 L 11 10 L 1 15 Z',
|
||||
class: 'highlight-pass-arrow'
|
||||
class: 'highlight-pass-arrow',
|
||||
})
|
||||
svgAppend(pass, passPath)
|
||||
|
||||
@@ -49,12 +49,12 @@ export function addArrow () {
|
||||
refY: '10',
|
||||
markerWidth: '10',
|
||||
markerHeight: '10',
|
||||
orient: 'auto'
|
||||
orient: 'auto',
|
||||
})
|
||||
const rejectPath = svgCreate('path')
|
||||
svgAttr(rejectPath, {
|
||||
d: 'M 1 5 L 11 10 L 1 15 Z',
|
||||
class: 'highlight-reject-arrow'
|
||||
class: 'highlight-reject-arrow',
|
||||
})
|
||||
svgAppend(reject, rejectPath)
|
||||
|
||||
@@ -67,12 +67,12 @@ export function addArrow () {
|
||||
refY: '10',
|
||||
markerWidth: '10',
|
||||
markerHeight: '10',
|
||||
orient: 'auto'
|
||||
orient: 'auto',
|
||||
})
|
||||
const cancelPath = svgCreate('path')
|
||||
svgAttr(cancelPath, {
|
||||
d: 'M 1 5 L 11 10 L 1 15 Z',
|
||||
class: 'highlight-cancel-arrow'
|
||||
class: 'highlight-cancel-arrow',
|
||||
})
|
||||
svgAppend(cancel, cancelPath)
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import { withInstall } from '/@/utils'
|
||||
import flowChart from './src/FlowChart.vue'
|
||||
|
||||
export const FlowChart = withInstall(flowChart)
|
||||
@@ -1,158 +0,0 @@
|
||||
<template>
|
||||
<div class="h-full" :class="prefixCls">
|
||||
<FlowChartToolbar :prefixCls="prefixCls" v-if="toolbar" @view-data="handlePreview" />
|
||||
<div ref="lfElRef" class="h-full"></div>
|
||||
<BasicModal @register="register" title="流程数据" width="50%">
|
||||
<JsonPreview :data="graphData" />
|
||||
</BasicModal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { Ref } from 'vue'
|
||||
import type { Definition } from '@logicflow/core'
|
||||
import { defineComponent, ref, onMounted, unref, nextTick, computed, watch } from 'vue'
|
||||
import FlowChartToolbar from './FlowChartToolbar.vue'
|
||||
import LogicFlow from '@logicflow/core'
|
||||
import { Snapshot, BpmnElement, Menu, DndPanel, SelectionSelect } from '@logicflow/extension'
|
||||
import { useDesign } from '/@/hooks/web/useDesign'
|
||||
import { useAppStore } from '/@/store/modules/app'
|
||||
import { createFlowChartContext } from './useFlowContext'
|
||||
import { toLogicFlowData } from './adpterForTurbo'
|
||||
import { useModal, BasicModal } from '/@/components/Modal'
|
||||
import { JsonPreview } from '/@/components/CodeEditor'
|
||||
import { configDefaultDndPanel } from './config'
|
||||
import '@logicflow/core/dist/style/index.css'
|
||||
import '@logicflow/extension/lib/style/index.css'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FlowChart',
|
||||
components: { BasicModal, FlowChartToolbar, JsonPreview },
|
||||
props: {
|
||||
flowOptions: {
|
||||
type: Object as PropType<Definition>,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object as PropType<any>,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
||||
toolbar: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
patternItems: {
|
||||
type: Array,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const lfElRef = ref(null)
|
||||
const graphData = ref({})
|
||||
|
||||
const lfInstance = ref(null) as Ref<LogicFlow | null>
|
||||
|
||||
const { prefixCls } = useDesign('flow-chart')
|
||||
const appStore = useAppStore()
|
||||
const [register, { openModal }] = useModal()
|
||||
createFlowChartContext({
|
||||
logicFlow: lfInstance as unknown as LogicFlow,
|
||||
})
|
||||
|
||||
const getFlowOptions = computed(() => {
|
||||
const { flowOptions } = props
|
||||
|
||||
const defaultOptions: Partial<Definition> = {
|
||||
grid: true,
|
||||
background: {
|
||||
color: appStore.getDarkMode === 'light' ? '#f7f9ff' : '#151515',
|
||||
},
|
||||
keyboard: {
|
||||
enabled: true,
|
||||
},
|
||||
...flowOptions,
|
||||
}
|
||||
return defaultOptions as Definition
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
() => {
|
||||
onRender()
|
||||
},
|
||||
)
|
||||
|
||||
// TODO
|
||||
// watch(
|
||||
// () => appStore.getDarkMode,
|
||||
// () => {
|
||||
// init();
|
||||
// }
|
||||
// );
|
||||
|
||||
watch(
|
||||
() => unref(getFlowOptions),
|
||||
(options) => {
|
||||
unref(lfInstance)?.updateEditConfig(options)
|
||||
},
|
||||
)
|
||||
|
||||
// init logicFlow
|
||||
async function init() {
|
||||
await nextTick()
|
||||
|
||||
const lfEl = unref(lfElRef)
|
||||
if (!lfEl) {
|
||||
return
|
||||
}
|
||||
LogicFlow.use(DndPanel)
|
||||
|
||||
// Canvas configuration
|
||||
LogicFlow.use(Snapshot)
|
||||
// Use the bpmn plug-in to introduce bpmn elements, which can be used after conversion in turbo
|
||||
LogicFlow.use(BpmnElement)
|
||||
// Start the right-click menu
|
||||
LogicFlow.use(Menu)
|
||||
LogicFlow.use(SelectionSelect)
|
||||
|
||||
lfInstance.value = new LogicFlow({
|
||||
...unref(getFlowOptions),
|
||||
container: lfEl,
|
||||
})
|
||||
const lf = unref(lfInstance)!
|
||||
lf?.setDefaultEdgeType('line')
|
||||
onRender()
|
||||
lf?.setPatternItems(props.patternItems || configDefaultDndPanel(lf))
|
||||
}
|
||||
|
||||
async function onRender() {
|
||||
await nextTick()
|
||||
const lf = unref(lfInstance)
|
||||
if (!lf) {
|
||||
return
|
||||
}
|
||||
const lFData = toLogicFlowData(props.data)
|
||||
lf.render(lFData)
|
||||
}
|
||||
|
||||
function handlePreview() {
|
||||
const lf = unref(lfInstance)
|
||||
if (!lf) {
|
||||
return
|
||||
}
|
||||
graphData.value = unref(lf).getGraphData()
|
||||
openModal()
|
||||
}
|
||||
|
||||
onMounted(init)
|
||||
|
||||
return {
|
||||
register,
|
||||
prefixCls,
|
||||
lfElRef,
|
||||
handlePreview,
|
||||
graphData,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -1,159 +0,0 @@
|
||||
<template>
|
||||
<div :class="`${prefixCls}-toolbar`" class="flex items-center px-2 py-1">
|
||||
<template v-for="item in toolbarItemList" :key="item.type">
|
||||
<Tooltip placement="bottom" v-bind="item.disabled ? { visible: false } : {}">
|
||||
<template #title>{{ item.tooltip }}</template>
|
||||
<span :class="`${prefixCls}-toolbar__icon`" v-if="item.icon" @click="onControl(item)">
|
||||
<Icon :icon="item.icon" :class="item.disabled ? 'cursor-not-allowed disabeld' : 'cursor-pointer'" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Divider v-if="item.separate" type="vertical" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { ToolbarConfig } from './types'
|
||||
|
||||
import { defineComponent, ref, onUnmounted, unref, nextTick, watchEffect } from 'vue'
|
||||
import { Divider, Tooltip } from 'ant-design-vue'
|
||||
import { Icon } from '/@/components/Icon'
|
||||
|
||||
import { useFlowChartContext } from './useFlowContext'
|
||||
import { ToolbarTypeEnum } from './enum'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FlowChartToolbar',
|
||||
components: { Icon, Divider, Tooltip },
|
||||
props: {
|
||||
prefixCls: String,
|
||||
},
|
||||
emits: ['view-data'],
|
||||
setup(_, { emit }) {
|
||||
const toolbarItemList = ref<ToolbarConfig[]>([
|
||||
{
|
||||
type: ToolbarTypeEnum.ZOOM_IN,
|
||||
icon: 'codicon:zoom-out',
|
||||
tooltip: '缩小',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.ZOOM_OUT,
|
||||
icon: 'codicon:zoom-in',
|
||||
tooltip: '放大',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.RESET_ZOOM,
|
||||
icon: 'codicon:screen-normal',
|
||||
tooltip: '重置比例',
|
||||
},
|
||||
{ separate: true },
|
||||
{
|
||||
type: ToolbarTypeEnum.UNDO,
|
||||
icon: 'ion:arrow-undo-outline',
|
||||
tooltip: '后退',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.REDO,
|
||||
icon: 'ion:arrow-redo-outline',
|
||||
tooltip: '前进',
|
||||
disabled: true,
|
||||
},
|
||||
{ separate: true },
|
||||
{
|
||||
type: ToolbarTypeEnum.SNAPSHOT,
|
||||
icon: 'ion:download-outline',
|
||||
tooltip: '下载',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.VIEW_DATA,
|
||||
icon: 'carbon:document-view',
|
||||
tooltip: '查看数据',
|
||||
},
|
||||
])
|
||||
|
||||
const { logicFlow } = useFlowChartContext()
|
||||
|
||||
function onHistoryChange({ data: { undoAble, redoAble } }) {
|
||||
const itemsList = unref(toolbarItemList)
|
||||
const undoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.UNDO)
|
||||
const redoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.REDO)
|
||||
if (undoIndex !== -1) {
|
||||
unref(toolbarItemList)[undoIndex].disabled = !undoAble
|
||||
}
|
||||
if (redoIndex !== -1) {
|
||||
unref(toolbarItemList)[redoIndex].disabled = !redoAble
|
||||
}
|
||||
}
|
||||
|
||||
const onControl = (item) => {
|
||||
const lf = unref(logicFlow)
|
||||
if (!lf) {
|
||||
return
|
||||
}
|
||||
switch (item.type) {
|
||||
case ToolbarTypeEnum.ZOOM_IN:
|
||||
lf.zoom()
|
||||
break
|
||||
case ToolbarTypeEnum.ZOOM_OUT:
|
||||
lf.zoom(true)
|
||||
break
|
||||
case ToolbarTypeEnum.RESET_ZOOM:
|
||||
lf.resetZoom()
|
||||
break
|
||||
case ToolbarTypeEnum.UNDO:
|
||||
lf.undo()
|
||||
break
|
||||
case ToolbarTypeEnum.REDO:
|
||||
lf.redo()
|
||||
break
|
||||
case ToolbarTypeEnum.SNAPSHOT:
|
||||
lf.getSnapshot()
|
||||
break
|
||||
case ToolbarTypeEnum.VIEW_DATA:
|
||||
emit('view-data')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
watchEffect(async () => {
|
||||
if (unref(logicFlow)) {
|
||||
await nextTick()
|
||||
unref(logicFlow)?.on('history:change', onHistoryChange)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
unref(logicFlow)?.off('history:change', onHistoryChange)
|
||||
})
|
||||
return { toolbarItemList, onControl }
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
@prefix-cls: ~'@{namespace}-flow-chart-toolbar';
|
||||
|
||||
html[data-theme='dark'] {
|
||||
.lf-dnd {
|
||||
background: #080808;
|
||||
}
|
||||
}
|
||||
.@{prefix-cls} {
|
||||
height: 36px;
|
||||
background-color: @app-content-background;
|
||||
border-bottom: 1px solid @border-color-base;
|
||||
|
||||
.disabeld {
|
||||
color: @disabled-color;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
margin-right: 10px;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,75 +0,0 @@
|
||||
const TurboType = {
|
||||
SEQUENCE_FLOW: 1,
|
||||
START_EVENT: 2,
|
||||
END_EVENT: 3,
|
||||
USER_TASK: 4,
|
||||
SERVICE_TASK: 5,
|
||||
EXCLUSIVE_GATEWAY: 6,
|
||||
}
|
||||
|
||||
function convertFlowElementToEdge(element) {
|
||||
const { incoming, outgoing, properties, key } = element
|
||||
const { text, startPoint, endPoint, pointsList, logicFlowType } = properties
|
||||
const edge = {
|
||||
id: key,
|
||||
type: logicFlowType,
|
||||
sourceNodeId: incoming[0],
|
||||
targetNodeId: outgoing[0],
|
||||
text,
|
||||
startPoint,
|
||||
endPoint,
|
||||
pointsList,
|
||||
properties: {},
|
||||
}
|
||||
const excludeProperties = ['startPoint', 'endPoint', 'pointsList', 'text', 'logicFlowType']
|
||||
Object.keys(element.properties).forEach((property) => {
|
||||
if (excludeProperties.indexOf(property) === -1) {
|
||||
edge.properties[property] = element.properties[property]
|
||||
}
|
||||
})
|
||||
return edge
|
||||
}
|
||||
|
||||
function convertFlowElementToNode(element) {
|
||||
const { properties, key } = element
|
||||
const { x, y, text, logicFlowType } = properties
|
||||
const node = {
|
||||
id: key,
|
||||
type: logicFlowType,
|
||||
x,
|
||||
y,
|
||||
text,
|
||||
properties: {},
|
||||
}
|
||||
const excludeProperties = ['x', 'y', 'text', 'logicFlowType']
|
||||
Object.keys(element.properties).forEach((property) => {
|
||||
if (excludeProperties.indexOf(property) === -1) {
|
||||
node.properties[property] = element.properties[property]
|
||||
}
|
||||
})
|
||||
return node
|
||||
}
|
||||
|
||||
export function toLogicFlowData(data) {
|
||||
const lfData: {
|
||||
// TODO type
|
||||
nodes: any[]
|
||||
edges: any[]
|
||||
} = {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
}
|
||||
const list = data.flowElementList
|
||||
list &&
|
||||
list.length > 0 &&
|
||||
list.forEach((element) => {
|
||||
if (element.type === TurboType.SEQUENCE_FLOW) {
|
||||
const edge = convertFlowElementToEdge(element)
|
||||
lfData.edges.push(edge)
|
||||
} else {
|
||||
const node = convertFlowElementToNode(element)
|
||||
lfData.nodes.push(node)
|
||||
}
|
||||
})
|
||||
return lfData
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
export const nodeList = [
|
||||
{
|
||||
text: '开始',
|
||||
type: 'start',
|
||||
class: 'node-start',
|
||||
},
|
||||
{
|
||||
text: '矩形',
|
||||
type: 'rect',
|
||||
class: 'node-rect',
|
||||
},
|
||||
{
|
||||
type: 'user',
|
||||
text: '用户',
|
||||
class: 'node-user',
|
||||
},
|
||||
{
|
||||
type: 'push',
|
||||
text: '推送',
|
||||
class: 'node-push',
|
||||
},
|
||||
{
|
||||
type: 'download',
|
||||
text: '位置',
|
||||
class: 'node-download',
|
||||
},
|
||||
{
|
||||
type: 'end',
|
||||
text: '结束',
|
||||
class: 'node-end',
|
||||
},
|
||||
]
|
||||
|
||||
export const BpmnNode = [
|
||||
{
|
||||
type: 'bpmn:startEvent',
|
||||
text: '开始',
|
||||
class: 'bpmn-start',
|
||||
},
|
||||
{
|
||||
type: 'bpmn:endEvent',
|
||||
text: '结束',
|
||||
class: 'bpmn-end',
|
||||
},
|
||||
{
|
||||
type: 'bpmn:exclusiveGateway',
|
||||
text: '网关',
|
||||
class: 'bpmn-exclusiveGateway',
|
||||
},
|
||||
{
|
||||
type: 'bpmn:userTask',
|
||||
text: '用户',
|
||||
class: 'bpmn-user',
|
||||
},
|
||||
]
|
||||
|
||||
export function configDefaultDndPanel(lf) {
|
||||
return [
|
||||
{
|
||||
text: '选区',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAOVJREFUOBGtVMENwzAIjKP++2026ETdpv10iy7WFbqFyyW6GBywLCv5gI+Dw2Bluj1znuSjhb99Gkn6QILDY2imo60p8nsnc9bEo3+QJ+AKHfMdZHnl78wyTnyHZD53Zzx73MRSgYvnqgCUHj6gwdck7Zsp1VOrz0Uz8NbKunzAW+Gu4fYW28bUYutYlzSa7B84Fh7d1kjLwhcSdYAYrdkMQVpsBr5XgDGuXwQfQr0y9zwLda+DUYXLaGKdd2ZTtvbolaO87pdo24hP7ov16N0zArH1ur3iwJpXxm+v7oAJNR4JEP8DoAuSFEkYH7cAAAAASUVORK5CYII=',
|
||||
callback: () => {
|
||||
lf.updateEditConfig({
|
||||
stopMoveGraph: true,
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'circle',
|
||||
text: '开始',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAnBJREFUOBGdVL1rU1EcPfdGBddmaZLiEhdx1MHZQXApraCzQ7GKLgoRBxMfcRELuihWKcXFRcEWF8HBf0DdDCKYRZpnl7p0svLe9Zzbd29eQhTbC8nv+9zf130AT63jvooOGS8Vf9Nt5zxba7sXQwODfkWpkbjTQfCGUd9gIp3uuPP8bZ946g56dYQvnBg+b1HB8VIQmMFrazKcKSvFW2dQTxJnJdQ77urmXWOMBCmXM2Rke4S7UAW+/8ywwFoewmBps2tu7mbTdp8VMOkIRAkKfrVawalJTtIliclFbaOBqa0M2xImHeVIfd/nKAfVq/LGnPss5Kh00VEdSzfwnBXPUpmykNss4lUI9C1ga+8PNrBD5YeqRY2Zz8PhjooIbfJXjowvQJBqkmEkVnktWhwu2SM7SMx7Cj0N9IC0oQXRo8xwAGzQms+xrB/nNSUWVveI48ayrFGyC2+E2C+aWrZHXvOuz+CiV6iycWe1Rd1Q6+QUG07nb5SbPrL4426d+9E1axKjY3AoRrlEeSQo2Eu0T6BWAAr6COhTcWjRaYfKG5csnvytvUr/WY4rrPMB53Uo7jZRjXaG6/CFfNMaXEu75nG47X+oepU7PKJvvzGDY1YLSKHJrK7vFUwXKkaxwhCW3u+sDFMVrIju54RYYbFKpALZAo7sB6wcKyyrd+aBMryMT2gPyD6GsQoRFkGHr14TthZni9ck0z+Pnmee460mHXbRAypKNy3nuMdrWgVKj8YVV8E7PSzp1BZ9SJnJAsXdryw/h5ctboUVi4AFiCd+lQaYMw5z3LGTBKjLQOeUF35k89f58Vv/tGh+l+PE/wG0rgfIUbZK5AAAAABJRU5ErkJggg==',
|
||||
},
|
||||
{
|
||||
type: 'rect',
|
||||
text: '用户任务',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==',
|
||||
cls: 'important-node',
|
||||
},
|
||||
{
|
||||
type: 'rect',
|
||||
text: '系统任务',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==',
|
||||
cls: 'import_icon',
|
||||
},
|
||||
{
|
||||
type: 'diamond',
|
||||
text: '条件判断',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAAHeEJUAAAAABGdBTUEAALGPC/xhBQAAAvVJREFUOBGNVEFrE0EU/mY3bQoiFlOkaUJrQUQoWMGePLX24EH0IIoHKQiCV0G8iE1covgLiqA/QTzVm1JPogc9tIJYFaQtlhQxqYjSpunu+L7JvmUTU3AgmTfvffPNN++9WSA1DO182f6xwILzD5btfAoQmwL5KJEwiQyVbSVZ0IgRyV6PTpIJ81E5ZvqfHQR0HUOBHW4L5Et2kQ6Zf7iAOhTFAA8s0pEP7AXO1uAA52SbqGk6h/6J45LaLhO64ByfcUzM39V7ZiAdS2yCePPEIQYvTUHqM/n7dgQNfBKWPjpF4ISk8q3J4nB11qw6X8l+FsF3EhlkEMfrjIer3wJTLwS2aCNcj4DbGxXTw00JmAuO+Ni6bBxVUCvS5d9aa04+so4pHW5jLTywuXAL7jJ+D06sl82Sgl2JuVBQn498zkc2bGKxULHjCnSMadBKYDYYHAtsby1EQ5lNGrQd4Y3v4Zo0XdGEmDno46yCM9Tk+RiJmUYHS/aXHPNTcjxcbTFna000PFJHIVZ5lFRqRpJWk9/+QtlOUYJj9HG5pVFEU7zqIYDVsw2s+AJaD8wTd2umgSCCyUxgGsS1Y6TBwXQQTFuZaHcd8gAGioE90hlsY+wMcs30RduYtxanjMGal8H5dMW67dmT1JFtYUEe8LiQLRsPZ6IIc7A4J5tqco3T0pnv/4u0kyzrYUq7gASuEyI8VXKvB9Odytv6jS/PNaZBln0nioJG/AVQRZvApOdhjj3Jt8QC8Im09SafwdBdvIpztpxWxpeKCC+EsFdS8DCyuCn2munFpL7ctHKp+Xc5cMybeIyMAN33SPL3ZR9QV1XVwLyzHm6Iv0/yeUuUb7PPlZC4D4HZkeu6dpF4v9j9MreGtMbxMMRLIcjJic9yHi7WQ3yVKzZVWUr5UrViJvn1FfUlwe/KYVfYyWRLSGNu16hR01U9IacajXPei0wx/5BqgInvJN+MMNtNme7ReU9SBbgntovn0kKHpFg7UogZvaZiOue/q1SBo9ktHzQAAAAASUVORK5CYII=',
|
||||
},
|
||||
{
|
||||
type: 'circle',
|
||||
text: '结束',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC',
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
export enum ToolbarTypeEnum {
|
||||
ZOOM_IN = 'zoomIn',
|
||||
ZOOM_OUT = 'zoomOut',
|
||||
RESET_ZOOM = 'resetZoom',
|
||||
|
||||
UNDO = 'undo',
|
||||
REDO = 'redo',
|
||||
|
||||
SNAPSHOT = 'snapshot',
|
||||
VIEW_DATA = 'viewData',
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { NodeConfig } from '@logicflow/core'
|
||||
import { ToolbarTypeEnum } from './enum'
|
||||
|
||||
export interface NodeItem extends NodeConfig {
|
||||
icon: string
|
||||
}
|
||||
|
||||
export interface ToolbarConfig {
|
||||
type?: string | ToolbarTypeEnum
|
||||
tooltip?: string | boolean
|
||||
icon?: string
|
||||
disabled?: boolean
|
||||
separate?: boolean
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import type LogicFlow from '@logicflow/core'
|
||||
|
||||
import { provide, inject } from 'vue'
|
||||
|
||||
const key = Symbol('flow-chart')
|
||||
|
||||
type Instance = {
|
||||
logicFlow: LogicFlow
|
||||
}
|
||||
|
||||
export function createFlowChartContext(instance: Instance) {
|
||||
provide(key, instance)
|
||||
}
|
||||
|
||||
export function useFlowChartContext(): Instance {
|
||||
return inject(key) as Instance
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defHttp } from '/@/utils/http/axios'
|
||||
import { BaseEntity } from '/#/web'
|
||||
import { PageResult, Result } from '/#/axios'
|
||||
import { BpmModelNode } from '/@/views/modules/bpm/model/ModelNode.api'
|
||||
import { BpmModelNode } from '/@/views/modules/bpm/model/node/ModelNode.api'
|
||||
|
||||
/**
|
||||
* 分页
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
</div>
|
||||
<bpm-model-edit ref="bpmModelEdit" @ok="queryPage" />
|
||||
<bpm-model-node-list ref="bpmModelNodeList" />
|
||||
<bpm-modeler ref="bpmModeler" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -93,11 +94,12 @@
|
||||
import { copy, del, page, publish, verifyModel } from '/@/views/modules/bpm/model/Model.api'
|
||||
import BQuery from '/@/components/Bootx/Query/BQuery.vue'
|
||||
import { useDict } from '/@/hooks/bootx/useDict'
|
||||
import { PUBLISHED, UNPUBLISHED } from './BpmModelNodeCode'
|
||||
import { PUBLISHED, UNPUBLISHED } from './node/BpmModelNodeCode'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { FormEditType } from '/@/enums/formTypeEnum'
|
||||
import BpmModelEdit from './BpmModelEdit.vue'
|
||||
import BpmModelNodeList from './BpmModelNodeList.vue'
|
||||
import BpmModelNodeList from './node/BpmModelNodeList.vue'
|
||||
import BpmModeler from './BpmModeler.vue'
|
||||
|
||||
const { handleTableChange, resetQueryParams, pageQueryResHandel, pagination, pages, model, loading } = useTablePage(queryPage)
|
||||
const { dictConvert } = useDict()
|
||||
|
||||
110
src/views/modules/bpm/model/BpmModeler.vue
Normal file
110
src/views/modules/bpm/model/BpmModeler.vue
Normal file
File diff suppressed because one or more lines are too long
@@ -117,7 +117,7 @@
|
||||
USER_GROUP,
|
||||
USER,
|
||||
ROLE,
|
||||
} from '/@/views/modules/bpm/model/BpmModelNodeCode'
|
||||
} from '/@/views/modules/bpm/model/node/BpmModelNodeCode'
|
||||
import BUserSelectModal from '/@/components/Bootx/UserSelectModal/BUserSelectModal.vue'
|
||||
import BRoleSelectModal from '/@/components/Bootx/RoleSelectModal/BRoleSelectModal.vue'
|
||||
import { UserInfo } from '/@/views/modules/system/user/User.api'
|
||||
@@ -51,8 +51,8 @@
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { useDict } from '/@/hooks/bootx/useDict'
|
||||
import { $ref } from 'vue/macros'
|
||||
import { BpmModel } from './Model.api'
|
||||
import { PUBLISHED } from '/@/views/modules/bpm/model/BpmModelNodeCode'
|
||||
import { BpmModel } from '../Model.api'
|
||||
import { PUBLISHED } from '/@/views/modules/bpm/model/node/BpmModelNodeCode'
|
||||
import { BpmModelNode, del, listByModelId, sync } from './ModelNode.api'
|
||||
import BpmModelNodeEdit from './BpmModelNodeEdit.vue'
|
||||
import { FormEditType } from '/@/enums/formTypeEnum'
|
||||
82
src/views/modules/develop/query/QuerySql.api.ts
Normal file
82
src/views/modules/develop/query/QuerySql.api.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { defHttp } from '/@/utils/http/axios'
|
||||
import { PageResult, Result } from '/#/axios'
|
||||
import { BaseEntity } from '/#/web'
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
export function page(params) {
|
||||
return defHttp.get<Result<PageResult<QuerySql>>>({
|
||||
url: '/query/sql/page',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全部
|
||||
*/
|
||||
export function findAll() {
|
||||
return defHttp.get<Result<QuerySql[]>>({
|
||||
url: '/query/sql/findAll',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单条
|
||||
*/
|
||||
export function get(id) {
|
||||
return defHttp.get<Result<QuerySql>>({
|
||||
url: '/query/sql/findById',
|
||||
params: { id },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*/
|
||||
export function add(obj: QuerySql) {
|
||||
return defHttp.post({
|
||||
url: '/query/sql/add',
|
||||
data: obj,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*/
|
||||
export function update(obj: QuerySql) {
|
||||
return defHttp.post({
|
||||
url: '/query/sql/update',
|
||||
data: obj,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
export function del(id) {
|
||||
return defHttp.delete({
|
||||
url: '/query/sql/delete',
|
||||
params: { id },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL查询语句
|
||||
*/
|
||||
export interface QuerySql extends BaseEntity {
|
||||
// 数据源ID
|
||||
databaseId?: string
|
||||
// 名称
|
||||
name?: string
|
||||
// sql语句
|
||||
sql?: string
|
||||
// 是否集合
|
||||
isList?: boolean
|
||||
// SQL查询参数
|
||||
params?: string
|
||||
// SQL查询结果字段
|
||||
fields?: string
|
||||
// 备注
|
||||
remark?: string
|
||||
}
|
||||
133
src/views/modules/develop/query/QuerySqlEdit.vue
Normal file
133
src/views/modules/develop/query/QuerySqlEdit.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<basic-modal
|
||||
defaultFullscreen
|
||||
v-bind="$attrs"
|
||||
:loading="confirmLoading"
|
||||
:title="title"
|
||||
:width="modalWidth"
|
||||
:visible="visible"
|
||||
:mask-closable="showable"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form
|
||||
class="small-from-item"
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
:validate-trigger="['blur', 'change']"
|
||||
:label-col="labelCol"
|
||||
:wrapper-col="wrapperCol"
|
||||
>
|
||||
<a-form-item label="主键" :hidden="true">
|
||||
<a-input v-model:value="form.id" :disabled="showable" />
|
||||
</a-form-item>
|
||||
<a-form-item label="数据源ID" name="databaseId">
|
||||
<a-input v-model:value="form.databaseId" :disabled="showable" placeholder="请输入数据源ID" />
|
||||
</a-form-item>
|
||||
<a-form-item label="名称" name="name">
|
||||
<a-input v-model:value="form.name" :disabled="showable" placeholder="请输入名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="sql语句" name="sql">
|
||||
<a-input v-model:value="form.sql" :disabled="showable" placeholder="请输入sql语句" />
|
||||
</a-form-item>
|
||||
<a-form-item label="是否集合" name="isList">
|
||||
<a-input v-model:value="form.isList" :disabled="showable" placeholder="请输入是否集合" />
|
||||
</a-form-item>
|
||||
<a-form-item label="SQL查询参数" name="params">
|
||||
<a-input v-model:value="form.params" :disabled="showable" placeholder="请输入SQL查询参数" />
|
||||
</a-form-item>
|
||||
<a-form-item label="SQL查询结果字段" name="fields">
|
||||
<a-input v-model:value="form.fields" :disabled="showable" placeholder="请输入SQL查询结果字段" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-space>
|
||||
<a-button key="cancel" @click="handleCancel">取消</a-button>
|
||||
<a-button v-if="!showable" key="forward" :loading="confirmLoading" type="primary" @click="handleOk">保存</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</basic-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, reactive } from 'vue'
|
||||
import { $ref } from 'vue/macros'
|
||||
import useFormEdit from '/@/hooks/bootx/useFormEdit'
|
||||
import { add, get, update, QuerySql } from './QuerySql.api'
|
||||
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
|
||||
import { FormEditType } from '/@/enums/formTypeEnum'
|
||||
import { BasicModal } from '/@/components/Modal'
|
||||
const {
|
||||
initFormEditType,
|
||||
handleCancel,
|
||||
search,
|
||||
labelCol,
|
||||
wrapperCol,
|
||||
modalWidth,
|
||||
title,
|
||||
confirmLoading,
|
||||
visible,
|
||||
editable,
|
||||
showable,
|
||||
formEditType,
|
||||
} = useFormEdit()
|
||||
// 表单
|
||||
const formRef = $ref<FormInstance>()
|
||||
let form = $ref<QuerySql>({
|
||||
id: null,
|
||||
databaseId: undefined,
|
||||
name: '',
|
||||
sql: '',
|
||||
isList: false,
|
||||
params: undefined,
|
||||
fields: undefined,
|
||||
})
|
||||
// 校验
|
||||
const rules = reactive({} as Record<string, Rule[]>)
|
||||
// 事件
|
||||
const emits = defineEmits(['ok'])
|
||||
// 入口
|
||||
function init(id, editType: FormEditType) {
|
||||
initFormEditType(editType)
|
||||
resetForm()
|
||||
getInfo(id, editType)
|
||||
}
|
||||
// 获取信息
|
||||
function getInfo(id, editType: FormEditType) {
|
||||
if ([FormEditType.Edit, FormEditType.Show].includes(editType)) {
|
||||
confirmLoading.value = true
|
||||
get(id).then(({ data }) => {
|
||||
form = data
|
||||
confirmLoading.value = false
|
||||
})
|
||||
} else {
|
||||
confirmLoading.value = false
|
||||
}
|
||||
}
|
||||
// 保存
|
||||
function handleOk() {
|
||||
formRef?.validate().then(async () => {
|
||||
confirmLoading.value = true
|
||||
if (formEditType.value === FormEditType.Add) {
|
||||
await add(form)
|
||||
} else if (formEditType.value === FormEditType.Edit) {
|
||||
await update(form)
|
||||
}
|
||||
confirmLoading.value = false
|
||||
handleCancel()
|
||||
emits('ok')
|
||||
})
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
function resetForm() {
|
||||
nextTick(() => {
|
||||
formRef?.resetFields()
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
init,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
121
src/views/modules/develop/query/QuerySqlList.vue
Normal file
121
src/views/modules/develop/query/QuerySqlList.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="m-3 p-3 pt-5 bg-white">
|
||||
<b-query :query-params="model.queryParam" :fields="fields" @query="queryPage" @reset="resetQueryParams" />
|
||||
</div>
|
||||
<div class="m-3 p-3 bg-white">
|
||||
<vxe-toolbar ref="xToolbar" custom :refresh="{ query: queryPage }">
|
||||
<template #buttons>
|
||||
<a-space>
|
||||
<a-button type="primary" pre-icon="ant-design:plus-outlined" @click="add">新建</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</vxe-toolbar>
|
||||
<vxe-table row-id="id" ref="xTable" :data="pagination.records" :loading="loading">
|
||||
<vxe-column type="seq" width="60" />
|
||||
<vxe-column field="databaseId" title="数据源ID" />
|
||||
<vxe-column field="name" title="名称" />
|
||||
<vxe-column field="sql" title="sql语句" />
|
||||
<vxe-column field="isList" title="是否集合">
|
||||
<template #default="{ row }">
|
||||
<a-tag>{{ row.isList ? '是' : '否' }}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="remark" title="备注" />
|
||||
<vxe-column field="createTime" title="创建时间" />
|
||||
<vxe-column fixed="right" width="220" :showOverflow="false" title="操作">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
<a-link @click="show(row)">查看</a-link>
|
||||
</span>
|
||||
<a-divider type="vertical" />
|
||||
<span>
|
||||
<a-link @click="edit(row)">编辑</a-link>
|
||||
</span>
|
||||
<span>
|
||||
<a-link @click="edit(row)">测试</a-link>
|
||||
</span>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm title="是否删除" @confirm="remove(row)" okText="是" cancelText="否">
|
||||
<a-link danger>删除</a-link>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<vxe-pager
|
||||
size="medium"
|
||||
:loading="loading"
|
||||
:current-page="pagination.current"
|
||||
:page-size="pagination.size"
|
||||
:total="pagination.total"
|
||||
@page-change="handleTableChange"
|
||||
/>
|
||||
<query-sql-edit ref="querySqlEdit" @ok="queryPage" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue'
|
||||
import { $ref } from 'vue/macros'
|
||||
import { del, page } from './QuerySql.api'
|
||||
import useTablePage from '/@/hooks/bootx/useTablePage'
|
||||
import QuerySqlEdit from './QuerySqlEdit.vue'
|
||||
import { VxeTableInstance, VxeToolbarInstance } from 'vxe-table'
|
||||
import BQuery from '/@/components/Bootx/Query/BQuery.vue'
|
||||
import { FormEditType } from '/@/enums/formTypeEnum'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { QueryField } from '/@/components/Bootx/Query/Query'
|
||||
|
||||
// 使用hooks
|
||||
const { handleTableChange, pageQueryResHandel, resetQueryParams, pagination, pages, model, loading } = useTablePage(queryPage)
|
||||
const { notification, createMessage, createConfirm } = useMessage()
|
||||
|
||||
// 查询条件
|
||||
const fields = [] as QueryField[]
|
||||
|
||||
const xTable = $ref<VxeTableInstance>()
|
||||
const xToolbar = $ref<VxeToolbarInstance>()
|
||||
const querySqlEdit = $ref<any>()
|
||||
|
||||
onMounted(() => {
|
||||
vxeBind()
|
||||
queryPage()
|
||||
})
|
||||
function vxeBind() {
|
||||
xTable?.connect(xToolbar as VxeToolbarInstance)
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
function queryPage() {
|
||||
loading.value = true
|
||||
page({
|
||||
...model.queryParam,
|
||||
...pages,
|
||||
}).then(({ data }) => {
|
||||
pageQueryResHandel(data)
|
||||
})
|
||||
}
|
||||
// 新增
|
||||
function add() {
|
||||
querySqlEdit.init(null, FormEditType.Add)
|
||||
}
|
||||
// 编辑
|
||||
function edit(record) {
|
||||
querySqlEdit.init(record.id, FormEditType.Edit)
|
||||
}
|
||||
// 查看
|
||||
function show(record) {
|
||||
querySqlEdit.init(record.id, FormEditType.Show)
|
||||
}
|
||||
|
||||
// 删除
|
||||
function remove(record) {
|
||||
del(record.id).then(() => {
|
||||
createMessage.success('删除成功')
|
||||
queryPage()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
38
yarn.lock
38
yarn.lock
@@ -1324,24 +1324,6 @@
|
||||
"@jridgewell/resolve-uri" "^3.0.3"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
|
||||
"@logicflow/core@^1.1.13", "@logicflow/core@^1.1.21":
|
||||
version "1.1.21"
|
||||
resolved "https://registry.npmmirror.com/@logicflow/core/-/core-1.1.21.tgz#80f3651a9559e7bf90631814f5cd3fe61e543e7a"
|
||||
integrity sha512-LfFnHV009HhozPSWyFlLwsIsEXniFtjJKHGxQVxzRDwKqsgBOUBwyCTbDgejTIc4fw0zaINYhG5YRFSPGsDzWQ==
|
||||
dependencies:
|
||||
"@types/mousetrap" "^1.6.4"
|
||||
mousetrap "^1.6.5"
|
||||
preact "^10.4.8"
|
||||
|
||||
"@logicflow/extension@^1.1.13":
|
||||
version "1.1.21"
|
||||
resolved "https://registry.npmmirror.com/@logicflow/extension/-/extension-1.1.21.tgz#efa91c2fe6712568270e222ff7b73859caf09d45"
|
||||
integrity sha512-jUrChV89BC7QsyejGt3tIWX9/EGI/Rh+LFsht0OZDafgabk4D99D3J8Glg1UC/unh9dOUNDoD3Hs3xaO8gDBzg==
|
||||
dependencies:
|
||||
"@logicflow/core" "^1.1.21"
|
||||
ids "^1.0.0"
|
||||
preact "^10.4.8"
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||
@@ -1750,11 +1732,6 @@
|
||||
resolved "https://registry.npmmirror.com/@types/mockjs/-/mockjs-1.0.6.tgz#dafdd5de65156f7aa63eab4e29fa3d532cd95609"
|
||||
integrity sha512-Yu5YlqbYZyqsd6LjO4e8ONJDN9pTSnciHDcRP4teNOh/au2b8helFhgRx+3w8xsTFEnwr9jtfTVJbAx+eYmlHA==
|
||||
|
||||
"@types/mousetrap@^1.6.4":
|
||||
version "1.6.9"
|
||||
resolved "https://registry.npmmirror.com/@types/mousetrap/-/mousetrap-1.6.9.tgz#f1ef9adbd1eac3466f21b6988b1c82c633a45340"
|
||||
integrity sha512-HUAiN65VsRXyFCTicolwb5+I7FM6f72zjMWr+ajGk+YTvzBgXqa2A5U7d+rtsouAkunJ5U4Sb5lNJjo9w+nmXg==
|
||||
|
||||
"@types/node@*", "@types/node@>=12":
|
||||
version "18.0.3"
|
||||
resolved "https://registry.npmmirror.com/@types/node/-/node-18.0.3.tgz#463fc47f13ec0688a33aec75d078a0541a447199"
|
||||
@@ -3107,11 +3084,6 @@ chardet@^0.7.0:
|
||||
resolved "https://registry.npmmirror.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
||||
|
||||
china-area-data@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmmirror.com/china-area-data/-/china-area-data-5.0.1.tgz#7943b83a0619f033bb5893da80cb46e52e44be66"
|
||||
integrity sha512-BQDPpiv5Nn+018ekcJK2oSD9PAD+E1bvXB0wgabc//dFVS/KvRqCgg0QOEUt3vBkx9XzB5a9BmkJCEZDBxVjVw==
|
||||
|
||||
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2:
|
||||
version "3.5.3"
|
||||
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
@@ -7126,11 +7098,6 @@ modify-values@^1.0.0:
|
||||
resolved "https://registry.npmmirror.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
|
||||
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
|
||||
|
||||
mousetrap@^1.6.5:
|
||||
version "1.6.5"
|
||||
resolved "https://registry.npmmirror.com/mousetrap/-/mousetrap-1.6.5.tgz#8a766d8c272b08393d5f56074e0b5ec183485bf9"
|
||||
integrity sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==
|
||||
|
||||
mozjpeg@^7.0.0:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.npmmirror.com/mozjpeg/-/mozjpeg-7.1.1.tgz#dfb61953536e66fcabd4ae795e7a312d42a51f18"
|
||||
@@ -7943,11 +7910,6 @@ posthtml@^0.9.2:
|
||||
posthtml-parser "^0.2.0"
|
||||
posthtml-render "^1.0.5"
|
||||
|
||||
preact@^10.4.8:
|
||||
version "10.9.0"
|
||||
resolved "https://registry.npmmirror.com/preact/-/preact-10.9.0.tgz#69b282b26926b66481c9ae3450cf68610fee29ff"
|
||||
integrity sha512-jO6/OvCRL+OT8gst/+Q2ir7dMybZAX8ioP02Zmzh3BkQMHLyqZSujvxbUriXvHi8qmhcHKC2Gwbog6Kt+YTh+Q==
|
||||
|
||||
preact@^10.5.13:
|
||||
version "10.11.3"
|
||||
resolved "https://registry.npmmirror.com/preact/-/preact-10.11.3.tgz#8a7e4ba19d3992c488b0785afcc0f8aa13c78d19"
|
||||
|
||||
Reference in New Issue
Block a user