提交 29053438 authored 作者: lihuihui's avatar lihuihui

update

......@@ -87,3 +87,7 @@ textarea:focus {
.info .el-form-item {
margin-bottom: 0;
}
.info tr:last-child td {
padding-bottom: 0 !important;
}
......@@ -17,7 +17,9 @@ const props = defineProps({
const { removeEdges } = useVueFlow()
const path = computed(() => getBezierPath(props))
const path = computed(() => {
return getBezierPath(props)
})
</script>
<script>
......@@ -28,7 +30,22 @@ export default {
<template>
<!-- You can use the `BaseEdge` component to create your own custom edge more easily -->
<BaseEdge :id="id" :style="style" :path="path[0]" :marker-end="markerEnd" />
<!-- :marker-end="markerEnd" -->
<BaseEdge :id="id" :style="style" :path="path[0]" marker-end="url(#triangle)" />
<defs>
<marker
id="triangle"
viewBox="0 0 1 10"
refX="1"
refY="5"
markerUnits="strokeWidth"
markerHeight="8"
markerWidth="8"
orient="auto"
>
<path d="M 0 1.5 L 4 5 L 0 8.5 z" />
</marker>
</defs>
<!-- Use the `EdgeLabelRenderer` to escape the SVG world of edges and render your own custom label in a `<div>` ctx -->
<EdgeLabelRenderer>
......
......@@ -8,18 +8,19 @@ export default {
import { nanoid } from 'nanoid'
import { VueFlow, useVueFlow, PanelPosition } from '@vue-flow/core'
import { Controls } from '@vue-flow/controls'
import Sidebar from './Sidebar.vue'
import CustomNode from './CustomNode.vue'
import CustomEdge from './CustomEdge.vue'
interface Props {
action: string
role: string
templateType?: string
}
const props = withDefaults(defineProps<Props>(), { action: 'edit', role: 'teacher' })
provide('action', props.action)
provide('role', props.role)
provide('templateType', props.templateType)
const { findNode, onConnect, addEdges, addNodes, project, vueFlowRef } = useVueFlow()
......@@ -81,25 +82,10 @@ const onDrop = (event: DragEvent) => {
</script>
<template>
<div class="flow">
<Sidebar></Sidebar>
<slot name="left-panel"> </slot>
<el-card shadow="never" class="flow-main" @drop="onDrop">
<slot name="header">
<el-row align="middle" v-if="action === 'edit'">
<el-button type="primary" size="large">配置连接</el-button>
<el-alert center style="flex: 1; margin-left: 20px">
<p style="text-align: center">
用户旅程的基本组成:触发条件+营销动作+条件分支<br />
您可以从左侧组件区域选择的对应的触发条件、营销动作和条件分支,拖拽到右侧的画布里面,进行编排组合个性化的用户旅程。
</p>
</el-alert>
</el-row>
</slot>
<VueFlow
fit-view-on-init
:zoom-on-scroll="false"
:prevent-scrolling="false"
@dragover="onDragOver"
v-bind="$attrs">
<slot name="header"> </slot>
<VueFlow :zoom-on-scroll="false" :prevent-scrolling="false" @dragover="onDragOver" v-bind="$attrs">
<template #node-custom="node">
<CustomNode :node="node" />
</template>
......@@ -110,6 +96,7 @@ const onDrop = (event: DragEvent) => {
</VueFlow>
<slot name="footer"></slot>
</el-card>
<slot name="right-panel"></slot>
</div>
</template>
......
<script setup lang="ts">
import { useConnection } from '@/composables/useAllData'
import Icon from '@/components/ConnectionIcon.vue'
const props = defineProps<{
connectionIds: string[]
}>()
// 所有连接
const { connectionList } = useConnection()
// 绑定的连接
const connections = computed(() => {
return connectionList.value.filter(item => props.connectionIds.includes(item.id))
})
const list = ref([
{
name: '触发条件',
background: {
icon: 'circle',
color: '#4C5AB3'
},
background: { icon: 'circle', color: '#4C5AB3' },
children: [
{ name: '实时触发', type: '触发条件', icon: '13', componentName: 'TriggeringConditions1' },
{ name: '加入群组', type: '触发条件', icon: '14', componentName: 'TriggeringConditions2' },
{ name: '变更属性', type: '触发条件', icon: '15', componentName: 'TriggeringConditions3' },
{ name: '公众号', type: '触发条件', icon: '1', componentName: 'TriggeringConditions4' },
{ name: '抖音', type: '触发条件', icon: '6', componentName: 'TriggeringConditions5' },
{ name: '小红书', type: '触发条件', icon: '8', componentName: 'TriggeringConditions6' },
{ name: '微博', type: '触发条件', icon: '7', componentName: 'TriggeringConditions7' },
{ name: '自定义', type: '触发条件', icon: '12', componentName: 'TriggeringConditions8' },
{ name: '小鹅通', type: '触发条件', icon: '3', componentName: 'TriggeringConditions9' },
{ name: '问卷星', type: '触发条件', icon: '4', componentName: 'TriggeringConditions10' }
{ name: '公众号', type: '触发条件', icon: '1', componentName: 'TriggeringConditions4', connection_type: 1 },
{ name: '抖音', type: '触发条件', icon: '6', componentName: 'TriggeringConditions5', connection_type: 6 },
{ name: '小红书', type: '触发条件', icon: '8', componentName: 'TriggeringConditions6', connection_type: 8 },
{ name: '微博', type: '触发条件', icon: '7', componentName: 'TriggeringConditions7', connection_type: 7 },
{ name: '自定义', type: '触发条件', icon: '12', componentName: 'TriggeringConditions8', connection_type: 12 },
{ name: '小鹅通', type: '触发条件', icon: '3', componentName: 'TriggeringConditions9', connection_type: 3 },
{ name: '问卷星', type: '触发条件', icon: '4', componentName: 'TriggeringConditions10', connection_type: 4 }
]
},
{
name: '营销动作',
background: {
icon: 'square',
color: '#19AAA5'
},
background: { icon: 'square', color: '#19AAA5' },
children: [
// { name: '终止旅程', type: '营销动作', icon: '16' },
{ name: '加入群组', type: '营销动作', icon: '14', componentName: 'MarketingAction1' },
......@@ -33,32 +41,40 @@ const list = ref([
{ name: '变更属性', type: '营销动作', icon: '15', componentName: 'MarketingAction3' },
{ name: '延时处理', type: '营销动作', icon: '18', componentName: 'MarketingAction4' },
{ name: '内部通知', type: '营销动作', icon: '19', componentName: 'MarketingAction5' },
{ name: '短信', type: '营销动作', icon: '10', componentName: 'MarketingAction6' },
{ name: '邮件', type: '营销动作', icon: '9', componentName: 'MarketingAction7' },
{ name: '公众号', type: '营销动作', icon: '1', componentName: 'MarketingAction8' },
{ name: '抖音', type: '营销动作', icon: '6', componentName: 'MarketingAction9' },
// { name: '小红书', type: '营销动作', icon: '8' },
{ name: '微博', type: '营销动作', icon: '7', componentName: 'MarketingAction10' },
{ name: '钉钉', type: '营销动作', icon: '2', componentName: 'MarketingAction11' }
{ name: '短信', type: '营销动作', icon: '10', componentName: 'MarketingAction6', connection_type: 10 },
{ name: '邮件', type: '营销动作', icon: '9', componentName: 'MarketingAction7', connection_type: 9 },
{ name: '公众号', type: '营销动作', icon: '1', componentName: 'MarketingAction8', connection_type: 1 },
{ name: '抖音', type: '营销动作', icon: '6', componentName: 'MarketingAction9', connection_type: 6 },
// { name: '小红书', type: '营销动作', icon: '8', connection_type: 8 },
{ name: '微博', type: '营销动作', icon: '7', componentName: 'MarketingAction10', connection_type: 7 },
{ name: '钉钉', type: '营销动作', icon: '2', componentName: 'MarketingAction11', connection_type: 2 }
]
},
{
name: '条件分支',
background: {
icon: 'hexagon',
color: '#CEAA62'
},
background: { icon: 'hexagon', color: '#CEAA62' },
children: [
{ name: '属性判断', type: '条件分支', icon: '20', componentName: 'ConditionalBranch6' },
{ name: '标签判断', type: '条件分支', icon: '21', componentName: 'ConditionalBranch1' },
{ name: '群组判断', type: '条件分支', icon: '22', componentName: 'ConditionalBranch2' },
{ name: '事件判断', type: '条件分支', icon: '23', componentName: 'ConditionalBranch3' },
{ name: '时间判断', type: '条件分支', icon: '24', componentName: 'ConditionalBranch4' },
{ name: '公众号', type: '条件分支', icon: '1', componentName: 'ConditionalBranch5' }
{ name: '公众号', type: '条件分支', icon: '1', componentName: 'ConditionalBranch5', connection_type: 1 }
]
}
])
const currentList = computed(() => {
return list.value.map(item => {
return {
...item,
children: item.children.filter(item =>
item.connection_type ? connections.value.find(connection => connection.type === item.connection_type) : true
)
}
})
})
const onDragStart = (event: DragEvent, data: any) => {
if (event.dataTransfer) {
event.dataTransfer.setData('application/vueflow', JSON.stringify(data))
......@@ -69,7 +85,7 @@ const onDragStart = (event: DragEvent, data: any) => {
<template>
<el-card shadow="never" class="flow-sidebar">
<dl v-for="(parent, index) in list" :key="index">
<dl v-for="(parent, index) in currentList" :key="index">
<dt :style="`background: ${parent.background?.color}`">{{ parent.name }}</dt>
<dd>
<ul>
......
......@@ -2,6 +2,7 @@
import type { NodeProps } from '@vue-flow/core'
import { useVueFlow, Handle, Position } from '@vue-flow/core'
import { Setting, Delete } from '@element-plus/icons-vue'
import IconFlowLine from '@/components/icon/IconFlowLine.vue'
const props = defineProps<{ node: NodeProps }>()
......@@ -14,36 +15,88 @@ function onRemove() {
const node = findNode(props.node.id)
if (node) removeNodes([node])
}
let toolbarShow = ref(false)
window.addEventListener('click', function () {
toolbarShow.value = false
})
const handleToolbar = function () {
setTimeout(() => {
toolbarShow.value = true
}, 100)
}
</script>
<template>
<div class="custom-node">
<div class="node-toolbar">
<div class="custom-node" @click="handleToolbar">
<div class="node-toolbar" v-if="toolbarShow">
<el-icon size="12" @click="onRemove"><Delete /></el-icon>
<el-icon size="12" @click="emit('setting')"><Setting /></el-icon>
</div>
<div class="custom-node__inner">
<slot :node="node" />
</div>
<IconFlowLine class="tool-line" v-if="toolbarShow"></IconFlowLine>
</div>
<Handle id="right" class="handle" :position="Position.Right" />
<Handle id="left" class="handle" :position="Position.Left" />
<Handle id="bottom" class="handle" :position="Position.Bottom" />
<Handle id="right" class="handle handle-right" :position="Position.Right"></Handle>
<Handle style="opacity: 0; width: 10px; height: 10px" id="left" class="handle" :position="Position.Left" />
<!-- <Handle id="bottom" class="handle" :position="Position.Bottom" /> -->
</template>
<style lang="scss" scoped>
.custom-node {
&:hover {
.node-toolbar {
display: flex;
.dispatchers {
position: absolute;
width: 100px;
height: 100px;
right: -110px;
top: 20px;
z-index: -2;
div {
width: 50px;
line-height: 18px;
height: 18px;
border-radius: 3px;
font-size: 6px;
text-align: center;
color: #fff;
}
.item1 {
background: #6dbd7a;
}
.item2 {
margin: 3px 0;
background: #fe615e;
}
.item3 {
background: #6a6c8a;
}
}
.handle-right{
width: 10px;
border-radius: 0;
right: -5px;
opacity: 0;
}
.tool-line {
position: absolute;
top: 35%;
right: -12px;
}
.vue-flow__handle {
}
.custom-node {
position: relative;
// &:hover {
// .node-toolbar {
// display: flex;
// }
// }
}
.node-toolbar {
position: absolute;
left: 50%;
top: -22px;
display: none;
top: -25px;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
......
......@@ -10,6 +10,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -40,6 +48,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -87,13 +96,18 @@ const removeTag = function (index) {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="hexagon" :color="form.isEdit === true ? '#CEAA62' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="hexagon" color="#CEAA62" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="21" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -34,6 +42,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -60,13 +69,18 @@ onMounted(() => {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="hexagon" :color="form.isEdit === true ? '#CEAA62' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="hexagon" color="#CEAA62" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="22" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -33,6 +41,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -59,13 +68,18 @@ onMounted(() => {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="hexagon" :color="form.isEdit === true ? '#CEAA62' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="hexagon" color="#CEAA62" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="23" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -8,6 +8,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -35,6 +43,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -53,13 +62,18 @@ function handleClosed() {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="hexagon" :color="form.isEdit === true ? '#CEAA62' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="hexagon" color="#CEAA62" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="24" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -12,8 +12,15 @@ const store = useMapStore()
const props = defineProps({ node: Object })
const action = inject('action')
// const role = inject('role')
const role = 'student'
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -33,6 +40,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -75,13 +83,18 @@ const changeMaterialType = function () {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="hexagon" :color="form.isEdit === true ? '#CEAA62' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="hexagon" color="#CEAA62" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="1" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -11,6 +11,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
// 获取逻辑运算符名称
function getLogicalName(value) {
......@@ -87,6 +95,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -113,13 +122,18 @@ onMounted(() => {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="hexagon" :color="form.isEdit === true ? '#CEAA62' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="hexagon" color="#CEAA62" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="20" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -58,13 +67,18 @@ onMounted(() => {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="14" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -13,6 +13,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -32,6 +40,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -78,13 +87,18 @@ const changeMaterialType = function () {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="7" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -13,6 +13,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -32,6 +40,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -74,13 +83,18 @@ const changeMaterialType = function () {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="2" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -58,13 +67,18 @@ onMounted(() => {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="17" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -10,6 +10,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -29,6 +37,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -69,13 +78,18 @@ const handleRemove = function (index) {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="15" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -8,6 +8,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -27,6 +35,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -45,13 +54,18 @@ function handleClosed() {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="18" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -8,6 +8,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -27,6 +35,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -45,13 +54,18 @@ function handleClosed() {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="19" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -3,12 +3,19 @@
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getAttrList } from '@/api/flow'
const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +35,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -52,13 +60,18 @@ let stepActive = ref(0)
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="10" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -13,6 +13,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -32,6 +40,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -74,13 +83,18 @@ const changeMaterialType = function () {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="9" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -13,6 +13,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -32,6 +40,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -74,13 +83,18 @@ const changeMaterialType = function () {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="square" :color="form.isEdit === true ? '#19AAA5' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="1" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -13,6 +13,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -32,6 +40,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......
......@@ -8,6 +8,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -35,6 +43,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -53,13 +62,18 @@ function handleClosed() {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="13" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -60,13 +69,18 @@ let stepActive = ref(0)
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="4" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -58,13 +67,18 @@ onMounted(() => {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="14" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
......@@ -87,13 +96,18 @@ onMounted(() => {
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="15" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -71,13 +80,18 @@ let stepActive = ref(0)
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="1" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -65,13 +74,18 @@ let stepActive = ref(0)
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="6" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -67,13 +76,18 @@ let stepActive = ref(0)
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="8" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -63,13 +72,18 @@ let stepActive = ref(0)
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="7" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -69,13 +78,18 @@ let stepActive = ref(0)
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="12" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
......@@ -9,6 +9,14 @@ const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
......@@ -28,6 +36,7 @@ const rules = ref({
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
......@@ -60,13 +69,18 @@ let stepActive = ref(0)
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<template v-if="templateType === '2' && role === 'student'">
<Icon name="circle" :color="form.isEdit === true ? '#4C5AB3' : 'rgb(154, 154, 154)'" w="60" h="60"></Icon>
</template>
<template v-else>
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
</template>
<Icon class="icon" name="3" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" @close="handleClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-form :disabled="action === 'view'" ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
......
<template>
<svg
version="1.1"
id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
width="13px"
height="13px"
viewBox="0 0 18.75 18.75"
enable-background="new 0 0 18.75 18.75"
xml:space="preserve"
>
<path
fill="#6A6C8A"
d="M9.884,9.838c0.54-0.551,1.005-0.955,1.384-1.201c0.463-0.308,0.749-0.352,0.887-0.352h1.34v1.367 c0,0.104,0.061,0.2,0.154,0.242s0.204,0.027,0.284-0.038l3.168-2.669c0.06-0.051,0.096-0.125,0.096-0.203S17.16,6.83,17.101,6.781 l-3.168-2.677c-0.08-0.067-0.19-0.081-0.284-0.038c-0.094,0.045-0.154,0.139-0.154,0.242v1.414h-1.343 c-1.24,0.014-2.215,0.67-2.927,1.242c-0.797,0.65-1.533,1.447-2.245,2.217c-0.361,0.391-0.7,0.759-1.044,1.1 c-0.541,0.549-1.011,0.951-1.395,1.199c-0.354,0.231-0.678,0.357-0.921,0.357h-1.8c-0.146,0-0.266,0.12-0.266,0.265v2.029 c0,0.148,0.12,0.268,0.266,0.268h1.8l0,0c1.255-0.014,2.239-0.667,2.958-1.24c0.82-0.661,1.572-1.475,2.297-2.256 C9.225,10.524,9.555,10.169,9.884,9.838z"
/>
</svg>
</template>
......@@ -28,7 +28,7 @@ export interface TagType {
export interface ConnectionType {
id: string
name: string
type: string
type: number
status: '0' | '1'
config_attributes: any
}
......
import httpRequest from '@/utils/axios'
// 获取实验详情
export function getExperiment() {
return httpRequest.get('/api/lab/v1/student/experiment/detail')
}
// 学生获取旅程
export function getStudentTrip() {
return httpRequest.get('/api/lab/v1/experiment/itinerary/student-get-itinerary')
}
// 更新旅程
export function updateTrip(data: { itinerary_id: string; graph: string; status: number }) {
return httpRequest.post('/api/lab/v1/experiment/itinerary/student-save-itinerary', data)
}
// 旅程绑定连接
export function bindTripConnections(data: { itinerary_id: string; connections_id: string }) {
return httpRequest.post('/api/lab/v1/experiment/itinerary/student-bind-connections', data)
}
// 获取旅程模板demo
export function getTripTemplateDemo(params: { itinerary_id?: string }) {
return httpRequest.get('/api/lab/v1/experiment/itinerary/get-itinerary-demo', { params })
}
<script setup lang="ts">
import type { Trip } from '../types'
import { ElMessage } from 'element-plus'
import { bindTripConnections } from '../api'
import type { ConnectionType } from '@/composables/useAllData'
import { useConnection } from '@/composables/useAllData'
import ConnectionIcon from '@/components/ConnectionIcon.vue'
const props = defineProps<{
data: Trip
}>()
const emit = defineEmits<{
(e: 'update', value: string[]): void
(e: 'update:modelValue', visible: boolean): void
}>()
const { connectionList } = useConnection()
const multipleSelection = ref<string[]>([])
function toggleSelection(data: ConnectionType) {
multipleSelection.value.includes(data.id)
? multipleSelection.value.filter(id => id !== data.id)
: multipleSelection.value.push(data.id)
}
function isActive(data: ConnectionType) {
return multipleSelection.value.includes(data.id)
}
// 保存
function handleSave() {
bindTripConnections({ itinerary_id: props.data.id, connections_id: multipleSelection.value.join(',') }).then(() => {
ElMessage({ message: '保存成功', type: 'success' })
emit('update', multipleSelection.value)
emit('update:modelValue', false)
})
}
</script>
<template>
<el-dialog title="配置连接" width="800px" append-to-body @update:modelValue="$emit('update:modelValue')">
<div class="connection-list">
<div
class="connection-item"
v-for="item in connectionList"
:key="item.id"
:class="{ 'is-active': isActive(item) }"
@click="toggleSelection(item)">
<el-checkbox @change="toggleSelection(item)" :model-value="isActive(item)" />
<div class="connection-item__icon"><ConnectionIcon :name="item.type + ''" /></div>
<p>{{ item.name }}</p>
</div>
</div>
<template #footer>
<el-row justify="center">
<el-button plain auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button type="primary" plain auto-insert-space @click="handleSave">保存</el-button>
</el-row>
</template>
</el-dialog>
</template>
<style lang="scss">
.connection-list {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.connection-item {
position: relative;
height: 100px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #fff;
border: 1px dashed #bbb;
cursor: pointer;
&.is-active {
background-color: rgb(204 247 131 / 38%);
}
.el-checkbox {
position: absolute;
left: 10px;
top: 0;
}
}
</style>
export interface Trip {
id: string
experiment_id: string
itinerary_id: string
student_id: string
connect_ids: string[]
graph: string
score: string
status: string
commit_time: string
comment_sso_id: string
comment_time: string
comment_status: string
comment: string
created_time: string
updated_time: string
status_name: string
comment_status_name: string
course_id: string
course_name: string
experiment_name: string
experiment_itinerary_type: string
experiment_itinerary_type_name: string
}
<script setup lang="ts">
import type { Trip } from '../types'
import TripFlow from '@/components/flow/Index.vue'
import { getExperiment, getStudentTrip } from '../api'
import TripFlowSidebar from '@/components/flow/Sidebar.vue'
import { ElMessage } from 'element-plus'
import { getStudentTrip, getTripTemplateDemo, updateTrip } from '../api'
const experiment = ref<any>()
function fetchExperiment() {
getExperiment().then(res => {
experiment.value = res.data.detail
})
}
onMounted(() => fetchExperiment())
const BindConnection = defineAsyncComponent(() => import('../components/BindConnection.vue'))
const detail = ref<Trip>()
const elements = ref([])
const connectionIds = computed(() => {
return detail.value?.connect_ids || []
})
// 是否是自由旅程
const isFree = computed(() => {
return detail.value?.experiment_itinerary_type === '1'
})
// 获取旅程信息
const detail = ref<any>()
function fetchInfo() {
getStudentTrip().then(res => {
detail.value = res.data.detail
})
async function fetchInfo() {
const res = await getStudentTrip()
detail.value = res.data
try {
elements.value = res.data.graph ? JSON.parse(res.data.graph) : []
} catch (error) {
console.log(error)
}
}
onMounted(() => fetchInfo())
onMounted(async () => {
await fetchInfo()
fetchDemo()
})
const elements = ref([
{
id: '1',
type: 'custom',
label: '实时触发',
position: { x: 0, y: 0 },
data: { name: '实时触发', type: '触发条件', score: 10, componentName: 'TriggeringConditions6' }
// 获取模板配置数据
async function fetchDemo() {
if (!detail.value) return
if (isFree.value || detail.value.graph) return
const res = await getTripTemplateDemo({ itinerary_id: detail.value.itinerary_id })
try {
elements.value = res.data.graph ? JSON.parse(res.data.graph) : []
} catch (error) {
console.log(error)
}
])
watchEffect(() => {
console.log(elements)
})
}
// 保存
function handleSubmit() {}
function handleSubmit() {
if (!detail.value) return
const params = { itinerary_id: detail.value.itinerary_id, graph: JSON.stringify(elements.value), status: 1 }
updateTrip(params).then(() => {
ElMessage.success('保存成功')
})
}
// 配置
let configVisible = $ref(false)
function handleConfig() {
configVisible = true
}
function handleConnectionUpdate(value: string[]) {
if (!detail.value) return
detail.value.connect_ids = value
}
</script>
<template>
<AppCard title="自由旅程">
<el-card shadow="never" style="margin-bottom: 20px" v-if="experiment">
<el-descriptions label-suffix=":">
<el-descriptions-item label="课程名称:">{{ experiment.course.name }}</el-descriptions-item>
<el-descriptions-item label="实验名称:">{{ experiment.name }}</el-descriptions-item>
<el-descriptions-item label="旅程类型:">自由旅程</el-descriptions-item>
<AppCard :title="detail?.experiment_itinerary_type_name">
<el-card shadow="never" style="margin-bottom: 20px" v-if="detail">
<el-descriptions class="info">
<el-descriptions-item label="课程名称:">{{ detail.course_name }}</el-descriptions-item>
<el-descriptions-item label="实验名称:">{{ detail.experiment_name }}</el-descriptions-item>
<el-descriptions-item label="旅程类型:">{{ detail.experiment_itinerary_type_name }}</el-descriptions-item>
</el-descriptions>
</el-card>
<TripFlow v-model="elements" action="edit" role="student" style="height: 80vh">
<TripFlow v-model="elements" action="edit" role="student">
<template #left-panel v-if="isFree">
<TripFlowSidebar :connectionIds="connectionIds" />
</template>
<template #header>
<el-row align="middle">
<el-button type="primary" size="large" @click="handleConfig" style="margin-right: 20px" v-if="isFree"
>配置连接</el-button
>
<el-alert center style="flex: 1">
<p style="text-align: center">
<template v-if="isFree">
用户旅程的基本组成:触发条件+营销动作+条件分支<br />
您可以从左侧组件区域选择的对应的触发条件、营销动作和条件分支,拖拽到右侧的画布里面,进行编排组合个性化的用户旅程。
</template>
<template v-else>请给本用户旅程的每一个节点进行详细配置,确保每一个节点能够顺利执行。</template>
</p>
</el-alert>
</el-row>
</template>
<template #footer>
<el-row justify="center">
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
......@@ -53,4 +99,12 @@ function handleSubmit() {}
</template>
</TripFlow>
</AppCard>
<!-- 配置连接 -->
<BindConnection
v-model="configVisible"
:data="detail"
@update="handleConnectionUpdate"
v-if="configVisible && detail"
></BindConnection>
</template>
......@@ -11,7 +11,7 @@ const props = defineProps<{
}>()
const emit = defineEmits<{
(e: 'update'): void
(e: 'update', value: ConnectionType[]): void
(e: 'update:modelValue', visible: boolean): void
}>()
......@@ -40,7 +40,7 @@ function handleSave() {
const ids = multipleSelection.value.map(item => item.id)
bindTripConnections({ itinerary_id: props.data.id, connection_ids: ids }).then(() => {
ElMessage({ message: '保存成功', type: 'success' })
emit('update')
emit('update', multipleSelection.value)
emit('update:modelValue', false)
})
}
......@@ -54,8 +54,7 @@ function handleSave() {
v-for="item in connectionList"
:key="item.id"
:class="{ 'is-active': isActive(item) }"
@click="toggleSelection(item)"
>
@click="toggleSelection(item)">
<el-checkbox @change="toggleSelection(item)" :model-value="isActive(item)" />
<div class="connection-item__icon"><ConnectionIcon :name="item.type + ''" /></div>
<p>{{ item.name }}</p>
......
<!-- 固定旅程模板配置 -->
<script setup lang="ts">
import type { TripTemplate } from '../types'
import type { ConnectionType } from '@/composables/useAllData'
import { ElMessage } from 'element-plus'
import TripFlow from '@/components/flow/Index.vue'
import { getTripTemplate, getTripTemplateDemo, updateTripTemplateDemo } from '../api'
import TripFlowSidebar from '@/components/flow/Sidebar.vue'
import { getTripTemplate, getTripConnections, getTripTemplateDemo, updateTripTemplateDemo } from '../api'
import { useMapStore } from '@/stores/map'
import { getNameByValue, tripTemplateTypeList } from '@/utils/dictionary'
const BindConnection = defineAsyncComponent(() => import('../components/BindConnection.vue'))
const props = defineProps<{ id: string }>()
......@@ -19,6 +23,17 @@ function fetchInfo() {
onMounted(() => fetchInfo())
const connections = ref<ConnectionType[]>([])
const connectionIds = computed(() => {
return connections.value.map(item => item.id)
})
function fetchConnections() {
getTripConnections({ itinerary_id: props.id }).then(res => {
connections.value = res.data.items
})
}
onMounted(() => fetchConnections())
const elements = ref([])
// 获取模板配置数据
function fetchDemo() {
......@@ -39,10 +54,16 @@ function handleSubmit() {
ElMessage.success('保存成功')
})
}
// 配置
let configVisible = $ref(false)
function handleConfig() {
configVisible = true
}
</script>
<template>
<AppCard title="固定旅程模版配置">
<el-card shadow="never" style="margin-bottom: 20px" v-if="detail">
<AppCard title="固定旅程模版配置" v-if="detail">
<el-card shadow="never" style="margin-bottom: 20px">
<el-form label-suffix=":" class="info">
<el-row justify="space-between">
<el-col :span="8">
......@@ -72,13 +93,35 @@ function handleSubmit() {
</el-row>
</el-form>
</el-card>
<TripFlow v-model="elements" action="edit" role="teacher">
<TripFlow v-model="elements" action="edit" role="student" :templateType="detail?.type">
<template #left-panel>
<TripFlowSidebar :connectionIds="connectionIds" />
</template>
<template #header>
<el-row align="middle">
<el-button type="primary" size="large" @click="handleConfig">配置连接</el-button>
<el-alert center style="flex: 1; margin-left: 20px">
<p style="text-align: center">
用户旅程的基本组成:触发条件+营销动作+条件分支<br />
您可以从左侧组件区域选择的对应的触发条件、营销动作和条件分支,拖拽到右侧的画布里面,进行编排组合个性化的用户旅程。
</p>
</el-alert>
</el-row>
</template>
<template #footer>
<el-row justify="center">
<el-button plain auto-insert-space>取消</el-button>
<el-button plain auto-insert-space @click="$router.push('/trip/template')">取消</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
</el-row>
</template>
</TripFlow>
</AppCard>
<!-- 配置连接 -->
<BindConnection
v-model="configVisible"
:data="detail"
v-if="configVisible && detail"
@update="fetchConnections"
></BindConnection>
</template>
......@@ -26,7 +26,7 @@ export default defineConfig(({ mode }) => ({
cert: fs.readFileSync(path.join(__dirname, './https/ezijing.com.pem'))
},
proxy: {
'/api': 'https://saas-lab.ezijing.com'
'/api': 'https://saas-dml.ezijing.com'
}
},
resolve: {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论