提交 9e7cbfb7 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 e22781b2
...@@ -8,7 +8,6 @@ export default { ...@@ -8,7 +8,6 @@ export default {
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import { VueFlow, useVueFlow, PanelPosition } from '@vue-flow/core' import { VueFlow, useVueFlow, PanelPosition } from '@vue-flow/core'
import { Controls } from '@vue-flow/controls' import { Controls } from '@vue-flow/controls'
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'
...@@ -81,19 +80,9 @@ const onDrop = (event: DragEvent) => { ...@@ -81,19 +80,9 @@ const onDrop = (event: DragEvent) => {
</script> </script>
<template> <template>
<div class="flow"> <div class="flow">
<Sidebar></Sidebar> <slot name="left-panel"> </slot>
<el-card shadow="never" class="flow-main" @drop="onDrop"> <el-card shadow="never" class="flow-main" @drop="onDrop">
<slot name="header"> <slot name="header"> </slot>
<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 <VueFlow
fit-view-on-init fit-view-on-init
:zoom-on-scroll="false" :zoom-on-scroll="false"
...@@ -110,6 +99,7 @@ const onDrop = (event: DragEvent) => { ...@@ -110,6 +99,7 @@ const onDrop = (event: DragEvent) => {
</VueFlow> </VueFlow>
<slot name="footer"></slot> <slot name="footer"></slot>
</el-card> </el-card>
<slot name="right-panel"></slot>
</div> </div>
</template> </template>
......
<script setup lang="ts"> <script setup lang="ts">
import { useConnection } from '@/composables/useAllData'
import Icon from '@/components/ConnectionIcon.vue' 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([ const list = ref([
{ {
name: '触发条件', name: '触发条件',
background: { background: { icon: 'circle', color: '#4C5AB3' },
icon: 'circle',
color: '#4C5AB3'
},
children: [ children: [
{ name: '实时触发', type: '触发条件', icon: '13', componentName: 'TriggeringConditions1' }, { name: '实时触发', type: '触发条件', icon: '13', componentName: 'TriggeringConditions1' },
{ name: '加入群组', type: '触发条件', icon: '14', componentName: 'TriggeringConditions2' }, { name: '加入群组', type: '触发条件', icon: '14', componentName: 'TriggeringConditions2' },
{ name: '变更属性', type: '触发条件', icon: '15', componentName: 'TriggeringConditions3' }, { name: '变更属性', type: '触发条件', icon: '15', componentName: 'TriggeringConditions3' },
{ name: '公众号', type: '触发条件', icon: '1', componentName: 'TriggeringConditions4' }, { name: '公众号', type: '触发条件', icon: '1', componentName: 'TriggeringConditions4', connection_type: 1 },
{ name: '抖音', type: '触发条件', icon: '6', componentName: 'TriggeringConditions5' }, { name: '抖音', type: '触发条件', icon: '6', componentName: 'TriggeringConditions5', connection_type: 6 },
{ name: '小红书', type: '触发条件', icon: '8', componentName: 'TriggeringConditions6' }, { name: '小红书', type: '触发条件', icon: '8', componentName: 'TriggeringConditions6', connection_type: 8 },
{ name: '微博', type: '触发条件', icon: '7', componentName: 'TriggeringConditions7' }, { name: '微博', type: '触发条件', icon: '7', componentName: 'TriggeringConditions7', connection_type: 7 },
{ name: '自定义', type: '触发条件', icon: '12', componentName: 'TriggeringConditions8' }, { name: '自定义', type: '触发条件', icon: '12', componentName: 'TriggeringConditions8', connection_type: 12 },
{ name: '小鹅通', type: '触发条件', icon: '3', componentName: 'TriggeringConditions9' }, { name: '小鹅通', type: '触发条件', icon: '3', componentName: 'TriggeringConditions9', connection_type: 3 },
{ name: '问卷星', type: '触发条件', icon: '4', componentName: 'TriggeringConditions10' } { name: '问卷星', type: '触发条件', icon: '4', componentName: 'TriggeringConditions10', connection_type: 4 }
] ]
}, },
{ {
name: '营销动作', name: '营销动作',
background: { background: { icon: 'square', color: '#19AAA5' },
icon: 'square',
color: '#19AAA5'
},
children: [ children: [
// { name: '终止旅程', type: '营销动作', icon: '16' }, // { name: '终止旅程', type: '营销动作', icon: '16' },
{ name: '加入群组', type: '营销动作', icon: '14', componentName: 'MarketingAction1' }, { name: '加入群组', type: '营销动作', icon: '14', componentName: 'MarketingAction1' },
...@@ -33,32 +41,40 @@ const list = ref([ ...@@ -33,32 +41,40 @@ const list = ref([
{ name: '变更属性', type: '营销动作', icon: '15', componentName: 'MarketingAction3' }, { name: '变更属性', type: '营销动作', icon: '15', componentName: 'MarketingAction3' },
{ name: '延时处理', type: '营销动作', icon: '18', componentName: 'MarketingAction4' }, { name: '延时处理', type: '营销动作', icon: '18', componentName: 'MarketingAction4' },
{ name: '内部通知', type: '营销动作', icon: '19', componentName: 'MarketingAction5' }, { name: '内部通知', type: '营销动作', icon: '19', componentName: 'MarketingAction5' },
{ name: '短信', type: '营销动作', icon: '10', componentName: 'MarketingAction6' }, { name: '短信', type: '营销动作', icon: '10', componentName: 'MarketingAction6', connection_type: 10 },
{ name: '邮件', type: '营销动作', icon: '9', componentName: 'MarketingAction7' }, { name: '邮件', type: '营销动作', icon: '9', componentName: 'MarketingAction7', connection_type: 9 },
{ name: '公众号', type: '营销动作', icon: '1', componentName: 'MarketingAction8' }, { name: '公众号', type: '营销动作', icon: '1', componentName: 'MarketingAction8', connection_type: 1 },
{ name: '抖音', type: '营销动作', icon: '6', componentName: 'MarketingAction9' }, { name: '抖音', type: '营销动作', icon: '6', componentName: 'MarketingAction9', connection_type: 6 },
// { name: '小红书', type: '营销动作', icon: '8' }, // { name: '小红书', type: '营销动作', icon: '8', connection_type: 8 },
{ name: '微博', type: '营销动作', icon: '7', componentName: 'MarketingAction10' }, { name: '微博', type: '营销动作', icon: '7', componentName: 'MarketingAction10', connection_type: 7 },
{ name: '钉钉', type: '营销动作', icon: '2', componentName: 'MarketingAction11' } { name: '钉钉', type: '营销动作', icon: '2', componentName: 'MarketingAction11', connection_type: 2 }
] ]
}, },
{ {
name: '条件分支', name: '条件分支',
background: { background: { icon: 'hexagon', color: '#CEAA62' },
icon: 'hexagon',
color: '#CEAA62'
},
children: [ children: [
{ name: '属性判断', type: '条件分支', icon: '20', componentName: 'ConditionalBranch6' }, { name: '属性判断', type: '条件分支', icon: '20', componentName: 'ConditionalBranch6' },
{ name: '标签判断', type: '条件分支', icon: '21', componentName: 'ConditionalBranch1' }, { name: '标签判断', type: '条件分支', icon: '21', componentName: 'ConditionalBranch1' },
{ name: '群组判断', type: '条件分支', icon: '22', componentName: 'ConditionalBranch2' }, { name: '群组判断', type: '条件分支', icon: '22', componentName: 'ConditionalBranch2' },
{ name: '事件判断', type: '条件分支', icon: '23', componentName: 'ConditionalBranch3' }, { name: '事件判断', type: '条件分支', icon: '23', componentName: 'ConditionalBranch3' },
{ name: '时间判断', type: '条件分支', icon: '24', componentName: 'ConditionalBranch4' }, { 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) => { const onDragStart = (event: DragEvent, data: any) => {
if (event.dataTransfer) { if (event.dataTransfer) {
event.dataTransfer.setData('application/vueflow', JSON.stringify(data)) event.dataTransfer.setData('application/vueflow', JSON.stringify(data))
...@@ -69,7 +85,7 @@ const onDragStart = (event: DragEvent, data: any) => { ...@@ -69,7 +85,7 @@ 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 currentList" :key="index">
<dt :style="`background: ${parent.background?.color}`">{{ parent.name }}</dt> <dt :style="`background: ${parent.background?.color}`">{{ parent.name }}</dt>
<dd> <dd>
<ul> <ul>
...@@ -77,8 +93,7 @@ const onDragStart = (event: DragEvent, data: any) => { ...@@ -77,8 +93,7 @@ const onDragStart = (event: DragEvent, data: any) => {
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)">
>
<div class="icon-box"> <div class="icon-box">
<Icon class="icon" color="#fff" :name="item.icon" w="24" h="24"></Icon> <Icon class="icon" color="#fff" :name="item.icon" w="24" h="24"></Icon>
<Icon <Icon
...@@ -86,8 +101,7 @@ const onDragStart = (event: DragEvent, data: any) => { ...@@ -86,8 +101,7 @@ const onDragStart = (event: DragEvent, data: any) => {
:color="parent.background?.color" :color="parent.background?.color"
:name="parent.background?.icon || ''" :name="parent.background?.icon || ''"
w="60" w="60"
h="60" h="60"></Icon>
></Icon>
</div> </div>
<p>{{ item.name }}</p> <p>{{ item.name }}</p>
</li> </li>
......
...@@ -28,7 +28,7 @@ export interface TagType { ...@@ -28,7 +28,7 @@ export interface TagType {
export interface ConnectionType { export interface ConnectionType {
id: string id: string
name: string name: string
type: string type: number
status: '0' | '1' status: '0' | '1'
config_attributes: any config_attributes: any
} }
......
<!-- 固定旅程模板配置 -->
<script setup lang="ts"> <script setup lang="ts">
import type { TripTemplate } from '../types' import type { TripTemplate } from '../types'
import type { ConnectionType } from '@/composables/useAllData'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import TripFlow from '@/components/flow/Index.vue' 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 { useMapStore } from '@/stores/map'
import { getNameByValue, tripTemplateTypeList } from '@/utils/dictionary' import { getNameByValue, tripTemplateTypeList } from '@/utils/dictionary'
const BindConnection = defineAsyncComponent(() => import('../components/BindConnection.vue'))
const props = defineProps<{ id: string }>() const props = defineProps<{ id: string }>()
...@@ -19,6 +23,17 @@ function fetchInfo() { ...@@ -19,6 +23,17 @@ function fetchInfo() {
onMounted(() => 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([]) const elements = ref([])
// 获取模板配置数据 // 获取模板配置数据
function fetchDemo() { function fetchDemo() {
...@@ -39,6 +54,12 @@ function handleSubmit() { ...@@ -39,6 +54,12 @@ function handleSubmit() {
ElMessage.success('保存成功') ElMessage.success('保存成功')
}) })
} }
// 配置
let configVisible = $ref(false)
function handleConfig() {
configVisible = true
}
</script> </script>
<template> <template>
<AppCard title="固定旅程模版配置"> <AppCard title="固定旅程模版配置">
...@@ -73,12 +94,33 @@ function handleSubmit() { ...@@ -73,12 +94,33 @@ function handleSubmit() {
</el-form> </el-form>
</el-card> </el-card>
<TripFlow v-model="elements" action="edit" role="teacher"> <TripFlow v-model="elements" action="edit" role="teacher">
<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> <template #footer>
<el-row justify="center"> <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-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
</el-row> </el-row>
</template> </template>
</TripFlow> </TripFlow>
</AppCard> </AppCard>
<!-- 配置连接 -->
<BindConnection
v-model="configVisible"
:data="detail"
v-if="configVisible && detail"
@update="fetchConnections"></BindConnection>
</template> </template>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论