提交 95702e68 authored 作者: 王鹏飞's avatar 王鹏飞

refactor: 重构flow

上级 1bcc028b
...@@ -115,6 +115,7 @@ ...@@ -115,6 +115,7 @@
"useArrayFilter": true, "useArrayFilter": true,
"useArrayFind": true, "useArrayFind": true,
"useArrayFindIndex": true, "useArrayFindIndex": true,
"useArrayFindLast": true,
"useArrayJoin": true, "useArrayJoin": true,
"useArrayMap": true, "useArrayMap": true,
"useArrayReduce": true, "useArrayReduce": true,
......
// Generated by 'unplugin-auto-import' /* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-auto-import
export {} export {}
declare global { declare global {
const $$: typeof import('vue/macros')['$$'] const $$: typeof import('vue/macros')['$$']
...@@ -109,6 +112,7 @@ declare global { ...@@ -109,6 +112,7 @@ declare global {
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter'] const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
const useArrayFind: typeof import('@vueuse/core')['useArrayFind'] const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex'] const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast']
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin'] const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
const useArrayMap: typeof import('@vueuse/core')['useArrayMap'] const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce'] const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
...@@ -276,5 +280,5 @@ declare global { ...@@ -276,5 +280,5 @@ declare global {
// for type re-export // for type re-export
declare global { declare global {
// @ts-ignore // @ts-ignore
export type { Component,ComponentPublicInstance,ComputedRef,InjectionKey,PropType,Ref,VNode } from 'vue' export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
} }
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
// 获取实验旅程中的群组列表 // 获取实验旅程中的群组列表
export function getGroupsList() { export function getGroupList() {
return httpRequest.get('/api/lab/v1/experiment/itinerary/groups') return httpRequest.get('/api/lab/v1/experiment/itinerary/groups')
} }
...@@ -11,16 +11,21 @@ export function getAttrList() { ...@@ -11,16 +11,21 @@ export function getAttrList() {
} }
// 链接列表 // 链接列表
export function getConnectionList(params: { created_operator?: string; type?: string; page?: number; page_size?: number }) { export function getConnectionList() {
return httpRequest.get('/api/lab/v1/experiment/connection/list', { params }) return httpRequest.get('/api/lab/v1/experiment/itinerary/connections')
} }
// 标签列表 // 标签列表
export function getTagsList() { export function getTagList() {
return httpRequest.get('/api/lab/v1/experiment/itinerary/tags') return httpRequest.get('/api/lab/v1/experiment/itinerary/tags')
} }
// 时间列表 // 事件列表
export function getEventsList() { export function getEventList() {
return httpRequest.get('/api/lab/v1/experiment/itinerary/events') return httpRequest.get('/api/lab/v1/experiment/itinerary/events')
} }
// 营销资料列表
export function getMaterialList() {
return httpRequest.get('/api/lab/v1/experiment/itinerary/marketing-materials')
}
<script setup lang="ts"> <script setup lang="ts">
const component = computed(() => { const component = computed(() => {
const allComponent: any = { const allComponent: any = {
TriggeringConditions1: markRaw( TCRealTimeTrigger: markRaw(
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions1.vue')) defineAsyncComponent(() => import('./components/triggeringConditions/realTimeTrigger/Index.vue'))
), ),
TriggeringConditions2: markRaw( TCJoinGroup: markRaw(defineAsyncComponent(() => import('./components/triggeringConditions/joinGroup/Index.vue'))),
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions2.vue')) TCChangeProps: markRaw(
), defineAsyncComponent(() => import('./components/triggeringConditions/changeProps/Index.vue'))
TriggeringConditions3: markRaw( ),
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions3.vue')) TCOffiaccount: markRaw(
), defineAsyncComponent(() => import('./components/triggeringConditions/offiaccount/Index.vue'))
TriggeringConditions4: markRaw( ),
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions4.vue')) TCDouyin: markRaw(defineAsyncComponent(() => import('./components/triggeringConditions/douyin/Index.vue'))),
), TCXiaohongshu: markRaw(
TriggeringConditions5: markRaw( defineAsyncComponent(() => import('./components/triggeringConditions/xiaohongshu/Index.vue'))
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions5.vue')) ),
), TCWeibo: markRaw(defineAsyncComponent(() => import('./components/triggeringConditions/weibo/Index.vue'))),
TriggeringConditions6: markRaw( TCCustom: markRaw(defineAsyncComponent(() => import('./components/triggeringConditions/custom/Index.vue'))),
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions6.vue')) TCXiaoetong: markRaw(defineAsyncComponent(() => import('./components/triggeringConditions/xiaoetong/Index.vue'))),
), TCWenjuanxing: markRaw(
TriggeringConditions7: markRaw( defineAsyncComponent(() => import('./components/triggeringConditions/wenjuanxing/Index.vue'))
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions7.vue')) ),
), MAJoinGroup: markRaw(defineAsyncComponent(() => import('./components/marketingAction/joinGroup/Index.vue'))),
TriggeringConditions8: markRaw( MALeaveGroup: markRaw(defineAsyncComponent(() => import('./components/marketingAction/leaveGroup/Index.vue'))),
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions8.vue')) MAChangeProps: markRaw(defineAsyncComponent(() => import('./components/marketingAction/changeProps/Index.vue'))),
), MADelayProcess: markRaw(defineAsyncComponent(() => import('./components/marketingAction/delayProcess/Index.vue'))),
TriggeringConditions9: markRaw( MAInternalNotice: markRaw(
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions9.vue')) defineAsyncComponent(() => import('./components/marketingAction/internalNotice/Index.vue'))
), ),
TriggeringConditions10: markRaw( MAOffiaccount: markRaw(defineAsyncComponent(() => import('./components/marketingAction/offiaccount/Index.vue'))),
defineAsyncComponent(() => import('./components/triggeringConditions/TriggeringConditions10.vue')) MAEmail: markRaw(defineAsyncComponent(() => import('./components/marketingAction/email/Index.vue'))),
), MASMS: markRaw(defineAsyncComponent(() => import('./components/marketingAction/sms/Index.vue'))),
MarketingAction1: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction1.vue'))), MADouyin: markRaw(defineAsyncComponent(() => import('./components/marketingAction/douyin/Index.vue'))),
MarketingAction2: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction2.vue'))), MAWeibo: markRaw(defineAsyncComponent(() => import('./components/marketingAction/weibo/Index.vue'))),
MarketingAction3: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction3.vue'))), MADingTalk: markRaw(defineAsyncComponent(() => import('./components/marketingAction/dingtalk/Index.vue'))),
MarketingAction4: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction4.vue'))), CBAttributeJudgment: markRaw(
MarketingAction5: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction5.vue'))), defineAsyncComponent(() => import('./components/conditionalBranch/attributeJudgment/Index.vue'))
MarketingAction6: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction6.vue'))), ),
MarketingAction7: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction7.vue'))), CBGroupJudgment: markRaw(
MarketingAction8: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction8.vue'))), defineAsyncComponent(() => import('./components/conditionalBranch/groupJudgment/Index.vue'))
MarketingAction9: markRaw(defineAsyncComponent(() => import('./components/marketingAction/MarketingAction9.vue'))), ),
MarketingAction10: markRaw( CBEventJudgment: markRaw(
defineAsyncComponent(() => import('./components/marketingAction/MarketingAction10.vue')) defineAsyncComponent(() => import('./components/conditionalBranch/eventJudgment/Index.vue'))
), ),
MarketingAction11: markRaw( CBTimeJudgment: markRaw(
defineAsyncComponent(() => import('./components/marketingAction/MarketingAction11.vue')) defineAsyncComponent(() => import('./components/conditionalBranch/timeJudgment/Index.vue'))
), ),
ConditionalBranch1: markRaw( CBOffiaccount: markRaw(defineAsyncComponent(() => import('./components/conditionalBranch/offiaccount/Index.vue'))),
defineAsyncComponent(() => import('./components/conditionalBranch/ConditionalBranch1.vue')) CBLabelJudgment: markRaw(
), defineAsyncComponent(() => import('./components/conditionalBranch/labelJudgment/Index.vue'))
ConditionalBranch2: markRaw(
defineAsyncComponent(() => import('./components/conditionalBranch/ConditionalBranch2.vue'))
),
ConditionalBranch3: markRaw(
defineAsyncComponent(() => import('./components/conditionalBranch/ConditionalBranch3.vue'))
),
ConditionalBranch4: markRaw(
defineAsyncComponent(() => import('./components/conditionalBranch/ConditionalBranch4.vue'))
),
ConditionalBranch5: markRaw(
defineAsyncComponent(() => import('./components/conditionalBranch/ConditionalBranch5.vue'))
),
ConditionalBranch6: markRaw(
defineAsyncComponent(() => import('./components/conditionalBranch/ConditionalBranch6.vue'))
) )
} }
return allComponent[props.node?.data.componentName] return allComponent[props.node?.data.componentName]
......
...@@ -15,12 +15,14 @@ interface Props { ...@@ -15,12 +15,14 @@ interface Props {
action: string action: string
role: string role: string
templateType?: string templateType?: string
score?: number
} }
const props = withDefaults(defineProps<Props>(), { action: 'edit', role: 'teacher' }) const props = withDefaults(defineProps<Props>(), { action: 'edit', role: 'teacher', score: 0 })
provide('action', props.action) provide('action', props.action)
provide('role', props.role) provide('role', props.role)
provide('templateType', props.templateType) provide('templateType', props.templateType)
provide('score', props.score)
const { findNode, onConnect, addEdges, addNodes, project, vueFlowRef } = useVueFlow() const { findNode, onConnect, addEdges, addNodes, project, vueFlowRef } = useVueFlow()
......
...@@ -19,47 +19,47 @@ const list = ref([ ...@@ -19,47 +19,47 @@ const list = ref([
name: '触发条件', name: '触发条件',
background: { icon: 'circle', color: '#4C5AB3' }, background: { icon: 'circle', color: '#4C5AB3' },
children: [ children: [
{ name: '实时触发', type: '触发条件', icon: '13', componentName: 'TriggeringConditions1' }, { name: '定时触发', type: '触发条件', icon: '13', componentName: 'TCRealTimeTrigger' },
{ name: '加入群组', type: '触发条件', icon: '14', componentName: 'TriggeringConditions2' }, { name: '加入群组', type: '触发条件', icon: '14', componentName: 'TCJoinGroup' },
{ name: '变更属性', type: '触发条件', icon: '15', componentName: 'TriggeringConditions3' }, { name: '变更属性', type: '触发条件', icon: '15', componentName: 'TCChangeProps' },
{ name: '公众号', type: '触发条件', icon: '1', componentName: 'TriggeringConditions4', connection_type: 1 }, { name: '公众号', type: '触发条件', icon: '1', componentName: 'TCOffiaccount', connection_type: 1 },
{ name: '抖音', type: '触发条件', icon: '6', componentName: 'TriggeringConditions5', connection_type: 6 }, { name: '抖音', type: '触发条件', icon: '6', componentName: 'TCDouyin', connection_type: 6 },
{ name: '小红书', type: '触发条件', icon: '8', componentName: 'TriggeringConditions6', connection_type: 8 }, { name: '小红书', type: '触发条件', icon: '8', componentName: 'TCXiaohongshu', connection_type: 8 },
{ name: '微博', type: '触发条件', icon: '7', componentName: 'TriggeringConditions7', connection_type: 7 }, { name: '微博', type: '触发条件', icon: '7', componentName: 'TCWeibo', connection_type: 7 },
{ name: '自定义', type: '触发条件', icon: '12', componentName: 'TriggeringConditions8', connection_type: 12 }, { name: '自定义', type: '触发条件', icon: '12', componentName: 'TCCustom', connection_type: 12 },
{ name: '小鹅通', type: '触发条件', icon: '3', componentName: 'TriggeringConditions9', connection_type: 3 }, { name: '小鹅通', type: '触发条件', icon: '3', componentName: 'TCXiaoetong', connection_type: 3 },
{ name: '问卷星', type: '触发条件', icon: '4', componentName: 'TriggeringConditions10', connection_type: 4 } { name: '问卷星', type: '触发条件', icon: '4', componentName: 'TCWenjuanxing', connection_type: 4 }
] ]
}, },
{ {
name: '营销动作', name: '营销动作',
background: { icon: 'square', color: '#19AAA5' }, background: { icon: 'square', color: '#19AAA5' },
children: [ children: [
// { name: '终止旅程', type: '营销动作', icon: '16' }, { name: '终止旅程', type: '营销动作', icon: '16', componentName: 'MAEndTrip' },
{ name: '加入群组', type: '营销动作', icon: '14', componentName: 'MarketingAction1' }, { name: '加入群组', type: '营销动作', icon: '14', componentName: 'MAJoinGroup' },
{ name: '移除群组', type: '营销动作', icon: '17', componentName: 'MarketingAction2' }, { name: '移除群组', type: '营销动作', icon: '17', componentName: 'MALeaveGroup' },
{ name: '变更属性', type: '营销动作', icon: '15', componentName: 'MarketingAction3' }, { name: '变更属性', type: '营销动作', icon: '15', componentName: 'MAChangeProps' },
{ name: '延时处理', type: '营销动作', icon: '18', componentName: 'MarketingAction4' }, { name: '延时处理', type: '营销动作', icon: '18', componentName: 'MADelayProcess' },
{ name: '内部通知', type: '营销动作', icon: '19', componentName: 'MarketingAction5' }, { name: '内部通知', type: '营销动作', icon: '19', componentName: 'MAInternalNotice' },
{ name: '短信', type: '营销动作', icon: '10', componentName: 'MarketingAction6', connection_type: 10 }, { name: '短信', type: '营销动作', icon: '10', componentName: 'MASMS', connection_type: 10 },
{ name: '邮件', type: '营销动作', icon: '9', componentName: 'MarketingAction7', connection_type: 9 }, { name: '邮件', type: '营销动作', icon: '9', componentName: 'MAEmail', connection_type: 9 },
{ name: '公众号', type: '营销动作', icon: '1', componentName: 'MarketingAction8', connection_type: 1 }, { name: '公众号', type: '营销动作', icon: '1', componentName: 'MAOffiaccount', connection_type: 1 },
{ name: '抖音', type: '营销动作', icon: '6', componentName: 'MarketingAction9', connection_type: 6 }, { name: '抖音', type: '营销动作', icon: '6', componentName: 'MADouyin', connection_type: 6 },
// { name: '小红书', type: '营销动作', icon: '8', connection_type: 8 }, // { name: '小红书', type: '营销动作', icon: '8', componentName: 'MAXiaohongshu', connection_type: 8 },
{ name: '微博', type: '营销动作', icon: '7', componentName: 'MarketingAction10', connection_type: 7 }, { name: '微博', type: '营销动作', icon: '7', componentName: 'MAWeibo', connection_type: 7 },
{ name: '钉钉', type: '营销动作', icon: '2', componentName: 'MarketingAction11', connection_type: 2 } { name: '钉钉', type: '营销动作', icon: '2', componentName: 'MADingTalk', connection_type: 2 }
] ]
}, },
{ {
name: '条件分支', name: '条件分支',
background: { icon: 'hexagon', color: '#CEAA62' }, background: { icon: 'hexagon', color: '#CEAA62' },
children: [ children: [
{ name: '属性判断', type: '条件分支', icon: '20', componentName: 'ConditionalBranch6' }, { name: '属性判断', type: '条件分支', icon: '20', componentName: 'CBAttributeJudgment' },
{ name: '标签判断', type: '条件分支', icon: '21', componentName: 'ConditionalBranch1' }, { name: '标签判断', type: '条件分支', icon: '21', componentName: 'CBLabelJudgment' },
{ name: '群组判断', type: '条件分支', icon: '22', componentName: 'ConditionalBranch2' }, { name: '群组判断', type: '条件分支', icon: '22', componentName: 'CBGroupJudgment' },
{ name: '事件判断', type: '条件分支', icon: '23', componentName: 'ConditionalBranch3' }, { name: '事件判断', type: '条件分支', icon: '23', componentName: 'CBEventJudgment' },
{ name: '时间判断', type: '条件分支', icon: '24', componentName: 'ConditionalBranch4' }, { name: '时间判断', type: '条件分支', icon: '24', componentName: 'CBTimeJudgment' },
{ name: '公众号', type: '条件分支', icon: '1', componentName: 'ConditionalBranch5', connection_type: 1 } { name: '公众号', type: '条件分支', icon: '1', componentName: 'CBOffiaccount', connection_type: 1 }
] ]
} }
]) ])
...@@ -93,8 +93,7 @@ const onDragStart = (event: DragEvent, data: any) => { ...@@ -93,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
...@@ -102,8 +101,7 @@ const onDragStart = (event: DragEvent, data: any) => { ...@@ -102,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>
......
<!-- 学生设置组件 -->
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import { useVueFlow } from '@vue-flow/core'
interface Props {
model: any
node: any
stepNum?: number
}
const props = defineProps<Props>()
const role = inject('role') as string
const score = inject('score') as number
const { nodes } = useVueFlow()
const formRef = ref<FormInstance>()
const form = reactive({
score: undefined,
answer_analysis: ''
})
watchEffect(() => {
Object.assign(form, props.model)
})
const rules = ref<FormRules>({
score: [{ required: true, message: '请输入组件分值' }]
})
const step = ref(0)
// 已设置组件分值
const scoreTotal = computed(() => {
return nodes.value.reduce((total, node) => {
const nodeScore = node.data.teacher?.score || 0
return total + parseFloat(nodeScore)
}, 0)
})
// 最大可设置的分值
const maxScore = computed(() => {
const nodeScore = props.node.data.teacher?.score || 0
return score - (scoreTotal.value - nodeScore)
})
// 保存
function submit() {
formRef.value?.validate().then(updateNode)
}
function updateNode() {
if (props.node && role) Object.assign(props.node.data, { [role]: { ...form } })
}
</script>
<template>
<el-dialog title="设置组件" append-to-body width="600px">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":">
<!-- 学生设置组件 -->
<template v-if="role === 'student'">
<el-row justify="space-between">
<el-form-item label="组件类型">{{ node.data.type }}</el-form-item>
<el-form-item label="组件名称">{{ node.data.name }}</el-form-item>
<el-form-item label="分值">{{ node.data.teacher.score }} </el-form-item>
</el-row>
<slot :step="step" :model="form"></slot>
</template>
<!-- 老师设置组件 -->
<template v-if="role === 'teacher'">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="组件类型">{{ node.data.type }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="组件名称">{{ node.data.name }}</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="组件分值" prop="score">
<el-input-number v-model="form.score" :controls="false" :max="maxScore" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="已设置组件分值">{{ scoreTotal }}</el-form-item>
</el-col>
</el-row>
<el-card header="标准答案" shadow="never">
<slot :step="step" :model="form"></slot>
</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" v-if="stepNum">
<!-- <el-button plain auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button> -->
<el-button @click="step--" plain auto-insert-space v-if="step >= 1">上一步</el-button>
<el-button @click="step++" plain auto-insert-space v-if="step < stepNum">下一步</el-button>
<el-button type="primary" auto-insert-space @click="submit" v-if="step === stepNum">保存</el-button>
</el-row>
<el-row justify="center" v-else>
<el-button plain auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button type="primary" auto-insert-space @click="submit">保存</el-button>
</el-row>
</template>
</el-dialog>
</template>
<!-- 学生设置组件 -->
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
interface Props {
node: any
}
const props = defineProps<Props>()
const role = inject('role') as string
const formRef = ref<FormInstance>()
const form = reactive({
score: undefined
})
watchEffect(() => {
Object.assign(form, props.node.data.student)
})
const rules = ref<FormRules>({
score: [{ required: true, message: '请输入组件分值' }]
})
// 保存
function submit() {
formRef.value?.validate().then(updateNode)
}
function updateNode() {
if (props.node && role) Object.assign(props.node.data, { student: { ...form } })
}
</script>
<template>
<el-dialog title="组件配置" append-to-body width="600px">
<el-form ref="formRef" :rules="rules" label-suffix=":">
<el-row justify="space-between">
<el-form-item label="组件类型">{{ node.data.type }}</el-form-item>
<el-form-item label="组件名称">{{ node.data.name }}</el-form-item>
<el-form-item label="分值">{{ node.data.teacher.score }} </el-form-item>
</el-row>
<slot></slot>
<el-form-item label="答案解析"> {{ node.data.teacher.answer_analysis }} </el-form-item>
<!-- 老师评分 -->
<template v-if="role === 'teacher'">
<el-form-item label="得分">
<el-input-number v-model="form.score" :controls="false" />
</el-form-item>
</template>
<!-- 学生查看评分 -->
<template v-if="role === 'student'">
<el-form-item label="得分">{{ node.data.student.score }}</el-form-item>
</template>
</el-form>
<template #footer>
<el-row justify="center">
<el-button plain auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button type="primary" auto-insert-space @click="submit" v-if="role === 'teacher'">保存</el-button>
</el-row>
</template>
</el-dialog>
</template>
...@@ -111,3 +111,15 @@ const handleToolbar = function () { ...@@ -111,3 +111,15 @@ const handleToolbar = function () {
} }
} }
</style> </style>
<style 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'
import { CirclePlusFilled, RemoveFilled } from '@element-plus/icons-vue'
import { getTagsList } 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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({
score: '',
type: '',
name: '',
tags: [
{
tag_id: '',
condition_id: '',
tag_value: ''
}
]
})
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
// 标签列表
const tags = ref()
onMounted(() => {
getTagsList().then(res => {
tags.value = res.data.items
})
})
const conditionOptions = [
{ label: '等于', value: '0' },
{ label: '不等于', value: '1' },
{ label: '包含', value: '2' },
{ label: '不包含', value: '3' },
{ label: '空值', value: '4' },
{ label: '非空', value: '5' }
]
const addTag = function () {
form.tags.push({
tag_id: '',
condition_id: '',
tag_value: ''
})
}
const removeTag = function (index) {
form.tags.splice(index, 1)
}
</script>
<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 :disabled="action === 'view'" 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>
<div style="display: flex; align-items: center; margin-bottom: 15px" v-for="(item, index) in form.tags">
<el-select v-model="item.tag_id" placeholder="请选择标签">
<el-option v-for="opt in tags" :value="opt.id" :label="opt.name"></el-option>
</el-select>
<el-select style="margin: 0 10px" v-model="item.condition_id" placeholder="请选择">
<el-option v-for="opt in conditionOptions" :value="opt.value" :label="opt.label"></el-option>
</el-select>
<el-input v-model="item.tag_value" placeholder="请输入标签值"></el-input>
<el-icon
v-if="form.tags.length > 1"
size="20"
color="#AA1941"
style="margin-left: 10px"
@click="removeTag(index)"
><RemoveFilled
/></el-icon>
<el-icon
v-if="index === form.tags.length - 1"
size="20"
color="#AA1941"
style="margin-left: 10px"
@click="addTag"
><CirclePlusFilled
/></el-icon>
</div>
</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">
<div style="display: flex; align-items: center; margin-bottom: 15px" v-for="(item, index) in form.tags">
<el-select v-model="item.tag_id" placeholder="请选择标签">
<el-option v-for="opt in tags" :value="opt.id" :label="opt.name"></el-option>
</el-select>
<el-select style="margin: 0 10px" v-model="item.condition_id" placeholder="请选择">
<el-option v-for="opt in conditionOptions" :value="opt.value" :label="opt.label"></el-option>
</el-select>
<el-input v-model="item.tag_value" placeholder="请输入标签值"></el-input>
<el-icon
v-if="form.tags.length > 1"
size="20"
color="#AA1941"
style="margin-left: 10px"
@click="removeTag(index)"
><RemoveFilled
/></el-icon>
<el-icon
v-if="index === form.tags.length - 1"
size="20"
color="#AA1941"
style="margin-left: 10px"
@click="addTag"
><CirclePlusFilled
/></el-icon>
</div>
</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getGroupsList } 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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({
score: '',
type: '',
name: '',
radio: '0',
group_id: ''
})
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
// 标签列表
const groupsOption = ref()
onMounted(() => {
getGroupsList().then(res => {
groupsOption.value = res.data.items
})
})
</script>
<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 :disabled="action === 'view'" 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>
<el-radio-group v-model="form.radio">
<el-radio label="0">在群组中</el-radio>
<el-radio label="1">不在群组中</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-select v-model="form.group_id">
<el-option v-for="item in groupsOption" :value="item.id" :label="item.name"></el-option>
</el-select>
</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>
<el-radio-group v-model="form.radio">
<el-radio label="0">在群组中</el-radio>
<el-radio label="1">不在群组中</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-select v-model="form.group_id">
<el-option v-for="item in groupsOption" :value="item.id" :label="item.name"></el-option>
</el-select>
</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getEventsList } 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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({
score: '',
type: '',
name: '',
event_id: ''
})
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
// 标签列表
const eventsOption = ref()
onMounted(() => {
getEventsList().then(res => {
eventsOption.value = res.data.items
})
})
</script>
<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 :disabled="action === 'view'" 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>
<el-select v-model="form.event_id" placeholder="请选择触发事件">
<el-option v-for="item in eventsOption" :value="item.id" :label="item.name"></el-option>
</el-select>
</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>
<el-select v-model="form.event_id" placeholder="请选择触发事件">
<el-option v-for="item in eventsOption" :value="item.id" :label="item.name"></el-option>
</el-select>
</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>
<!-- 定时触发 -->
<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 templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({
score: '',
type: '',
name: '',
radio: '0',
date: '',
condition_id: '0',
week: []
})
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
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">
<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 :disabled="action === 'view'" 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="时间判断类型">
<el-radio-group v-model="form.radio">
<el-radio label="0">日期范围</el-radio>
<el-radio label="1">星期范围</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="进入该步骤的时间">
<template v-if="form.radio === '0'">
<el-select v-model="form.condition_id" placeholder="请选择" style="width: 115px">
<el-option label="早于" value="0" />
<el-option label="晚于" value="1" />
<el-option label="区间" value="2" />
</el-select>
<el-date-picker
v-if="form.condition_id === '0' || form.condition_id === '1'"
v-model="form.date"
type="date"
placeholder="请选择"
/>
<el-date-picker
v-else
v-model="form.date"
style="width: 100px"
type="daterange"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</template>
<template v-else>
<el-checkbox-group v-model="form.week">
<el-checkbox label="周一" />
<el-checkbox label="周二" />
<el-checkbox label="周三" />
<el-checkbox label="周四" />
<el-checkbox label="周五" />
<el-checkbox label="周六" />
<el-checkbox label="周日" />
</el-checkbox-group>
</template>
</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="时间判断类型">
<el-radio-group v-model="form.radio">
<el-radio label="0">日期范围</el-radio>
<el-radio label="1">星期范围</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="进入该步骤的时间">
<template v-if="form.radio === '0'">
<el-select v-model="form.condition_id" placeholder="请选择" style="width: 115px">
<el-option label="早于" value="0" />
<el-option label="晚于" value="1" />
<el-option label="区间" value="2" />
</el-select>
<el-date-picker
v-if="form.condition_id === '0' || form.condition_id === '1'"
v-model="form.date"
type="date"
placeholder="请选择"
/>
<el-date-picker
v-else
v-model="form.date"
style="width: 100px"
type="daterange"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</template>
<template v-else>
<el-checkbox-group v-model="form.week">
<el-checkbox label="周一" />
<el-checkbox label="周二" />
<el-checkbox label="周三" />
<el-checkbox label="周四" />
<el-checkbox label="周五" />
<el-checkbox label="周六" />
<el-checkbox label="周日" />
</el-checkbox-group>
</template>
</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getConnectionList } from '@/api/flow'
import { useMapStore } from '@/stores/map'
import { getMaterialList } from '@/api/base'
const store = useMapStore()
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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ material_type: '0', step_one_id: '0', step_two_value: '', material_value: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
const stepOneOptions = [{ label: '发送邮件', value: '0' }]
const stepTwoOptions = ref()
onMounted(() => {
// 链接列表
getConnectionList({ type: '1' }).then(res => {
stepTwoOptions.value = res.data.list
})
changeMaterialType()
})
// 步骤
let stepActive = ref(0)
// 选择资料类型
let materiaList = ref([])
const changeMaterialType = function () {
form.material_value = ''
getMaterialList({ type: form.material_type }).then(res => {
materiaList.value = res.data.list
})
}
</script>
<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 :disabled="action === 'view'" 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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-form-item>
<el-radio-group v-model="form.material_type">
<el-radio style="width: 105px" label="0">关注中</el-radio>
</el-radio-group>
</el-form-item>
</el-radio-group>
<!-- 第二步 -->
<el-select placeholder="请选择公众号" style="width: 100%" v-model="form.step_two_value" v-if="stepActive === 1">
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
</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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-form-item>
<el-radio-group v-model="form.material_type">
<el-radio style="width: 105px" label="0">关注中</el-radio>
</el-radio-group>
</el-form-item>
</el-radio-group>
<!-- 第二步 -->
<el-select
placeholder="请选择公众号"
style="width: 100%"
v-model="form.step_two_value"
v-if="stepActive === 1"
>
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
</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 @click="stepActive--" plain auto-insert-space v-if="stepActive !== 0">上一步</el-button>
<el-button @click="stepActive++" plain auto-insert-space v-if="stepActive < 1">下一步</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit" v-if="stepActive === 1">保存</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>
<script setup lang="ts">
import { CirclePlusFilled, RemoveFilled } from '@element-plus/icons-vue'
import ConfigTemplate from '../../ConfigTemplate.vue'
import { stringOperatorList, numberOperatorList, dateOperatorList } from '@/utils/dictionary'
import { useUserAttr } from '../../../useAllData'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
rules: [{ attr_id: '', attr_type: '', operate: '', value: '' }]
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const { userAttrList } = useUserAttr()
// 获取运算符列表
function getOperatorList(type: string) {
if (type === '1') return stringOperatorList
if (type === '2' || type === '3') return numberOperatorList
if (type === '4' || type === '5') return dateOperatorList
return stringOperatorList
}
function onAttrChange(rule: any) {
const currentUserAttr = userAttrList.value.find(item => item.id === rule.attr_id)
rule.attr_type = currentUserAttr ? currentUserAttr.type : ''
rule.operate = ''
rule.value = ''
}
function addRule() {
form.rules.push({ attr_id: '', attr_type: '', operate: '=', value: '' })
}
function removeRule(index: number) {
form.rules.splice(index, 1)
}
</script>
<template>
<ConfigTemplate :model="form" :node="node">
<el-form-item v-for="(rule, index) in form.rules" :key="index">
<el-row align="middle">
<el-select v-model="rule.attr_id" @change="onAttrChange(rule)" placeholder="请选择属性" style="width: 120px">
<el-option :key="item.id" v-for="item in userAttrList" :value="item.id" :label="item.name"></el-option>
</el-select>
<el-select v-model="rule.operate" style="margin: 0 10px; width: 120px">
<el-option
v-for="item in getOperatorList(rule.attr_type)"
:key="item.value"
:value="item.value"
:label="item.label"></el-option>
</el-select>
<el-input v-model="rule.value" placeholder="请输入属性值" style="width: 180px"></el-input>
<el-icon style="margin-left: 10px" size="20" color="#cf5b78" @click="removeRule(index)" v-if="index !== 0">
<RemoveFilled />
</el-icon>
<el-icon
style="margin-left: 10px"
size="20"
color="#cf5b78"
@click="addRule"
v-if="index === form.rules.length - 1">
<CirclePlusFilled />
</el-icon>
</el-row>
</el-form-item>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 属性判断 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="hexagon" :color="isGray ? '#9a9a9a' : '#ceaa62'" w="60" h="60"></Icon>
<Icon class="icon" name="20" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import ConfigTemplate from '../../ConfigTemplate.vue'
import { useMetaEvent } from '../../../useAllData'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
event_id: ''
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const { metaEventList } = useMetaEvent()
</script>
<template>
<ConfigTemplate :model="form" :node="node">
<el-form-item>
<el-select v-model="form.event_id" placeholder="请选择触发事件">
<el-option v-for="item in metaEventList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 属性判断 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="hexagon" :color="isGray ? '#9a9a9a' : '#ceaa62'" w="60" h="60"></Icon>
<Icon class="icon" name="23" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import ConfigTemplate from '../../ConfigTemplate.vue'
import { useGroup } from '../../../useAllData'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
in_group: '',
group_id: ''
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const { groupList } = useGroup()
</script>
<template>
<ConfigTemplate :model="form" :node="node">
<el-form-item>
<el-radio-group v-model="form.in_group">
<el-radio label="0">在群组中</el-radio>
<el-radio label="1">不在群组中</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-select v-model="form.group_id">
<el-option v-for="item in groupList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 属性判断 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="hexagon" :color="isGray ? '#9a9a9a' : '#ceaa62'" w="60" h="60"></Icon>
<Icon class="icon" name="22" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import { CirclePlusFilled, RemoveFilled } from '@element-plus/icons-vue'
import ConfigTemplate from '../../ConfigTemplate.vue'
import { stringOperatorList } from '@/utils/dictionary'
import { useTag } from '../../../useAllData'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
rules: [{ tag_id: '', operate: '', value: '' }]
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const { tagList } = useTag()
function addRule() {
form.rules.push({ tag_id: '', operate: '=', value: '' })
}
function removeRule(index: number) {
form.rules.splice(index, 1)
}
</script>
<template>
<ConfigTemplate :model="form" :node="node">
<el-form-item v-for="(rule, index) in form.rules" :key="index">
<el-row align="middle">
<el-select v-model="rule.tag_id" placeholder="请选择标签" style="width: 120px">
<el-option :key="item.id" v-for="item in tagList" :value="item.id" :label="item.name"></el-option>
</el-select>
<el-select v-model="rule.operate" style="margin: 0 10px; width: 120px">
<el-option
v-for="item in stringOperatorList"
:key="item.value"
:value="item.value"
:label="item.label"></el-option>
</el-select>
<el-input v-model="rule.value" placeholder="请输入标签值" style="width: 180px"></el-input>
<el-icon style="margin-left: 10px" size="20" color="#cf5b78" @click="removeRule(index)" v-if="index !== 0">
<RemoveFilled />
</el-icon>
<el-icon
style="margin-left: 10px"
size="20"
color="#cf5b78"
@click="addRule"
v-if="index === form.rules.length - 1">
<CirclePlusFilled />
</el-icon>
</el-row>
</el-form-item>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 属性判断 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="hexagon" :color="isGray ? '#9a9a9a' : '#ceaa62'" w="60" h="60"></Icon>
<Icon class="icon" name="21" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import ConfigTemplate from '../../ConfigTemplate.vue'
import { useConnection } from '../../../useAllData'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
operate: '',
connection_id: ''
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const { connectionList } = useConnection()
const operateList = ref([{ label: '关注中', value: '0' }])
</script>
<template>
<ConfigTemplate :model="form" :node="node" :stepNum="1">
<template #default="{ step }: { step: number }">
<el-form-item>
<template v-if="step === 0">
<el-radio-group v-model="form.operate" v-if="step === 0">
<el-radio v-for="item in operateList" :key="item.value" :label="item.value" style="width: 105px">
{{ item.label }}
</el-radio>
</el-radio-group>
</template>
<template v-else-if="step === 1">
<el-select placeholder="请选择关联使用公众号" style="width: 100%" v-model="form.connection_id">
<el-option v-for="item in connectionList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</template>
</el-form-item>
</template>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 公众号 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="hexagon" :color="isGray ? '#9a9a9a' : '#ceaa62'" w="60" h="60"></Icon>
<Icon class="icon" name="1" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import ConfigTemplate from '../../ConfigTemplate.vue'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
date_type: '',
date_rule: '',
date: '',
week: []
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const dateTypeList = ref([
{ label: '日期范围', value: '0' },
{ label: '星期范围', value: '1' }
])
const dateRuleList = ref([
{ label: '早于', value: '0' },
{ label: '晚于', value: '1' },
{ label: '区间', value: '2' }
])
const weekList = ref(['周一', '周二', '周三', '周四', '周五', '周六', '周日'])
</script>
<template>
<ConfigTemplate :model="form" :node="node">
<el-form-item label="时间判断类型">
<el-radio-group v-model="form.date_type">
<el-radio v-for="item in dateTypeList" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="进入该步骤的时间">
<template v-if="form.date_type === '0'">
<el-select v-model="form.date_rule" placeholder="请选择" style="width: 115px">
<el-option v-for="item in dateRuleList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-date-picker
v-if="['0', '1'].includes(form.date_rule)"
v-model="form.date"
type="date"
placeholder="请选择" />
<el-date-picker
v-else
v-model="form.date"
style="width: 100px"
type="daterange"
start-placeholder="开始时间"
end-placeholder="结束时间" />
</template>
<template v-else>
<el-checkbox-group v-model="form.week">
<el-checkbox v-for="item in weekList" :key="item" :label="item" />
</el-checkbox-group>
</template>
</el-form-item>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 时间判断 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="hexagon" :color="isGray ? '#9a9a9a' : '#ceaa62'" w="60" h="60"></Icon>
<Icon class="icon" name="24" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getGroupsList } 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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ group_id: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
// 获取群组列表
const groupsOption = ref([])
const getGroups = function () {
getGroupsList().then(res => {
groupsOption.value = res.data.items
})
}
onMounted(() => {
getGroups()
})
</script>
<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 :disabled="action === 'view'" 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>
<el-select style="width: 100%" v-model="form.group_id" placeholder="请选择用户群组">
<el-option :key="item.id" v-for="item in groupsOption" :value="item.id" :label="item.name"></el-option>
</el-select>
</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>
<el-select style="width: 100%" v-model="form.group_id" placeholder="请选择用户群组">
<el-option :key="item.id" v-for="item in groupsOption" :value="item.id" :label="item.name"></el-option>
</el-select>
</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getConnectionList } from '@/api/flow'
import { useMapStore } from '@/stores/map'
import { getMaterialList } from '@/api/base'
const store = useMapStore()
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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ step_one_id: '0', step_two_value: '', material_type: '1', material_value: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
const stepOneOptions = [
{ label: '发送私信', value: '0' },
{ label: '发送图片', value: '1' },
{ label: '向用户发送视频私信', value: '2' }
]
const stepTwoOptions = ref()
onMounted(() => {
// 链接列表
getConnectionList({ type: '7' }).then(res => {
stepTwoOptions.value = res.data.list
})
changeMaterialType()
})
// 步骤
let stepActive = ref(0)
// 选择资料类型
let materiaList = ref([])
const changeMaterialType = function () {
form.material_value = ''
getMaterialList({ type: form.material_type }).then(res => {
materiaList.value = res.data.list
})
}
</script>
<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 :disabled="action === 'view'" 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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio :label="item.value" v-for="item in stepOneOptions">{{ item.label }}</el-radio>
</el-radio-group>
<!-- 第二步 -->
<el-select
placeholder="请选择关联使用微博"
style="width: 100%"
v-model="form.step_two_value"
v-if="stepActive === 1"
>
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
<!-- 第三步 -->
<div class="means-box" v-if="stepActive === 2">
<el-form-item label="请选择营销资料">
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择使用营销资料" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</div>
</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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio :label="item.value" v-for="item in stepOneOptions">{{ item.label }}</el-radio>
</el-radio-group>
<!-- 第二步 -->
<el-select
placeholder="请选择关联使用微博"
style="width: 100%"
v-model="form.step_two_value"
v-if="stepActive === 1"
>
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
<!-- 第三步 -->
<div class="means-box" v-if="stepActive === 2">
<el-form-item label="请选择营销资料">
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择使用营销资料" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</div>
</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 @click="stepActive--" plain auto-insert-space v-if="stepActive !== 0">上一步</el-button>
<el-button @click="stepActive++" plain auto-insert-space v-if="stepActive < 2">下一步</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit" v-if="stepActive === 2">保存</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getConnectionList } from '@/api/flow'
import { useMapStore } from '@/stores/map'
import { getMaterialList } from '@/api/base'
const store = useMapStore()
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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ step_one_id: '0', step_two_value: '', material_type: '1', material_value: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
const stepOneOptions = [{ label: '发送消息', value: '0' }]
const stepTwoOptions = ref()
onMounted(() => {
// 链接列表
getConnectionList({ type: '2' }).then(res => {
stepTwoOptions.value = res.data.list
})
changeMaterialType()
})
// 步骤
let stepActive = ref(0)
// 选择资料类型
let materiaList = ref([])
const changeMaterialType = function () {
form.material_value = ''
getMaterialList({ type: form.material_type }).then(res => {
materiaList.value = res.data.list
})
}
</script>
<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 :disabled="action === 'view'" 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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio :label="item.value" v-for="item in stepOneOptions">{{ item.label }}</el-radio>
</el-radio-group>
<!-- 第二步 -->
<el-select
placeholder="请选择关联使用钉钉"
style="width: 100%"
v-model="form.step_two_value"
v-if="stepActive === 1"
>
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
<!-- 第三步 -->
<div class="means-box" v-if="stepActive === 2">
<el-form-item label="请选择营销资料">
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择使用营销资料" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</div>
</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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio :label="item.value" v-for="item in stepOneOptions">{{ item.label }}</el-radio>
</el-radio-group>
<!-- 第二步 -->
<el-select
placeholder="请选择关联使用钉钉"
style="width: 100%"
v-model="form.step_two_value"
v-if="stepActive === 1"
>
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
<!-- 第三步 -->
<div class="means-box" v-if="stepActive === 2">
<el-form-item label="请选择营销资料">
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择使用营销资料" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</div>
</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 @click="stepActive--" plain auto-insert-space v-if="stepActive !== 0">上一步</el-button>
<el-button @click="stepActive++" plain auto-insert-space v-if="stepActive < 2">下一步</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit" v-if="stepActive === 2">保存</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getGroupsList } 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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ group_id: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
// 获取群组列表
const groupsOption = ref([])
const getGroups = function () {
getGroupsList().then(res => {
groupsOption.value = res.data.items
})
}
onMounted(() => {
getGroups()
})
</script>
<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 :disabled="action === 'view'" 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>
<el-select style="width: 100%" v-model="form.group_id" placeholder="请选择用户群组">
<el-option :key="item.id" v-for="item in groupsOption" :value="item.id" :label="item.name"></el-option>
</el-select>
</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>
<el-select style="width: 100%" v-model="form.group_id" placeholder="请选择用户群组">
<el-option :key="item.id" v-for="item in groupsOption" :value="item.id" :label="item.name"></el-option>
</el-select>
</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getAttrList } from '@/api/flow'
import { CirclePlusFilled, RemoveFilled } from '@element-plus/icons-vue'
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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive([{ attr_id: '', attr_value: '' }])
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
// 获取群组列表
const attrOption = ref([])
const getAttr = function () {
getAttrList().then(res => {
attrOption.value = res.data.items
})
}
onMounted(() => {
getAttr()
})
// 添加属性
const handleAdd = function () {
form.push({ attr_id: '', attr_value: '' })
}
// 删除属性
const handleRemove = function (index) {
form.splice(index, 1)
}
</script>
<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 :disabled="action === 'view'" 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>
<div style="margin-bottom: 15px; display: flex; align-items: center" v-for="(forms, index) in form">
<el-select style="width: 130px" v-model="forms.attr_id" placeholder="请选择">
<el-option :key="item.id" v-for="item in attrOption" :value="item.id" :label="item.name"></el-option>
</el-select>
<span style="margin: 0 10px">=</span>
<el-input v-model="forms.attr_value" style="width: 200px" placeholder="请输入"></el-input>
<el-icon
v-if="form.length > 1"
style="margin-left: 10px"
size="20"
color="#cf5b78"
@click="handleRemove(index)"
><RemoveFilled
/></el-icon>
<el-icon
v-if="index === form.length - 1"
style="margin-left: 10px"
size="20"
color="#cf5b78"
@click="handleAdd"
><CirclePlusFilled
/></el-icon>
</div>
</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>
<div style="margin-bottom: 15px; display: flex; align-items: center" v-for="(forms, index) in form">
<el-select style="width: 130px" v-model="forms.attr_id" placeholder="请选择">
<el-option :key="item.id" v-for="item in attrOption" :value="item.id" :label="item.name"></el-option>
</el-select>
<span style="margin: 0 10px">=</span>
<el-input v-model="forms.attr_value" style="width: 200px" placeholder="请输入"></el-input>
<el-icon
v-if="form.length > 1"
style="margin-left: 10px"
size="20"
color="#cf5b78"
@click="handleRemove(index)"
><RemoveFilled
/></el-icon>
<el-icon
v-if="index === form.length - 1"
style="margin-left: 10px"
size="20"
color="#cf5b78"
@click="handleAdd"
><CirclePlusFilled
/></el-icon>
</div>
</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>
<!-- 定时触发 -->
<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 templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ date_type: '0', num: '', time_unit: '0', date: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
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">
<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 :disabled="action === 'view'" 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>
<el-radio-group v-model="form.date_type" style="display: block">
<el-radio label="0" size="large" style="display: block">
<span>延时 </span>
<el-input
:disabled="form.date_type !== '0'"
v-model="form.num"
placeholder="请输入"
class="input-with-select"
>
<template #append>
<el-select
:disabled="form.date_type !== '0'"
v-model="form.time_unit"
placeholder="请选择"
style="width: 115px"
>
<el-option label="分钟" value="0" />
<el-option label="小时" value="1" />
<el-option label="日" value="2" />
<el-option label="周" value="3" />
</el-select>
</template>
</el-input>
</el-radio>
<el-radio label="1" size="large" style="display: block">
<span>延时至 </span>
<el-date-picker
:disabled="form.date_type !== '1'"
v-model="form.date"
type="datetime"
placeholder="请选择"
/>
</el-radio>
</el-radio-group>
</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>
<el-radio-group v-model="form.date_type" style="display: block">
<el-radio label="0" size="large" style="display: block">
<span>延时 </span>
<el-input
:disabled="form.date_type !== '0'"
v-model="form.num"
placeholder="请输入"
class="input-with-select"
>
<template #append>
<el-select
:disabled="form.date_type !== '0'"
v-model="form.time_unit"
placeholder="请选择"
style="width: 115px"
>
<el-option label="分钟" value="0" />
<el-option label="小时" value="1" />
<el-option label="日" value="2" />
<el-option label="周" value="3" />
</el-select>
</template>
</el-input>
</el-radio>
<el-radio label="1" size="large" style="display: block">
<span>延时至 </span>
<el-date-picker
:disabled="form.date_type !== '1'"
v-model="form.date"
type="datetime"
placeholder="请选择"
/>
</el-radio>
</el-radio-group>
</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>
<!-- 定时触发 -->
<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 templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ content: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
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">
<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 :disabled="action === 'view'" 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>
<el-input v-model="form.content" :rows="3" type="textarea" placeholder="请输入" />
</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>
<el-input v-model="form.content" :rows="3" type="textarea" placeholder="请输入" />
</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>
<!-- 定时触发 -->
<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 templateType = inject('templateType')
onMounted(() => {
// 学生固定旅程吧组件置灰
if (templateType === '2' && role === 'student') {
Object.assign(form, props.node.data)
}
})
const { findNode } = useVueFlow()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ step_one_id: '0', content: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
const stepOneOptions = [{ label: '发送短信', value: '0' }]
// 步骤
let stepActive = ref(0)
</script>
<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 :disabled="action === 'view'" 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>
<el-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio style="width: 130px" :label="item.value" v-for="item in stepOneOptions">{{
item.label
}}</el-radio>
</el-radio-group>
<el-input v-if="stepActive === 1" v-model="form.content" :rows="3" type="textarea" placeholder="请输入" />
</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>
<el-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio style="width: 130px" :label="item.value" v-for="item in stepOneOptions">{{
item.label
}}</el-radio>
</el-radio-group>
<el-input v-if="stepActive === 1" v-model="form.content" :rows="3" type="textarea" placeholder="请输入" />
</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 @click="stepActive--" plain auto-insert-space v-if="stepActive !== 0">上一步</el-button>
<el-button @click="stepActive++" plain auto-insert-space v-if="stepActive < 1">下一步</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit" v-if="stepActive === 1">保存</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getConnectionList } from '@/api/flow'
import { useMapStore } from '@/stores/map'
import { getMaterialList } from '@/api/base'
const store = useMapStore()
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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ step_one_id: '0', step_two_value: '', material_type: '1', material_value: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
const stepOneOptions = [{ label: '发送邮件', value: '0' }]
const stepTwoOptions = ref()
onMounted(() => {
// 链接列表
getConnectionList({ type: '9' }).then(res => {
stepTwoOptions.value = res.data.list
})
changeMaterialType()
})
// 步骤
let stepActive = ref(0)
// 选择资料类型
let materiaList = ref([])
const changeMaterialType = function () {
form.material_value = ''
getMaterialList({ type: form.material_type }).then(res => {
materiaList.value = res.data.list
})
}
</script>
<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 :disabled="action === 'view'" 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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio style="width: 105px" :label="item.value" v-for="item in stepOneOptions">{{ item.label }}</el-radio>
</el-radio-group>
<!-- 第二步 -->
<el-select placeholder="请选择" style="width: 100%" v-model="form.step_two_value" v-if="stepActive === 1">
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
<!-- 第三步 -->
<div class="means-box" v-if="stepActive === 2">
<el-form-item label="请选择营销资料">
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择使用营销资料" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</div>
</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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio style="width: 105px" :label="item.value" v-for="item in stepOneOptions">{{
item.label
}}</el-radio>
</el-radio-group>
<!-- 第二步 -->
<el-select placeholder="请选择" style="width: 100%" v-model="form.step_two_value" v-if="stepActive === 1">
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
<!-- 第三步 -->
<div class="means-box" v-if="stepActive === 2">
<el-form-item label="请选择使用营销资料类型">
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择使用营销资料" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</div>
</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 @click="stepActive--" plain auto-insert-space v-if="stepActive !== 0">上一步</el-button>
<el-button @click="stepActive++" plain auto-insert-space v-if="stepActive < 2">下一步</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit" v-if="stepActive === 2">保存</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getConnectionList } from '@/api/flow'
import { useMapStore } from '@/stores/map'
import { getMaterialList } from '@/api/base'
const store = useMapStore()
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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ step_one_id: '0', step_two_value: '', material_type: '1', material_value: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
const stepOneOptions = [{ label: '发送邮件', value: '0' }]
const stepTwoOptions = ref()
onMounted(() => {
// 链接列表
getConnectionList({ type: '1' }).then(res => {
stepTwoOptions.value = res.data.list
})
changeMaterialType()
})
// 步骤
let stepActive = ref(0)
// 选择资料类型
let materiaList = ref([])
const changeMaterialType = function () {
form.material_value = ''
getMaterialList({ type: form.material_type }).then(res => {
materiaList.value = res.data.list
})
}
</script>
<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 :disabled="action === 'view'" 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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-form-item>
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>发送{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择资料内容" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</el-radio-group>
<!-- 第二步 -->
<el-select placeholder="请选择公众号" style="width: 100%" v-model="form.step_two_value" v-if="stepActive === 1">
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
</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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-form-item>
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>发送{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择资料内容" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</el-radio-group>
<!-- 第二步 -->
<el-select
placeholder="请选择公众号"
style="width: 100%"
v-model="form.step_two_value"
v-if="stepActive === 1"
>
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
</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 @click="stepActive--" plain auto-insert-space v-if="stepActive !== 0">上一步</el-button>
<el-button @click="stepActive++" plain auto-insert-space v-if="stepActive < 1">下一步</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit" v-if="stepActive === 1">保存</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>
<!-- 定时触发 -->
<script setup>
import { useVueFlow } from '@vue-flow/core'
import NodeTemplate from '../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
import { getConnectionList } from '@/api/flow'
import { useMapStore } from '@/stores/map'
import { getMaterialList } from '@/api/base'
const store = useMapStore()
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()
// 设置
const settingVisible = ref(false)
const formRef = ref()
const form = reactive({ step_one_id: '0', step_two_value: '', material_type: '1', material_value: '' })
watch(settingVisible, () => {
if (props.node) Object.assign(form, props.node.data)
})
const rules = ref({
score: [{ required: true, message: '请输入' }]
})
// 保存
function handleSubmit() {
formRef.value.validate().then(() => {
form.isEdit = true
updateNode()
settingVisible.value = false
stepActive.value = 0
})
}
function updateNode() {
const node = findNode(props.node.id)
if (node) Object.assign(node.data, form)
}
function handleClosed() {
formRef.value.resetFields()
}
const stepOneOptions = [
{ label: '向用户发送文本私信', value: '0' },
{ label: '向用户发送图片私信', value: '1' },
{ label: '向用户发送视频私信', value: '2' }
]
const stepTwoOptions = ref()
onMounted(() => {
// 链接列表
getConnectionList({ type: '6' }).then(res => {
stepTwoOptions.value = res.data.list
})
changeMaterialType()
})
// 步骤
let stepActive = ref(0)
// 选择资料类型
let materiaList = ref([])
const changeMaterialType = function () {
form.material_value = ''
getMaterialList({ type: form.material_type }).then(res => {
materiaList.value = res.data.list
})
}
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="square" color="#19AAA5" w="60" h="60"></Icon>
<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=":">
<!-- 学生设置组件 -->
<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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio :label="item.value" v-for="item in stepOneOptions">{{ item.label }}</el-radio>
</el-radio-group>
<!-- 第二步 -->
<el-select
placeholder="请选择关联使用抖音"
style="width: 100%"
v-model="form.step_two_value"
v-if="stepActive === 1"
>
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
<!-- 第三步 -->
<div class="means-box" v-if="stepActive === 2">
<el-form-item label="请选择营销资料">
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择使用营销资料" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</div>
</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-radio-group v-model="form.step_one_id" v-if="stepActive === 0">
<el-radio :label="item.value" v-for="item in stepOneOptions">{{ item.label }}</el-radio>
</el-radio-group>
<!-- 第二步 -->
<el-select
placeholder="请选择关联使用抖音"
style="width: 100%"
v-model="form.step_two_value"
v-if="stepActive === 1"
>
<el-option v-for="item in stepTwoOptions" :value="item.id" :label="item.type_name"></el-option>
</el-select>
<!-- 第三步 -->
<div class="means-box" v-if="stepActive === 2">
<el-form-item label="请选择营销资料">
<el-radio-group @change="changeMaterialType" v-model="form.material_type">
<el-radio
style="width: 105px"
:label="item.value"
v-for="item in store.getMapValuesByKey('experiment_marketing_material_type')"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="营销资料">
<el-select placeholder="请选择使用营销资料" v-model="form.material_value" style="width: 100%">
<el-option :value="item.id" :label="item.name" v-for="item in materiaList"></el-option>
</el-select>
</el-form-item>
</div>
</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 @click="stepActive--" plain auto-insert-space v-if="stepActive !== 0">上一步</el-button>
<el-button @click="stepActive++" plain auto-insert-space v-if="stepActive < 2">下一步</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit" v-if="stepActive === 2">保存</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>
<script setup lang="ts">
import { CirclePlusFilled, RemoveFilled } from '@element-plus/icons-vue'
import ConfigTemplate from '../../ConfigTemplate.vue'
import { useUserAttr } from '../../../useAllData'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
rules: [{ attr_id: '', operate: '=', value: '' }]
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const { userAttrList } = useUserAttr()
function addRule() {
form.rules.push({ attr_id: '', operate: '=', value: '' })
}
function removeRule(index: number) {
form.rules.splice(index, 1)
}
</script>
<template>
<ConfigTemplate :model="form" :node="node">
<el-form-item v-for="(rule, index) in form.rules" :key="index">
<el-row justify="center" align="middle">
<el-select v-model="rule.attr_id" placeholder="请选择属性" style="width: 130px">
<el-option :key="item.id" v-for="item in userAttrList" :value="item.id" :label="item.name"></el-option>
</el-select>
<el-button style="margin: 0 10px">=</el-button>
<el-input v-model="rule.value" placeholder="请输入" style="width: 200px"></el-input>
<el-icon style="margin-left: 10px" size="20" color="#cf5b78" @click="removeRule(index)" v-if="index !== 0">
<RemoveFilled />
</el-icon>
<el-icon
style="margin-left: 10px"
size="20"
color="#cf5b78"
@click="addRule"
v-if="index === form.rules.length - 1">
<CirclePlusFilled />
</el-icon>
</el-row>
</el-form-item>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 变更属性 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="square" :color="isGray ? '#9a9a9a' : '#19AAA5'" w="60" h="60"></Icon>
<Icon class="icon" name="15" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import ConfigTemplate from '../../ConfigTemplate.vue'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
time_type: '0',
time_num: '',
time_unit: '0',
time: ''
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const timeUnitList = ref([
{ label: '分钟', value: '0' },
{ label: '小时', value: '1' },
{ label: '日', value: '2' },
{ label: '周', value: '3' }
])
</script>
<template>
<ConfigTemplate :model="form" :node="node">
<el-form-item>
<el-radio-group v-model="form.time_type" style="display: block">
<el-radio label="0" size="large" style="display: block">
<span>延时 </span>
<el-input
:disabled="form.time_type !== '0'"
v-model="form.time_num"
placeholder="请输入"
class="input-with-select">
<template #append>
<el-select
v-model="form.time_unit"
placeholder="请选择"
style="width: 115px"
:disabled="form.time_type !== '0'">
<el-option v-for="item in timeUnitList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
</el-input>
</el-radio>
<el-radio label="1" size="large" style="display: block">
<span>延时至 </span>
<el-date-picker :disabled="form.time_type !== '1'" v-model="form.time" type="datetime" placeholder="请选择" />
</el-radio>
</el-radio-group>
</el-form-item>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 延时处理 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="square" :color="isGray ? '#9a9a9a' : '#19AAA5'" w="60" h="60"></Icon>
<Icon class="icon" name="18" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import ConfigTemplate from '../../ConfigTemplate.vue'
import { useMaterial, useConnection } from '../../../useAllData'
import { useMapStore } from '@/stores/map'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
operate: '',
material_type: '',
material_id: '',
connection_id: ''
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const operateList = ref([{ label: '发送消息', value: '0' }])
const materialTypeList = useMapStore().getMapValuesByKey('experiment_marketing_material_type')
const { materialList } = useMaterial()
const { connectionList } = useConnection()
</script>
<template>
<ConfigTemplate :model="form" :node="node" :stepNum="2">
<template #default="{ step }: { step: number }">
<template v-if="step === 0">
<el-form-item>
<el-radio-group v-model="form.operate" v-if="step === 0">
<el-radio v-for="item in operateList" :key="item.value" :label="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</template>
<template v-else-if="step === 1">
<el-form-item>
<el-select placeholder="请选择" style="width: 100%" v-model="form.connection_id">
<el-option v-for="item in connectionList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</template>
<template v-else-if="step === 2">
<el-form-item>
<el-radio-group v-model="form.material_type">
<el-radio v-for="item in materialTypeList" :key="item.id" :label="item.value" style="width: 105px">
发送{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-select placeholder="请选择资料内容" v-model="form.material_id" style="width: 100%">
<el-option v-for="item in materialList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</template>
</template>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 公众号 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="square" :color="isGray ? '#9a9a9a' : '#19AAA5'" w="60" h="60"></Icon>
<Icon class="icon" name="2" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import ConfigTemplate from '../../ConfigTemplate.vue'
import { useMaterial, useConnection } from '../../../useAllData'
import { useMapStore } from '@/stores/map'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
operate: '',
material_type: '',
material_id: '',
connection_id: ''
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const operateList = ref([
{ label: '向用户发送文本私信', value: '0' },
{ label: '向用户发送图片私信', value: '1' },
{ label: '向用户发送视频私信', value: '2' }
])
const materialTypeList = useMapStore().getMapValuesByKey('experiment_marketing_material_type')
const { materialList } = useMaterial()
const { connectionList } = useConnection()
</script>
<template>
<ConfigTemplate :model="form" :node="node" :stepNum="2">
<template #default="{ step }: { step: number }">
<template v-if="step === 0">
<el-form-item>
<el-radio-group v-model="form.operate" v-if="step === 0">
<el-radio v-for="item in operateList" :key="item.value" :label="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</template>
<template v-else-if="step === 1">
<el-form-item>
<el-select placeholder="请选择" style="width: 100%" v-model="form.connection_id">
<el-option v-for="item in connectionList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</template>
<template v-else-if="step === 2">
<el-form-item>
<el-radio-group v-model="form.material_type">
<el-radio v-for="item in materialTypeList" :key="item.id" :label="item.value" style="width: 105px">
发送{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-select placeholder="请选择资料内容" v-model="form.material_id" style="width: 100%">
<el-option v-for="item in materialList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</template>
</template>
</ConfigTemplate>
</template>
<script setup lang="ts">
import ConfigViewTemplate from '../../ConfigViewTemplate.vue'
defineProps<{ node: any }>()
</script>
<template>
<ConfigViewTemplate :node="node">
<el-form-item label="学生答案"> </el-form-item>
<el-form-item label="正确答案"> </el-form-item>
</ConfigViewTemplate>
</template>
<!-- 公众号 -->
<script setup lang="ts">
import NodeTemplate from '../../NodeTemplate.vue'
import Icon from '@/components/ConnectionIcon.vue'
const Config = defineAsyncComponent(() => import('./Config.vue'))
const ConfigView = defineAsyncComponent(() => import('./ConfigView.vue'))
const props = defineProps<{ node: any }>()
const action = inject('action') as string
const role = inject('role') as string
const templateType = inject('templateType') as string
// 是否置灰
const isGray = computed(() => {
return templateType === '2' && role === 'student' && action === 'edit' && !props.node.data[role]
})
// 设置
const settingVisible = ref(false)
</script>
<template>
<NodeTemplate :node="node" @setting="settingVisible = true">
<div class="node-item">
<Icon name="square" :color="isGray ? '#9a9a9a' : '#19AAA5'" w="60" h="60"></Icon>
<Icon class="icon" name="6" color="#fff" w="24" h="24"></Icon>
</div>
</NodeTemplate>
<!-- 配置 -->
<Config v-model="settingVisible" :node="node" v-if="settingVisible && action === 'edit'" />
<!-- 查看配置 -->
<ConfigView v-model="settingVisible" :node="node" v-if="settingVisible && action === 'view'" />
</template>
<script setup lang="ts">
import ConfigTemplate from '../../ConfigTemplate.vue'
import { useMaterial, useConnection } from '../../../useAllData'
import { useMapStore } from '@/stores/map'
const props = defineProps<{ node: any }>()
const role = inject('role') as string
const form = reactive({
operate: '',
material_type: '',
material_id: '',
connection_id: ''
})
watchEffect(() => {
Object.assign(form, props.node.data[role])
})
const operateList = ref([{ label: '发送邮件', value: '0' }])
const materialTypeList = useMapStore().getMapValuesByKey('experiment_marketing_material_type')
const { materialList } = useMaterial()
const { connectionList } = useConnection()
</script>
<template>
<ConfigTemplate :model="form" :node="node" :stepNum="2">
<template #default="{ step }: { step: number }">
<template v-if="step === 0">
<el-form-item>
<el-radio-group v-model="form.operate" v-if="step === 0">
<el-radio v-for="item in operateList" :key="item.value" :label="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</template>
<template v-else-if="step === 1">
<el-form-item>
<el-select placeholder="请选择" style="width: 100%" v-model="form.connection_id">
<el-option v-for="item in connectionList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</template>
<template v-else-if="step === 2">
<el-form-item>
<el-radio-group v-model="form.material_type">
<el-radio v-for="item in materialTypeList" :key="item.id" :label="item.value" style="width: 105px">
发送{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-select placeholder="请选择资料内容" v-model="form.material_id" style="width: 100%">
<el-option v-for="item in materialList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</template>
</template>
</ConfigTemplate>
</template>
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论