提交 becb8546 authored 作者: lihuihui's avatar lihuihui
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
<link rel="icon" href="https://zws-imgs-pub.ezijing.com/pc/base/favicon.ico" /> <link rel="icon" href="https://zws-imgs-pub.ezijing.com/pc/base/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>数字营销实验室DML</title> <title>数字营销实验室DML</title>
<script src="https://webapp-pub.ezijing.com/screenshot.js" async></script>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
......
...@@ -45,12 +45,12 @@ export function updateUploadVideoAuth(data: { source_id: string }) { ...@@ -45,12 +45,12 @@ export function updateUploadVideoAuth(data: { source_id: string }) {
} }
// 获取实验下的所有用户属性 // 获取实验下的所有用户属性
export function getMetaUserAttrList() { export function getMetaUserAttrList(params?: { check_role?: boolean }) {
return httpRequest.get('/api/lab/v1/experiment/meta-member/all') return httpRequest.get('/api/lab/v1/experiment/meta-member/all', { params })
} }
// 获取实验下的所有事件 // 获取实验下的所有事件
export function getMetaEventList() { export function getMetaEventList(params?: { check_role?: boolean }) {
return httpRequest.get('/api/lab/v1/experiment/meta-event/all') return httpRequest.get('/api/lab/v1/experiment/meta-event/all', { params })
} }
// 获取实验下的所有标签 // 获取实验下的所有标签
...@@ -79,7 +79,13 @@ export function updateMaterial(data: { name: string; content: string; status: st ...@@ -79,7 +79,13 @@ export function updateMaterial(data: { name: string; content: string; status: st
} }
// 资料列表 // 资料列表
export function getMaterialList(params?: { name: string; type: string; id: string; status: string; updated_operator: string }) { export function getMaterialList(params?: {
name: string
type: string
id: string
status: string
updated_operator: string
}) {
return httpRequest.get('/api/lab/v1/experiment/marketing-material/list', { params }) return httpRequest.get('/api/lab/v1/experiment/marketing-material/list', { params })
} }
......
...@@ -39,28 +39,35 @@ function findMenu(path: string, menus: IMenuItem[]) { ...@@ -39,28 +39,35 @@ function findMenu(path: string, menus: IMenuItem[]) {
<nav class="menu"> <nav class="menu">
<ul> <ul>
<li v-for="item in menus" :key="item.path" :class="{ 'is-active': item.path === currentMenu?.path }"> <li v-for="item in menus" :key="item.path" :class="{ 'is-active': item.path === currentMenu?.path }">
<el-tooltip :content="item.name" placement="right"> <div class="menu-item">
<template v-if="item.children">
<RouterLink :to="item.path">
<component :is="item.icon" class="menu-icon"></component>
</RouterLink>
</template>
<el-tooltip :content="item.name" placement="right" v-else>
<RouterLink :to="item.path"> <RouterLink :to="item.path">
<component :is="item.icon" class="menu-icon"></component> <component :is="item.icon" class="menu-icon"></component>
</RouterLink> </RouterLink>
</el-tooltip> </el-tooltip>
</li> </div>
</ul> <nav class="submenu" v-if="item.children">
</nav> <h1 class="submenu-title">{{ item.name }}</h1>
<nav class="submenu" v-if="currentMenu?.children?.length">
<h1 class="submenu-title">{{ currentMenu.name }}</h1>
<ul> <ul>
<li <li
v-for="item in currentMenu.children" v-for="submenu in item.children"
:key="item.path" :key="submenu.path"
:class="{ 'is-active': item.path === currentSubmenu?.path }"> :class="{ 'is-active': submenu.path === currentSubmenu?.path }">
<RouterLink :to="item.path"> <RouterLink :to="submenu.path">
<component :is="item.icon" class="submenu-icon" v-if="item.icon"></component> <component :is="submenu.icon" class="submenu-icon" v-if="submenu.icon"></component>
{{ item.name }} {{ submenu.name }}
</RouterLink> </RouterLink>
</li> </li>
</ul> </ul>
</nav> </nav>
</li>
</ul>
</nav>
</aside> </aside>
</template> </template>
...@@ -70,18 +77,16 @@ function findMenu(path: string, menus: IMenuItem[]) { ...@@ -70,18 +77,16 @@ function findMenu(path: string, menus: IMenuItem[]) {
top: 0; top: 0;
display: flex; display: flex;
height: 100vh; height: 100vh;
overflow-x: hidden; // overflow-x: hidden;
overflow-y: auto; // overflow-y: auto;
box-sizing: content-box; box-sizing: content-box;
z-index: 2001;
.menu { .menu {
width: 60px; width: 60px;
height: 100%; height: 100%;
background: #fff; background: #fff;
box-sizing: border-box; box-sizing: border-box;
overflow-y: auto; .menu-item {
overflow-x: hidden;
li {
margin: 8px;
height: 44px; height: 44px;
text-align: center; text-align: center;
border-radius: 4px; border-radius: 4px;
...@@ -90,20 +95,33 @@ function findMenu(path: string, menus: IMenuItem[]) { ...@@ -90,20 +95,33 @@ function findMenu(path: string, menus: IMenuItem[]) {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
}
svg { svg {
fill: var(--main-color); fill: var(--main-color);
} }
}
}
> ul > li {
padding: 8px;
&.is-active { &.is-active {
.menu-item {
background-color: var(--main-color); background-color: var(--main-color);
svg { svg {
fill: #fff; fill: #fff;
} }
} }
} }
&:hover {
.submenu {
display: block;
}
}
}
} }
.submenu { .submenu {
display: none;
position: absolute;
left: 100%;
top: 0;
width: 200px; width: 200px;
height: 100vh; height: 100vh;
background: #efefef; background: #efefef;
......
...@@ -14,6 +14,11 @@ const eventAttrRule = ref(inject('eventAttrRule') as EventRule) ...@@ -14,6 +14,11 @@ const eventAttrRule = ref(inject('eventAttrRule') as EventRule)
const { metaEventList } = useMetaEvent() const { metaEventList } = useMetaEvent()
// 触发次数
const triggerNumberOperatorList = computed(() => {
return numberOperatorList.filter(item => !['range', 'null', 'not null'].includes(item.value))
})
// 获取逻辑运算符名称 // 获取逻辑运算符名称
function getLogicalName(value: 'and' | 'or') { function getLogicalName(value: 'and' | 'or') {
return value === 'or' ? '或' : '且' return value === 'or' ? '或' : '且'
...@@ -125,7 +130,7 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) { ...@@ -125,7 +130,7 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) {
<el-option v-for="option in happenInfoList" :key="option.label" v-bind="option"></el-option> <el-option v-for="option in happenInfoList" :key="option.label" v-bind="option"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-if="rule.happen_info.is_happened"> <el-form-item>
<el-select v-model="rule.happen_info.event_id" @change="value => handleEventChange(value, rule)"> <el-select v-model="rule.happen_info.event_id" @change="value => handleEventChange(value, rule)">
<el-option <el-option
v-for="option in metaEventList" v-for="option in metaEventList"
...@@ -134,16 +139,9 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) { ...@@ -134,16 +139,9 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) {
:value="option.id"></el-option> :value="option.id"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-button <el-button text :icon="Plus" @click="handleAttrAdd(rule.happen_info.attr_list)">添加条件</el-button>
text
:icon="Plus"
@click="handleAttrAdd(rule.happen_info.attr_list)"
v-if="rule.happen_info.is_happened"
>添加条件</el-button
>
<el-button text :icon="CloseBold" @click="handleRemove(eventAttrRule.items, index)"></el-button> <el-button text :icon="CloseBold" @click="handleRemove(eventAttrRule.items, index)"></el-button>
</el-row> </el-row>
<template v-if="rule.happen_info.is_happened">
<!-- 属性条件 --> <!-- 属性条件 -->
<el-row <el-row
justify="space-between" justify="space-between"
...@@ -193,12 +191,10 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) { ...@@ -193,12 +191,10 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) {
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
style="width: 180px" /> style="width: 180px" />
</template> </template>
<template <template v-else-if="attr.attr_type === '4' && (attr.operate === 'after' || attr.operate === 'before')">
v-else-if="attr.attr_type === '4' && (attr.operate === 'after' || attr.operate === 'before')">
<el-date-picker v-model="attr.value" type="date" value-format="YYYY-MM-DD" /> <el-date-picker v-model="attr.value" type="date" value-format="YYYY-MM-DD" />
</template> </template>
<template <template v-else-if="attr.attr_type === '5' && (attr.operate === 'after' || attr.operate === 'before')">
v-else-if="attr.attr_type === '5' && (attr.operate === 'after' || attr.operate === 'before')">
<el-date-picker <el-date-picker
v-model="attr.value" v-model="attr.value"
type="datetime" type="datetime"
...@@ -210,24 +206,19 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) { ...@@ -210,24 +206,19 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) {
</template> </template>
</el-form-item> </el-form-item>
</div> </div>
<el-button <el-button text :icon="CloseBold" @click="handleAttrRemove(rule.happen_info.attr_list, index)"></el-button>
text
:icon="CloseBold"
@click="handleAttrRemove(rule.happen_info.attr_list, index)"></el-button>
</el-row> </el-row>
<!-- 触发 --> <!-- 触发 -->
<el-row style="margin-top: 10px"> <el-row style="margin-top: 10px" v-if="rule.happen_info.is_happened">
<el-form-item> <el-form-item>
<el-select model-value="触发次数"> <el-select model-value="触发次数">
<el-option v-for="option in triggerInfoList" :key="option.value" v-bind="option"></el-option> <el-option v-for="option in triggerInfoList" :key="option.value" v-bind="option"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-select <el-select v-model="rule.trigger_info.operate" @change="value => handleTriggerOperateChange(value, rule)">
v-model="rule.trigger_info.operate"
@change="value => handleTriggerOperateChange(value, rule)">
<el-option <el-option
v-for="option in numberOperatorList" v-for="option in triggerNumberOperatorList"
:key="option.value" :key="option.value"
:label="option.alias || option.label" :label="option.alias || option.label"
:value="option.value" /> :value="option.value" />
...@@ -237,7 +228,6 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) { ...@@ -237,7 +228,6 @@ function handleTriggerOperateChange(value: string, item: EventRuleItem) {
<el-input v-model="rule.trigger_info.value" /> <el-input v-model="rule.trigger_info.value" />
</el-form-item> </el-form-item>
</el-row> </el-row>
</template>
</section> </section>
</div> </div>
</div> </div>
......
...@@ -37,7 +37,7 @@ export interface ConnectionType { ...@@ -37,7 +37,7 @@ export interface ConnectionType {
const userAttrList = ref<AttrType[]>([]) const userAttrList = ref<AttrType[]>([])
export function useUserAttr() { export function useUserAttr() {
function fetchUserAttrList() { function fetchUserAttrList() {
getMetaUserAttrList().then((res: any) => { getMetaUserAttrList({ check_role: true }).then((res: any) => {
userAttrList.value = res.data.items userAttrList.value = res.data.items
}) })
} }
...@@ -51,7 +51,7 @@ export function useUserAttr() { ...@@ -51,7 +51,7 @@ export function useUserAttr() {
const metaEventList = ref<MetaEventType[]>([]) const metaEventList = ref<MetaEventType[]>([])
export function useMetaEvent() { export function useMetaEvent() {
function fetchMetaEventList() { function fetchMetaEventList() {
getMetaEventList().then((res: any) => { getMetaEventList({ check_role: true }).then((res: any) => {
metaEventList.value = res.data.items metaEventList.value = res.data.items
}) })
} }
...@@ -75,7 +75,7 @@ export function useTag() { ...@@ -75,7 +75,7 @@ export function useTag() {
return { fetchTagList, tagList } return { fetchTagList, tagList }
} }
// 所有标签 // 所有连接
const connectionList = ref<ConnectionType[]>([]) const connectionList = ref<ConnectionType[]>([])
export function useConnection() { export function useConnection() {
function fetchConnectionList() { function fetchConnectionList() {
......
...@@ -25,3 +25,18 @@ export function getTripConnections(params: { itinerary_id: string }) { ...@@ -25,3 +25,18 @@ export function getTripConnections(params: { itinerary_id: string }) {
export function bindTripConnections(data: { itinerary_id: string; connection_ids: string[] }) { export function bindTripConnections(data: { itinerary_id: string; connection_ids: string[] }) {
return httpRequest.post('/api/lab/v1/experiment/itinerary/bind-connections', data) return httpRequest.post('/api/lab/v1/experiment/itinerary/bind-connections', data)
} }
// 获取旅程模板详情
export function getTripTemplate(params: { id: string }) {
return httpRequest.get('/api/lab/v1/experiment/itinerary/detail', { params })
}
// 获取旅程模板demo
export function getTripTemplateDemo(params: { itinerary_id: string }) {
return httpRequest.get('/api/lab/v1/experiment/itinerary/get-itinerary-demo', { params })
}
// 更新旅程模板demo
export function updateTripTemplateDemo(data: { itinerary_id: string; graph: string }) {
return httpRequest.post('/api/lab/v1/experiment/itinerary/save-itinerary-demo', data)
}
...@@ -5,7 +5,10 @@ const routes: RouteRecordRaw[] = [ ...@@ -5,7 +5,10 @@ const routes: RouteRecordRaw[] = [
{ {
path: '/trip/template', path: '/trip/template',
component: Layout, component: Layout,
children: [{ path: '', component: () => import('./views/Index.vue') }] children: [
{ path: '', component: () => import('./views/Index.vue') },
{ path: ':id', component: () => import('./views/Setting.vue'), props: true }
]
} }
] ]
......
...@@ -85,9 +85,15 @@ function handleView(row: TripTemplate) { ...@@ -85,9 +85,15 @@ function handleView(row: TripTemplate) {
// 配置 // 配置
let configVisible = $ref(false) let configVisible = $ref(false)
const router = useRouter()
function handleConfig(row: TripTemplate) { function handleConfig(row: TripTemplate) {
// 自由旅程
if (row.type === '2') {
router.push(`/trip/template/${row.id}`)
} else {
currentRow = row currentRow = row
configVisible = true configVisible = true
}
} }
</script> </script>
......
<script setup lang="ts">
import type { TripTemplate } from '../types'
import { ElMessage } from 'element-plus'
import TripFlow from '@/components/flow/Index.vue'
import { getTripTemplate, getTripTemplateDemo, updateTripTemplateDemo } from '../api'
import { useMapStore } from '@/stores/map'
import { getNameByValue, tripTemplateTypeList } from '@/utils/dictionary'
const props = defineProps<{ id: string }>()
const statusList = useMapStore().getMapValuesByKey('system_status')
const detail = ref<TripTemplate>()
function fetchInfo() {
getTripTemplate({ id: props.id }).then(res => {
detail.value = res.data.detail
})
}
onMounted(() => fetchInfo())
const elements = ref([])
// 获取模板配置数据
function fetchDemo() {
getTripTemplateDemo({ itinerary_id: props.id }).then(res => {
try {
elements.value = JSON.parse(res.data.graph)
} catch (error) {
console.log(error)
}
})
}
onMounted(() => fetchDemo())
// 保存
function handleSubmit() {
const params = { itinerary_id: props.id, graph: JSON.stringify(elements.value) }
updateTripTemplateDemo(params).then(() => {
ElMessage.success('保存成功')
})
}
</script>
<template>
<AppCard title="固定旅程模版配置">
<el-card shadow="never" style="margin-bottom: 20px" v-if="detail">
<el-form label-suffix=":">
<el-row justify="space-between">
<el-col :span="8">
<el-form-item label="旅程模版名称">{{ detail.name }}</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="模板类型">{{ getNameByValue(detail.type, tripTemplateTypeList) }}</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="分值">{{ detail.score }}</el-form-item>
</el-col>
</el-row>
<el-row justify="space-between">
<el-col :span="8">
<el-form-item label="更新人">{{ detail.updated_operator.real_name }}</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="更新时间">{{ detail.updated_time }}</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="状态">
<el-tag :type="detail.status === '1' ? 'success' : 'danger'">
{{ getNameByValue(detail.status, statusList) }}
</el-tag>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<TripFlow v-model="elements" action="edit" role="teacher" style="height: 80vh">
<template #footer>
<el-row justify="center">
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
</el-row>
</template>
</TripFlow>
</AppCard>
</template>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论