完善只读模式

This commit is contained in:
caixiaofeng 2024-05-21 12:50:43 +08:00
parent b48706c2c4
commit be7f45ff0a
6 changed files with 101 additions and 51 deletions

View File

@ -10,6 +10,7 @@ declare module 'vue' {
AdvancedFilter: typeof import('./../components/AdvancedFilter/index.vue')['default'] AdvancedFilter: typeof import('./../components/AdvancedFilter/index.vue')['default']
ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
ElCard: typeof import('element-plus/es')['ElCard'] ElCard: typeof import('element-plus/es')['ElCard']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol'] ElCol: typeof import('element-plus/es')['ElCol']
@ -17,6 +18,9 @@ declare module 'vue' {
ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer'] ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElForm: typeof import('element-plus/es')['ElForm'] ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon'] ElIcon: typeof import('element-plus/es')['ElIcon']

View File

@ -12,7 +12,6 @@ import type {
} from './nodes/type' } from './nodes/type'
import type { FilterRules } from '@/components/AdvancedFilter/type' import type { FilterRules } from '@/components/AdvancedFilter/type'
import type { Field } from '@/components/Render/type' import type { Field } from '@/components/Render/type'
import { downloadXml } from '@/api/modules/model'
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
@ -27,7 +26,6 @@ const props = withDefaults(
} }
) )
const isDark = ref(false)
const flatFields = computed(() => { const flatFields = computed(() => {
const all: Field[] = [] const all: Field[] = []
const loop = (children: Field[]) => { const loop = (children: Field[]) => {
@ -45,6 +43,7 @@ const flatFields = computed(() => {
}) })
const getScale = computed(() => zoom.value / 100) const getScale = computed(() => zoom.value / 100)
const zoom = ref(props.defaultZoom) const zoom = ref(props.defaultZoom)
const readOnly = computed(() => props.readOnly)
const activeData = ref<FlowNode>({ const activeData = ref<FlowNode>({
id: '', id: '',
name: '', name: '',
@ -53,17 +52,10 @@ const activeData = ref<FlowNode>({
const penalVisible = ref(false) const penalVisible = ref(false)
const nodesError = ref<Recordable<ErrorInfo[]>>({}) const nodesError = ref<Recordable<ErrorInfo[]>>({})
provide('flowDesign', { provide('flowDesign', {
readOnly: props.readOnly || false, readOnly: readOnly,
fields: flatFields, fields: flatFields,
nodesError: nodesError nodesError: nodesError
}) })
const handleToggleDark = () => {
if (isDark.value) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
}
const openPenal = (node: FlowNode) => { const openPenal = (node: FlowNode) => {
activeData.value = node activeData.value = node
penalVisible.value = true penalVisible.value = true
@ -284,23 +276,6 @@ const validate = () => {
} }
}) })
} }
const converterBpmn = () => {
const processModel = {
code: 'test',
name: '测试',
icon: {
name: 'el:HomeFilled',
color: '#409EFF'
},
process: props.process,
enable: true,
version: 1,
sort: 0,
groupId: '',
remark: ''
}
downloadXml(processModel)
}
defineExpose({ defineExpose({
validate validate
}) })
@ -309,13 +284,7 @@ defineExpose({
<template> <template>
<div class="designer-container"> <div class="designer-container">
<div class="tool"> <div class="tool">
<el-switch <slot></slot>
inline-prompt
active-icon="Sunny"
inactive-icon="Moon"
@change="handleToggleDark"
v-model="isDark"
/>
</div> </div>
<!--放大/缩小--> <!--放大/缩小-->
<div class="zoom"> <div class="zoom">
@ -326,7 +295,6 @@ defineExpose({
<el-tooltip content="缩小" placement="bottom-start"> <el-tooltip content="缩小" placement="bottom-start">
<el-button icon="minus" @click="zoom -= 10" circle :disabled="zoom <= 50"></el-button> <el-button icon="minus" @click="zoom -= 10" circle :disabled="zoom <= 50"></el-button>
</el-tooltip> </el-tooltip>
<el-button @click="converterBpmn" type="primary" icon="Download">转bpmn</el-button>
</div> </div>
<!--流程树--> <!--流程树-->
<div class="node-container"> <div class="node-container">
@ -361,8 +329,10 @@ defineExpose({
.tool { .tool {
position: fixed; position: fixed;
z-index: 999; z-index: 999;
top: 10px; top: 5px;
left: 20px; left: 5px;
display: flex;
gap: 5px;
} }
.node-container { .node-container {

View File

@ -1,10 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import type { PopoverInstance } from 'element-plus' import type { PopoverInstance } from 'element-plus'
import type { NodeType } from './type' import type { NodeType } from './type'
import type { Ref } from 'vue'
const { readOnly } = inject<{ const { readOnly } = inject<{
readOnly?: boolean readOnly?: Ref<boolean>
}>('flowDesign', { readOnly: false }) }>('flowDesign', { readOnly: ref(false) })
const popoverRef = ref<PopoverInstance>() const popoverRef = ref<PopoverInstance>()
const $emits = defineEmits<{ const $emits = defineEmits<{
(e: 'addNode', type: NodeType): void (e: 'addNode', type: NodeType): void
@ -100,6 +101,7 @@ const addTimerNode = () => {
&.Share { &.Share {
background-color: #45cf9b; background-color: #45cf9b;
} }
&.Timer { &.Timer {
background-color: #e872b7; background-color: #e872b7;
} }

View File

@ -2,6 +2,7 @@
import TreeNode from './TreeNode.vue' import TreeNode from './TreeNode.vue'
import type { BranchNode, FlowNode, NodeType } from './type' import type { BranchNode, FlowNode, NodeType } from './type'
import Add from './Add.vue' import Add from './Add.vue'
import type { Ref } from 'vue'
const $emits = defineEmits<{ const $emits = defineEmits<{
(e: 'addNode', type: NodeType, node: FlowNode): void (e: 'addNode', type: NodeType, node: FlowNode): void
@ -10,8 +11,8 @@ const props = defineProps<{
node: BranchNode node: BranchNode
}>() }>()
const { readOnly } = inject<{ const { readOnly } = inject<{
readOnly?: boolean readOnly?: Ref<boolean>
}>('flowDesign', { readOnly: false }) }>('flowDesign', { readOnly: ref(false) })
const addNode = (type: NodeType, node?: FlowNode) => { const addNode = (type: NodeType, node?: FlowNode) => {
$emits('addNode', type, node || props.node) $emits('addNode', type, node || props.node)
} }

View File

@ -5,9 +5,9 @@ import Add from './Add.vue'
import type { Ref } from 'vue' import type { Ref } from 'vue'
const _inject = inject<{ const _inject = inject<{
readOnly?: boolean readOnly?: Ref<boolean>
nodesError: Ref<Recordable<ErrorInfo[]>> nodesError: Ref<Recordable<ErrorInfo[]>>
}>('flowDesign', { readOnly: false, nodesError: ref({}) }) }>('flowDesign', { readOnly: ref(false), nodesError: ref({}) })
const $emits = defineEmits<{ const $emits = defineEmits<{
(e: 'addNode', type: NodeType, node: FlowNode): void (e: 'addNode', type: NodeType, node: FlowNode): void
(e: 'delNode', node: FlowNode): void (e: 'delNode', node: FlowNode): void
@ -27,7 +27,7 @@ const $props = withDefaults(
} }
) )
const errorInfo = computed<ErrorInfo[] | undefined>(() => _inject.nodesError.value[$props.node.id]) const errorInfo = computed<ErrorInfo[] | undefined>(() => _inject.nodesError.value[$props.node.id])
const _readOnly = computed(() => _inject.readOnly || $props.readOnly) const _readOnly = computed(() => _inject.readOnly?.value || $props.readOnly)
const showInput = ref(false) const showInput = ref(false)
const inputRef = ref<InputInstance>() const inputRef = ref<InputInstance>()
const onShowInput = () => { const onShowInput = () => {
@ -56,7 +56,10 @@ const delNode = () => {
<template> <template>
<div class="node-box"> <div class="node-box">
<el-card @click="activeNode" :class="['node', { 'error-node': errorInfo?.length }]"> <el-card
@click="activeNode"
:class="['node', { 'error-node': errorInfo?.length && !_readOnly }]"
>
<!--头部--> <!--头部-->
<template #header> <template #header>
<div class="head"> <div class="head">
@ -108,7 +111,7 @@ const delNode = () => {
{{ err.message }} {{ err.message }}
</div> </div>
</template> </template>
<el-icon class="warn-icon" :size="20" v-show="errorInfo?.length"> <el-icon class="warn-icon" :size="20" v-show="errorInfo?.length && !_readOnly">
<WarnTriangleFilled @click.stop /> <WarnTriangleFilled @click.stop />
</el-icon> </el-icon>
</el-tooltip> </el-tooltip>
@ -198,6 +201,7 @@ const delNode = () => {
background-color: var(--el-card-bg-color); background-color: var(--el-card-bg-color);
} }
} }
:deep(.el-card__body) { :deep(.el-card__body) {
position: relative; position: relative;
} }

View File

@ -2,6 +2,7 @@
import FlowDesign from '@/views/flowDesign/index.vue' import FlowDesign from '@/views/flowDesign/index.vue'
import type { Field } from '@/components/Render/type' import type { Field } from '@/components/Render/type'
import type { EndNode, FlowNode, StartNode } from '@/views/flowDesign/nodes/type' import type { EndNode, FlowNode, StartNode } from '@/views/flowDesign/nodes/type'
import { downloadXml } from '@/api/modules/model'
// //
const process = ref<FlowNode>({ const process = ref<FlowNode>({
@ -27,7 +28,7 @@ const fields = ref<Field[]>([
name: 'UserSelector', name: 'UserSelector',
value: null, value: null,
readonly: false, readonly: false,
required: false, required: true,
hidden: false, hidden: false,
props: { props: {
multiple: false, multiple: false,
@ -45,7 +46,7 @@ const fields = ref<Field[]>([
name: 'ElInputNumber', name: 'ElInputNumber',
value: null, value: null,
readonly: false, readonly: false,
required: false, required: true,
hidden: false, hidden: false,
props: { props: {
disabled: false, disabled: false,
@ -66,7 +67,7 @@ const fields = ref<Field[]>([
name: 'ElSelect', name: 'ElSelect',
value: null, value: null,
readonly: false, readonly: false,
required: false, required: true,
hidden: false, hidden: false,
props: { props: {
disabled: false, disabled: false,
@ -110,7 +111,7 @@ const fields = ref<Field[]>([
name: 'ElInput', name: 'ElInput',
value: null, value: null,
readonly: false, readonly: false,
required: false, required: true,
hidden: false, hidden: false,
props: { props: {
type: 'textarea', type: 'textarea',
@ -126,10 +127,78 @@ const fields = ref<Field[]>([
} }
} }
]) ])
//
const readOnly = ref(false)
//
const isDark = ref(false)
const converterBpmn = () => {
const processModel = {
code: 'test',
name: '测试',
icon: {
name: 'el:HomeFilled',
color: '#409EFF'
},
process: process.value,
enable: true,
version: 1,
sort: 0,
groupId: '',
remark: ''
}
downloadXml(processModel)
}
const handleToggleDark = () => {
if (isDark.value) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
}
const gitee = () => {
window.open('https://gitee.com/cai_xiao_feng/lowflow-design')
}
const github = () => {
window.open('https://github.com/tsai996/lowflow-design')
}
</script> </script>
<template> <template>
<FlowDesign :process="process" :fields="fields" /> <FlowDesign :process="process" :fields="fields" :readOnly="readOnly">
<el-switch
inline-prompt
active-text="正常模式"
inactive-text="暗黑模式"
@change="handleToggleDark"
v-model="isDark"
/>
<el-switch
v-model="readOnly"
active-text="只读模式"
inactive-text="编辑模式"
inline-prompt
:active-value="true"
:inactive-value="false"
/>
<el-button-group>
<el-button @click="converterBpmn" type="primary" icon="Download"> 转bpmn </el-button>
<!--开源地址-->
<el-dropdown>
<el-button type="primary">
开源地址
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click.stop="gitee">Gitee</el-dropdown-item>
<el-dropdown-item @click.stop="github">Github</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-button-group>
</FlowDesign>
</template> </template>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>