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

update

This source diff could not be displayed because it is too large. You can view the blob instead.
<script setup lang="ts"> <script setup lang="ts">
import TriggeringConditions1 from './components/triggeringConditions/TriggeringConditions1.vue' import TriggeringConditions1 from './components/triggeringConditions/TriggeringConditions1.vue'
import TriggeringConditions2 from './components/triggeringConditions/TriggeringConditions2.vue'
</script> </script>
<template> <template>
<component :is="TriggeringConditions1"></component> <component :is="TriggeringConditions2"></component>
</template> </template>
...@@ -11,6 +11,15 @@ import Sidebar from './Sidebar.vue' ...@@ -11,6 +11,15 @@ import Sidebar from './Sidebar.vue'
import CustomNode from './CustomNode.vue' import CustomNode from './CustomNode.vue'
import CustomEdge from './CustomEdge.vue' import CustomEdge from './CustomEdge.vue'
interface Props {
action: string
role: string
}
const props = withDefaults(defineProps<Props>(), { action: 'edit', role: 'teacher' })
provide('action', props.action)
provide('role', props.role)
let id = 0 let id = 0
const getId = () => `node_${id++}` const getId = () => `node_${id++}`
......
<script setup lang="ts"> <script setup lang="ts">
import Icon from '@/components/ConnectionIcon.vue'
const list = ref([ const list = ref([
{ {
name: '触发条件', name: '触发条件',
background: {
icon: 'circle',
color: '#4C5AB3'
},
children: [ children: [
{ name: '实时触发', type: '触发条件', icon: '' }, { name: '实时触发', type: '触发条件', icon: '13' },
{ name: '加入群组', type: '触发条件', icon: '' }, { name: '加入群组', type: '触发条件', icon: '14' },
{ name: '变更属性', type: '触发条件', icon: '' }, { name: '变更属性', type: '触发条件', icon: '15' },
{ name: '公众号', type: '触发条件', icon: '' }, { name: '公众号', type: '触发条件', icon: '1' },
{ name: '抖音', type: '触发条件', icon: '' }, { name: '抖音', type: '触发条件', icon: '6' },
{ name: '小红书', type: '触发条件', icon: '' }, { name: '小红书', type: '触发条件', icon: '8' },
{ name: '微博', type: '触发条件', icon: '' }, { name: '微博', type: '触发条件', icon: '7' },
{ name: '钉钉', type: '触发条件', icon: '' } { name: '钉钉', type: '触发条件', icon: '2' }
] ]
}, },
{ {
name: '营销动作', name: '营销动作',
background: {
icon: 'square',
color: '#19AAA5'
},
children: [ children: [
{ name: '终止旅程', type: '营销动作', icon: '' }, { name: '终止旅程', type: '营销动作', icon: '16' },
{ name: '加入群组', type: '营销动作', icon: '' }, { name: '加入群组', type: '营销动作', icon: '14' },
{ name: '移除群组', type: '营销动作', icon: '' }, { name: '移除群组', type: '营销动作', icon: '17' },
{ name: '变更属性', type: '营销动作', icon: '' }, { name: '变更属性', type: '营销动作', icon: '15' },
{ name: '延时处理', type: '营销动作', icon: '' }, { name: '延时处理', type: '营销动作', icon: '18' },
{ name: '内部通知', type: '营销动作', icon: '' }, { name: '内部通知', type: '营销动作', icon: '19' },
{ name: '短信', type: '营销动作', icon: '' }, { name: '短信', type: '营销动作', icon: '10' },
{ name: '邮件', type: '营销动作', icon: '' }, { name: '邮件', type: '营销动作', icon: '9' },
{ name: '公众号', type: '营销动作', icon: '' }, { name: '公众号', type: '营销动作', icon: '1' },
{ name: '抖音', type: '营销动作', icon: '' }, { name: '抖音', type: '营销动作', icon: '6' },
{ name: '小红书', type: '营销动作', icon: '' }, { name: '小红书', type: '营销动作', icon: '8' },
{ name: '微博', type: '营销动作', icon: '' }, { name: '微博', type: '营销动作', icon: '7' },
{ name: '钉钉', type: '营销动作', icon: '' } { name: '钉钉', type: '营销动作', icon: '2' }
] ]
}, },
{ {
name: '条件分支', name: '条件分支',
background: {
icon: 'hexagon',
color: '#CEAA62'
},
children: [ children: [
{ name: '属性判断', type: '条件分支', icon: '' }, { name: '属性判断', type: '条件分支', icon: '20' },
{ name: '标签判断', type: '条件分支', icon: '' }, { name: '标签判断', type: '条件分支', icon: '21' },
{ name: '群组判断', type: '条件分支', icon: '' }, { name: '群组判断', type: '条件分支', icon: '22' },
{ name: '事件判断', type: '条件分支', icon: '' }, { name: '事件判断', type: '条件分支', icon: '23' },
{ name: '时间判断', type: '条件分支', icon: '' }, { name: '时间判断', type: '条件分支', icon: '24' },
{ name: '公众号', type: '条件分支', icon: '' }, { name: '公众号', type: '条件分支', icon: '1' },
{ name: '钉钉', type: '条件分支', icon: '' } { name: '钉钉', type: '条件分支', icon: '2' }
] ]
} }
]) ])
...@@ -56,15 +69,25 @@ const onDragStart = (event: DragEvent, data: any) => { ...@@ -56,15 +69,25 @@ const onDragStart = (event: DragEvent, data: any) => {
<template> <template>
<el-card shadow="never" class="flow-sidebar"> <el-card shadow="never" class="flow-sidebar">
<dl v-for="(parent, index) in list" :key="index"> <dl v-for="(parent, index) in list" :key="index">
<dt>{{ parent.name }}</dt> <dt :style="`background: ${parent.background?.color}`">{{ parent.name }}</dt>
<dd> <dd>
<ul> <ul>
<li <li
v-for="(item, index) in parent.children" v-for="(item, index) in parent.children"
:key="index" :key="index"
:draggable="true" :draggable="true"
@dragstart="event => onDragStart(event, item)"> @dragstart="event => onDragStart(event, item)"
<img src="" alt="" /> >
<div class="icon-box">
<Icon class="icon" color="#fff" :name="item.icon" w="24" h="24"></Icon>
<Icon
class="circle"
:color="parent.background?.color"
:name="parent.background?.icon || ''"
w="60"
h="60"
></Icon>
</div>
<p>{{ item.name }}</p> <p>{{ item.name }}</p>
</li> </li>
</ul> </ul>
...@@ -74,13 +97,23 @@ const onDragStart = (event: DragEvent, data: any) => { ...@@ -74,13 +97,23 @@ const onDragStart = (event: DragEvent, data: any) => {
</template> </template>
<style lang="scss"> <style lang="scss">
.icon-box {
position: relative;
.icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
.flow-sidebar { .flow-sidebar {
width: 300px; width: 300px;
dt { dt {
color: #fff; color: #fff;
line-height: 40px; line-height: 30px;
text-align: center; text-align: center;
background-color: rgb(86, 119, 34); background-color: rgb(86, 119, 34);
font-size: 14px;
} }
dd { dd {
padding: 20px 0; padding: 20px 0;
......
...@@ -19,8 +19,8 @@ function onRemove() { ...@@ -19,8 +19,8 @@ function onRemove() {
<template> <template>
<div class="custom-node"> <div class="custom-node">
<div class="node-toolbar"> <div class="node-toolbar">
<el-icon @click="onRemove"><Delete /></el-icon> <el-icon size="12" @click="onRemove"><Delete /></el-icon>
<el-icon @click="emit('setting')"><Setting /></el-icon> <el-icon size="12" @click="emit('setting')"><Setting /></el-icon>
</div> </div>
<div class="custom-node__inner"> <div class="custom-node__inner">
<slot :node="node" /> <slot :node="node" />
...@@ -33,14 +33,6 @@ function onRemove() { ...@@ -33,14 +33,6 @@ function onRemove() {
<style lang="scss" scoped> <style lang="scss" scoped>
.custom-node { .custom-node {
// position: relative;
// width: 80px;
// height: 80px;
// border: 1px solid #000;
// display: flex;
// justify-content: center;
// align-items: center;
// border-radius: 50%;
&:hover { &:hover {
.node-toolbar { .node-toolbar {
display: flex; display: flex;
...@@ -50,14 +42,16 @@ function onRemove() { ...@@ -50,14 +42,16 @@ function onRemove() {
.node-toolbar { .node-toolbar {
position: absolute; position: absolute;
left: 50%; left: 50%;
top: -30px; top: -22px;
display: none; display: none;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 20px; font-size: 20px;
transform: translate(-50%); transform: translate(-50%);
box-shadow: 2px 2px 10px 0px rgba(0, 0, 0, 0.3);
border-radius: 20px;
.el-icon { .el-icon {
margin: 10px; margin: 5px 8px;
cursor: pointer; cursor: pointer;
} }
} }
......
<!-- 定时触发 --> <!-- 定时触发 -->
<script setup> <script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue' import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const props = defineProps({ node: Object }) const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const { findNode } = useVueFlow()
// 设置 // 设置
const settingVisible = ref(false) const settingVisible = ref(false)
const formRef = ref() const formRef = ref()
const form = reactive({ id: '', name: '', type: '' }) const form = reactive({ id: '', name: '', type: '', trigger_type: '单次触发', trigger_time: '', answer_analysis: '' })
watchEffect(() => {
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data) if (props.node) Object.assign(form, props.node.data)
}) })
const rules = ref({}) const rules = ref({})
// 保存 // 保存
function handleSubmit() {} function handleSubmit() {
formRef.value.validate().then(() => {
updateNode()
settingVisible.value = false
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
</script> </script>
<template> <template>
<NodeTemplate :node="node" @setting="settingVisible = true"> <NodeTemplate :node="node" @setting="settingVisible = true">
{{ node.label }} <div class="node-item">
<div class="item"></div> <Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
<Icon class="icon" name="13" :multicolour="true" w="24" h="24"></Icon>
</div>
</NodeTemplate> </NodeTemplate>
<el-dialog title="设置组件" append-to-body width="600px" v-model="settingVisible" v-if="settingVisible"> <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 ref="formRef" :model="form" :rules="rules" label-suffix=":">
<el-row justify="space-between"> <!-- 学生设置组件 -->
<el-form-item label="组件类型"> {{ form.type }} </el-form-item> <template v-if="role === 'student'">
<el-form-item label="组件名称"> <el-row justify="space-between">
{{ form.name }} <el-form-item label="组件类型">{{ form.type }}</el-form-item>
<el-form-item label="组件名称">{{ form.name }}</el-form-item>
<el-form-item label="分值">{{ form.score }} </el-form-item>
</el-row>
<el-form-item label="触发类型" prop="trigger_type">
<el-radio-group v-model="form.trigger_type">
<el-radio label="单次触发" />
<el-radio label="重复触发" />
<el-radio label="立即触发" />
</el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="分值">{{ form.score }} </el-form-item> <el-form-item label="触发时间" prop="trigger_time">
</el-row> <el-date-picker v-model="form.trigger_time" type="date" />
<slot name="form" :form="form"></slot> </el-form-item>
</template>
<!-- 老师设置组件 -->
<template v-if="role === 'teacher'">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="组件类型">{{ form.type }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="组件名称">{{ form.name }}</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="组件分值" prop="score">
<el-input v-model="form.score" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="已设置组件分值">110</el-form-item>
</el-col>
</el-row>
<el-card header="标准答案" shadow="never">
<el-form-item label="触发类型" prop="trigger_type">
<el-radio-group v-model="form.trigger_type">
<el-radio label="单次触发" />
<el-radio label="重复触发" />
<el-radio label="立即触发" />
</el-radio-group>
</el-form-item>
<el-form-item label="触发时间" prop="trigger_time">
<el-date-picker v-model="form.trigger_time" type="date" />
</el-form-item>
</el-card>
<el-card header="答案解析" shadow="never" style="margin-top: 20px">
<el-form-item prop="answer_analysis">
<el-input v-model="form.answer_analysis" :rows="3" type="textarea" placeholder="请输入答案解析"></el-input>
</el-form-item>
</el-card>
</template>
</el-form> </el-form>
<template #footer> <template #footer>
<el-row justify="center"> <el-row justify="center">
...@@ -44,3 +115,14 @@ function handleSubmit() {} ...@@ -44,3 +115,14 @@ function handleSubmit() {}
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<style scoped lang="scss">
.node-item {
position: relative;
.icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
</style>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const props = defineProps({ node: Object })
const action = inject('action')
const role = inject('role')
const { findNode } = useVueFlow()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ id: '', name: '', type: '', trigger_type: '单次触发', trigger_time: '', answer_analysis: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
updateNode()
settingVisible.value = false
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="circle" color="#4C5AB3" w="60" h="60"></Icon>
<Icon class="icon" name="14" :multicolour="true" 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=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
<el-form-item label="组件类型">{{ form.type }}</el-form-item>
<el-form-item label="组件名称">{{ form.name }}</el-form-item>
<el-form-item label="分值">{{ form.score }} </el-form-item>
</el-row>
<el-form-item label="触发类型" prop="trigger_type">
<el-radio-group v-model="form.trigger_type">
<el-radio label="单次触发" />
<el-radio label="重复触发" />
<el-radio label="立即触发" />
</el-radio-group>
</el-form-item>
<el-form-item label="触发时间" prop="trigger_time">
<el-date-picker v-model="form.trigger_time" type="date" />
</el-form-item>
</template>
<!-- 老师设置组件 -->
<template v-if="role === 'teacher'">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="组件类型">{{ form.type }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="组件名称">{{ form.name }}</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="组件分值" prop="score">
<el-input v-model="form.score" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="已设置组件分值">110</el-form-item>
</el-col>
</el-row>
<el-card header="标准答案" shadow="never">
<el-form-item label="触发类型" prop="trigger_type">
<el-radio-group v-model="form.trigger_type">
<el-radio label="单次触发" />
<el-radio label="重复触发" />
<el-radio label="立即触发" />
</el-radio-group>
</el-form-item>
<el-form-item label="触发时间" prop="trigger_time">
<el-date-picker v-model="form.trigger_time" type="date" />
</el-form-item>
</el-card>
<el-card header="答案解析" shadow="never" style="margin-top: 20px">
<el-form-item prop="answer_analysis">
<el-input v-model="form.answer_analysis" :rows="3" type="textarea" placeholder="请输入答案解析"></el-input>
</el-form-item>
</el-card>
</template>
</el-form>
<template #footer>
<el-row justify="center">
<el-button plain auto-insert-space @click="settingVisible = false">关闭</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
</el-row>
</template>
</el-dialog>
</template>
<style scoped lang="scss">
.node-item {
position: relative;
.icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
</style>
...@@ -28,7 +28,7 @@ function handleSubmit() {} ...@@ -28,7 +28,7 @@ function handleSubmit() {}
<template> <template>
<AppCard title="自由旅程"> <AppCard title="自由旅程">
<el-card shadow="never" style="margin-bottom: 20px"></el-card> <el-card shadow="never" style="margin-bottom: 20px"></el-card>
<TripFlow v-model="elements" style="height: 80vh"> <TripFlow v-model="elements" action="edit" role="student" style="height: 80vh">
<template #footer> <template #footer>
<el-row justify="center"> <el-row justify="center">
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button> <el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论