提交 0dfd43a6 authored 作者: 王鹏飞's avatar 王鹏飞

chore: 修改标签管理和群组管理

上级 202fa072
......@@ -56,8 +56,27 @@
.rule-item {
margin: 10px 0;
}
.event-rule {
.event-rule,
.user-action-rule {
section + section {
margin-top: 30px;
}
}
.rule-tips {
color: #999;
margin-bottom: 10px;
display: flex;
align-items: center;
.el-icon {
margin-right: 5px;
color: var(--main-color);
}
}
.rule-tag {
margin-right: 10px;
}
.rule-input {
width: 100px;
}
<script setup lang="ts">
import { Warning } from '@element-plus/icons-vue'
import EventRule from './EventRule.vue'
import { useMetaEvent } from '@/composables/useAllData'
const { metaEventList } = useMetaEvent()
const eventAttrRule = defineModel<any>({
default: () => ({
event_attr_rule: {
current_logic_operate: 'and',
happen_info: { is_happened: true, event_id: '-1', event_name: '所有事件', attr_list: [] },
trigger_info: { operate: '', operate_name: '', value: '' }
},
tag_rule: { event_id: '', event_name: '', attr_id: '', attr_name: '', type: 1, value: undefined }
})
})
const form: any = reactive({
event_attr_rule: {
current_logic_operate: 'and',
items: [
{
happen_info: { is_happened: true, event_id: '-1', event_name: '所有事件', attr_list: [] },
trigger_info: { operate: '', operate_name: '', value: undefined }
}
]
},
tag_rule: { event_id: '', event_name: '', attr_id: '', attr_name: '', type: 1, value: '' }
})
const { current_logic_operate, ...rest } = eventAttrRule.value.event_attr_rule
Object.assign(form, { tag_rule: eventAttrRule.value.tag_rule, event_attr_rule: { current_logic_operate, items: [rest] } })
const first = computed(() => form.event_attr_rule.items[0])
watch(
form,
() => {
eventAttrRule.value = {
event_attr_rule: { current_logic_operate: form.event_attr_rule.current_logic_operate, ...first.value },
tag_rule: form.tag_rule
}
},
{ deep: true }
)
watch(
() => first.value.happen_info.event_id,
() => {
form.tag_rule.event_id = first.value.happen_info.event_id
form.tag_rule.event_name = first.value.happen_info.event_name
form.tag_rule.attr_id = ''
form.tag_rule.attr_name = ''
}
)
// 获取事件属性列表
function getEventAttrList(eventId: string) {
return metaEventList.value.find(item => item.id === eventId)?.event_attrs || []
}
function handleAttrChange(value: string) {
const found = getEventAttrList(form.tag_rule.event_id).find(item => item.id === value)
form.tag_rule.attr_name = found?.name
}
</script>
<template>
<p class="rule-tips">
<el-icon><Warning /></el-icon>
事件偏好标签:将事件按照某个规则分组排序,使用排名前几个的事件属性作为用户标签值。
</p>
<!-- 事件属性规则 -->
<EventRule :limit="1" v-model="form.event_attr_rule" style="margin-top: 20px">
<template #footer>
<el-row align="middle" style="margin-top: 10px" v-if="first.happen_info.event_id">
<p></p>
<el-button type="info" style="margin: 0 10px">{{ form.tag_rule.event_name }}</el-button>
<el-select v-model="form.tag_rule.attr_id" style="width: 110px" @change="handleAttrChange">
<el-option v-for="option in getEventAttrList(form.tag_rule.event_id)" :key="option.id" :label="option.name" :value="option.id"></el-option>
</el-select>
<el-button type="info" style="margin: 0 10px">出现次数最多</el-button>
<p></p>
<el-input-number v-model="form.tag_rule.value" style="margin: 0 10px; width: 60px" :controls="false"></el-input-number>
<p></p>
<el-button type="info" style="margin: 0 10px">{{ form.tag_rule.attr_name }}</el-button>
<p>作为用户标签</p>
</el-row>
</template>
</EventRule>
</template>
<style src="@/assets/styles/rule.scss"></style>
......@@ -5,7 +5,10 @@ import { useMetaEvent } from '@/composables/useAllData'
import { stringOperatorList, numberOperatorList, dateOperatorList, happenInfoList, triggerInfoList } from '@/utils/dictionary'
import { searchEventAttrs } from '@/api/base'
const eventAttrRule = ref(inject('eventAttrRule') as EventRule)
const { limit = Infinity } = defineProps<{ limit?: number }>()
// const eventAttrRule = ref(inject('eventAttrRule') as EventRule)
const eventAttrRule = defineModel<EventRule>({ default: { current_logic_operate: 'and', items: [] } })
const { metaEventList } = useMetaEvent()
......@@ -72,7 +75,7 @@ function handleHappenOperateChange(value: string, item: EventRuleItem) {
// 事件改变
function handleEventChange(value: string, item: EventRuleItem) {
const currentEvent = metaEventList.value.find(item => item.id === value)
const currentEvent = currentMetaEventList.value.find(item => item.id === value)
item.happen_info.event_name = currentEvent?.name || ''
item.happen_info.attr_list = []
}
......@@ -173,7 +176,7 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
</el-select>
</el-form-item>
<el-button text :icon="Plus" @click="handleAttrAdd(rule.happen_info.attr_list)">添加条件</el-button>
<el-button text :icon="CloseBold" @click="handleRemove(eventAttrRule.items, index)"></el-button>
<el-button text :icon="CloseBold" @click="handleRemove(eventAttrRule.items, index)" v-if="limit !== 1"></el-button>
</el-row>
<!-- 属性条件 -->
<el-row justify="space-between" class="rule-item" v-for="(attr, index) in rule.happen_info.attr_list" :key="index">
......@@ -185,7 +188,11 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
</el-form-item>
<el-form-item>
<el-select v-model="attr.operate" @change="value => handleOperateChange(value, attr)">
<el-option v-for="option in getOperatorList(attr.attr_type)" :key="option.value" :label="option.alias || option.label" :value="option.value"></el-option>
<el-option
v-for="option in getOperatorList(attr.attr_type)"
:key="option.value"
:label="option.alias || option.label"
:value="option.value"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="!['null', 'not null'].includes(attr.operate)">
......@@ -248,7 +255,8 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
</section>
</div>
</div>
<el-button text :icon="Plus" @click="handleAdd(eventAttrRule.items)">添加条件</el-button>
<el-button text :icon="Plus" @click="handleAdd(eventAttrRule.items)" v-if="eventAttrRule.items.length < limit">添加条件</el-button>
<slot name="footer"></slot>
</el-card>
</template>
......
<script setup lang="ts">
import { Warning } from '@element-plus/icons-vue'
import EventRule from './EventRule.vue'
import { wayList } from '@/utils/dictionary'
const eventAttrRule = defineModel<any>({
default: () => ({
event_attr_rule: {
current_logic_operate: 'and',
happen_info: { is_happened: true, event_id: '-1', event_name: '所有事件', attr_list: [] },
trigger_info: { operate: '', operate_name: '', value: '' }
},
tag_rule: { way: '' }
})
})
const form: any = reactive({
event_attr_rule: {
current_logic_operate: 'and',
items: [
{
happen_info: { is_happened: true, event_id: '-1', event_name: '所有事件', attr_list: [] },
trigger_info: { operate: '', operate_name: '', value: '' }
}
]
},
tag_rule: { way: '' }
})
const { current_logic_operate, ...rest } = eventAttrRule.value.event_attr_rule
Object.assign(form, { tag_rule: eventAttrRule.value.tag_rule, event_attr_rule: { current_logic_operate, items: [rest] } })
const first = computed(() => form.event_attr_rule.items[0])
watch(
form,
() => {
eventAttrRule.value = {
event_attr_rule: { current_logic_operate: form.event_attr_rule.current_logic_operate, ...first.value },
tag_rule: form.tag_rule
}
},
{ deep: true }
)
</script>
<template>
<p class="rule-tips">
<el-icon><Warning /></el-icon>
事件指标标签:将事件指标作为用户的标签。
</p>
<!-- 事件属性规则 -->
<EventRule :limit="1" v-model="form.event_attr_rule" style="margin-top: 20px">
<template #footer>
<el-row align="middle" style="margin-top: 10px" v-if="first.happen_info.event_id">
<p></p>
<el-button type="info" style="margin: 0 10px">{{ first.happen_info.event_name }}</el-button>
<el-select v-model="form.tag_rule.way" style="margin-right: 10px; width: 130px">
<el-option v-for="item in wayList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<p>作为用户标签</p>
</el-row>
</template>
</EventRule>
</template>
<style src="@/assets/styles/rule.scss"></style>
......@@ -3,7 +3,8 @@ import type { TagRule } from '@/types'
import { PriceTag, Plus, CloseBold } from '@element-plus/icons-vue'
import { useTag } from '@/composables/useAllData'
const tagRule = ref(inject('tagRule') as TagRule)
// const tagRule = ref(inject('tagRule') as TagRule)
const tagRule = defineModel<TagRule>({ default: { current_logic_operate: 'and', items: [] } })
const { tagList } = useTag()
......@@ -44,11 +45,7 @@ function handleRemove(items: string[], index: number) {
标签 等于
<el-form-item>
<el-select v-model="tagRule.items[index]">
<el-option
v-for="option in tagList"
:key="option.id"
:label="option.name"
:value="option.id"></el-option>
<el-option v-for="option in tagList" :key="option.id" :label="option.name" :value="option.id"></el-option>
</el-select>
</el-form-item>
</div>
......
<script setup lang="ts">
import { Warning } from '@element-plus/icons-vue'
import { ElInput } from 'element-plus'
import UserRule from '@/components/rule/UserRule.vue'
import EventRule from '@/components/rule/EventRule.vue'
import UserActionRule from '@/components/rule/UserActionRule.vue'
const rules = defineModel<Array<any>>({ default: [] })
const inputValue = ref('')
const inputVisible = ref(false)
const InputRef = ref<InstanceType<typeof ElInput>>()
const activeIndex = ref(0)
const handleClose = (index: number) => {
rules.value.splice(index, 1)
activeIndex.value = 0
}
const showInput = () => {
inputVisible.value = true
nextTick(() => {
InputRef.value!.input!.focus()
})
}
const handleInputConfirm = () => {
if (inputValue.value) {
rules.value.push({
level: rules.value.length,
level_name: inputValue.value,
user_attr_rule: { current_logic_operate: 'and', items: [] },
event_attr_rule: { current_logic_operate: 'and', items: [] },
user_action_rule: { current_logic_operate: 'and', items: [] }
})
activeIndex.value = rules.value.length - 1
}
inputVisible.value = false
inputValue.value = ''
}
</script>
<template>
<p class="rule-tips">
<el-icon><Warning /></el-icon>
自定义分层标签:将满足不同分层规则的用户打上分层标签,同一用户会被优先匹配在顺序靠前的分层
</p>
<div>
<el-tag
class="rule-tag"
v-for="(rule, index) in rules"
size="large"
effect="light"
:type="index !== activeIndex ? 'info' : ''"
:key="rule.level"
closable
:disable-transitions="false"
@close="handleClose(index)"
@click="activeIndex = index">
{{ rule.level_name }}
</el-tag>
<el-input v-model="inputValue" class="rule-input" ref="InputRef" @keyup.enter="handleInputConfirm" @blur="handleInputConfirm" v-if="inputVisible" />
<el-button v-else style="width: 100px" @click="showInput"> + 添加分层 </el-button>
</div>
<template v-if="rules.length">
<!-- 用户属性规则 -->
<UserRule v-model="rules[activeIndex].user_attr_rule" style="margin-top: 20px"></UserRule>
<!-- 事件属性规则 -->
<EventRule v-model="rules[activeIndex].event_attr_rule" style="margin-top: 20px"></EventRule>
<!-- 用户行为序列规则 -->
<UserActionRule v-model="rules[activeIndex].user_action_rule" style="margin-top: 20px"></UserActionRule>
</template>
</template>
<style src="@/assets/styles/rule.scss"></style>
<script setup lang="ts">
import type { UserActionRule, UserActionRuleItem, RuleEvent, RuleAttr } from '@/types'
import { Paperclip, Plus, CloseBold } from '@element-plus/icons-vue'
import { useMetaEvent } from '@/composables/useAllData'
import { stringOperatorList, numberOperatorList, dateOperatorList } from '@/utils/dictionary'
import { searchEventAttrs } from '@/api/base'
// const userActionRule = ref(inject('userActionRule') as UserActionRule)
const userActionRule = defineModel<UserActionRule>({ default: { current_logic_operate: 'and', items: [] } })
const { metaEventList } = useMetaEvent()
const currentMetaEventList = computed(() => {
return [{ id: '-1', name: '所有事件', event_attrs: [] }, ...metaEventList.value]
})
// 获取逻辑运算符名称
function getLogicalName(value: 'and' | 'or') {
return value === 'or' ? '或' : '且'
}
// 获取运算符列表
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 getEventAttrList(eventId: string) {
return currentMetaEventList.value.find(item => item.id === eventId)?.event_attrs || []
}
// 切换逻辑运算符
function toggleOperate(rule: UserActionRule) {
rule.current_logic_operate = rule.current_logic_operate === 'or' ? 'and' : 'or'
}
// 添加条件
function handleAdd(items: UserActionRuleItem[]) {
items.push({ operate: '', operate_name: '', value: '', event_list: [] })
}
// 删除条件
function handleRemove(items: UserActionRuleItem[], index: number) {
items.splice(index, 1)
}
// 添加事件
function handleEventAdd(events: RuleEvent[]) {
events.push({ event_id: '', event_name: '', attr_list: [] })
}
// 删除事件条件
function handleEventRemove(events: RuleEvent[], index: number) {
events.splice(index, 1)
}
// 添加属性条件
function handleAttrAdd(attrs: RuleAttr[]) {
attrs.push({ attr_id: '', attr: '', attr_name: '', attr_type: '', operate: '', operate_name: '', value: '' })
}
// 删除属性条件
function handleAttrRemove(attrs: RuleAttr[], index: number) {
attrs.splice(index, 1)
}
// 发生条件改变
function handleHappenOperateChange(value: string, item: UserActionRuleItem) {
const found = dateOperatorList.find(item => item.value === value)
item.operate_name = found?.label || ''
item.value = ''
}
// 事件改变
function handleEventChange(value: string, event: RuleEvent) {
const currentEvent = metaEventList.value.find(item => item.id === value)
event.event_name = currentEvent?.name || ''
event.attr_list = []
}
// 属性改变
function handleAttrChange(value: string, attr: RuleAttr, event: RuleEvent) {
const found = getEventAttrList(event.event_id).find(item => item.id === value)
attr.attr = found?.english_name || ''
attr.attr_name = found?.name || ''
attr.attr_type = found?.type || ''
// 清空条件数据
attr.operate = ''
attr.operate_name = ''
attr.value = ''
}
// 条件改变
function handleOperateChange(value: string, item: RuleAttr) {
const found = getOperatorList(item.attr_type).find(item => item.value === value)
item.operate_name = found?.label || ''
item.value = ''
// 区间
if (value === 'range') {
item.value = { start: undefined, end: undefined }
}
}
function querySearch(event: RuleEvent, attr: RuleAttr, search: string, cb: (arg: any) => void) {
const found = getEventAttrList(event.event_id).find(item => item.id === attr.attr_id)
const experiment_meta_event_id = found?.experiment_meta_event_id || ''
searchEventAttrs({ search, experiment_meta_event_id: experiment_meta_event_id, experiment_meta_event_attr_id: attr.attr_id, per_page: 1000 }).then(res => {
const list: string[] = []
res.data.list.forEach((item: any) => {
try {
const fields = JSON.parse(item.fields)
const value = fields[attr.attr_id]
if (!list.includes(value)) list.push(value)
} catch (error) {
console.log(error)
}
})
cb(list.map((item: string) => ({ value: item })))
})
}
const options = ref<{ label: string; value: string }[]>([])
const loading = ref(false)
function remoteMethod(event: RuleEvent, attr: RuleAttr, search: string) {
const found = getEventAttrList(event.event_id).find(item => item.id === attr.attr_id)
const experiment_meta_event_id = found?.experiment_meta_event_id || ''
loading.value = true
searchEventAttrs({ search, experiment_meta_event_id: experiment_meta_event_id, experiment_meta_event_attr_id: attr.attr_id, per_page: 1000 }).then(res => {
const list: string[] = []
res.data.list.forEach((item: any) => {
try {
const fields = JSON.parse(item.fields)
const value = fields[attr.attr_id]
if (!list.includes(value)) list.push(value)
} catch (error) {
console.log(error)
}
})
options.value = list.map((item: string) => ({ value: item, label: item }))
loading.value = false
})
}
</script>
<template>
<el-card shadow="never" class="user-action-rule">
<template #header>
<el-button circle color="#67c23a" :icon="Paperclip"></el-button>
用户行为序列满足以下条件
</template>
<div class="rule" v-if="userActionRule.items.length">
<div class="rule-operator">
<span @click="toggleOperate(userActionRule)">{{ getLogicalName(userActionRule.current_logic_operate) }}</span>
</div>
<div class="rule-list">
<section class="rule-item" v-for="(rule, index) in userActionRule.items" :key="index">
<el-row align="middle">
<!-- 发生 -->
<el-form-item>
<el-select v-model="rule.operate" @change="value => handleHappenOperateChange(value, rule)">
<el-option v-for="option in dateOperatorList" :key="option.label" v-bind="option"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<template v-if="rule.operate === 'after' || rule.operate === 'before'">
<el-date-picker v-model="rule.value" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
</template>
<el-input v-model="rule.value" v-else />
</el-form-item>
<p style="margin-right: 10px">依次发生过</p>
<el-button text :icon="Plus" @click="handleEventAdd(rule.event_list)">添加条件</el-button>
<el-button text :icon="CloseBold" @click="handleRemove(userActionRule.items, index)"></el-button>
</el-row>
<div class="rule-item" v-for="(event, index) in rule.event_list" :key="index" style="margin: 15px 0">
<el-form-item>
<el-select v-model="event.event_id" @change="value => handleEventChange(value, event)">
<el-option v-for="option in currentMetaEventList" :key="option.id" :label="option.name" :value="option.id"></el-option>
</el-select>
</el-form-item>
<el-button text :icon="Plus" @click="handleAttrAdd(event.attr_list)">添加条件</el-button>
<el-button text :icon="CloseBold" @click="handleEventRemove(rule.event_list, index)"></el-button>
<!-- 属性条件 -->
<el-row justify="space-between" class="rule-item" v-for="(attr, index) in event.attr_list" :key="index">
<div>
<el-form-item>
<el-select v-model="attr.attr_id" @change="value => handleAttrChange(value, attr, event)">
<el-option v-for="option in getEventAttrList(event.event_id)" :key="option.id" :label="option.name" :value="option.id"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="attr.operate" @change="value => handleOperateChange(value, attr)">
<el-option
v-for="option in getOperatorList(attr.attr_type)"
:key="option.value"
:label="option.alias || option.label"
:value="option.value"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="!['null', 'not null'].includes(attr.operate)">
<!-- 数字区间 -->
<template v-if="['2', '3'].includes(attr.attr_type) && attr.operate === 'range'">
<el-input-number step-strictly :controls="false" :min="0" v-model="attr.value.start" />
<el-input-number step-strictly :controls="false" :min="0" v-model="attr.value.end" />
</template>
<!-- 日期区间 -->
<template v-else-if="attr.attr_type === '4' && attr.operate === 'range'">
<el-date-picker v-model="attr.value.start" type="date" value-format="YYYY-MM-DD" />
<el-date-picker v-model="attr.value.end" type="date" value-format="YYYY-MM-DD" />
</template>
<!-- 时间区间 -->
<template v-else-if="attr.attr_type === '5' && attr.operate === 'range'">
<el-date-picker v-model="attr.value.start" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
<el-date-picker v-model="attr.value.end" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
</template>
<template v-else-if="attr.attr_type === '4' && (attr.operate === 'after' || attr.operate === 'before')">
<el-date-picker v-model="attr.value" type="date" value-format="YYYY-MM-DD" />
</template>
<template v-else-if="attr.attr_type === '5' && (attr.operate === 'after' || attr.operate === 'before')">
<el-date-picker v-model="attr.value" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
</template>
<template v-else>
<el-select
v-model="attr.value"
filterable
remote
allow-create
multiple
:remote-method="(query:string) => remoteMethod(event, attr, query)"
:loading="loading"
style="width: 320px"
v-if="['in', 'not in'].includes(attr.operate)">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-autocomplete v-model="attr.value" :fetch-suggestions="(query, cb) => querySearch(event, attr, query, cb)" style="width: 320px" v-else />
</template>
</el-form-item>
</div>
<el-button text :icon="CloseBold" @click="handleAttrRemove(event.attr_list, index)"></el-button>
</el-row>
</div>
</section>
</div>
</div>
<el-button text :icon="Plus" @click="handleAdd(userActionRule.items)">添加条件</el-button>
</el-card>
</template>
<style src="@/assets/styles/rule.scss"></style>
......@@ -5,7 +5,8 @@ import { useUserAttr } from '@/composables/useAllData'
import { stringOperatorList, numberOperatorList, dateOperatorList } from '@/utils/dictionary'
import { searchMetaMemberAttrs } from '@/api/base'
const userAttrRule = ref(inject('userAttrRule') as UserAttrRule)
// const userAttrRule = ref(inject('userAttrRule') as UserAttrRule)
const userAttrRule = defineModel<UserAttrRule>({ default: { current_logic_operate: 'and', items: [] } })
const { userAttrList } = useUserAttr()
......@@ -107,17 +108,16 @@ function remoteMethod(item: RuleAttr, search: string = '') {
</el-form-item>
<el-form-item>
<el-select v-model="item.operate" @change="value => handleOperateChange(value, item)">
<el-option v-for="option in getOperatorList(item.attr_type)" :key="option.value" :label="option.alias || option.label" :value="option.value"></el-option>
<el-option
v-for="option in getOperatorList(item.attr_type)"
:key="option.value"
:label="option.alias || option.label"
:value="option.value"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="!['null', 'not null'].includes(item.operate)">
<!-- 数字区间 -->
<template v-if="['2', '3'].includes(item.attr_type) && item.operate === 'range'">
<el-input-number step-strictly :controls="false" :min="0" v-model="item.value.start" />
<el-input-number step-strictly :controls="false" :min="0" v-model="item.value.end" />
</template>
<!-- 日期区间 -->
<template v-else-if="item.attr_type === '4' && item.operate === 'range'">
<template v-if="item.attr_type === '4' && item.operate === 'range'">
<el-date-picker v-model="item.value.start" type="date" value-format="YYYY-MM-DD" />
<el-date-picker v-model="item.value.end" type="date" value-format="YYYY-MM-DD" />
</template>
......@@ -145,7 +145,12 @@ function remoteMethod(item: RuleAttr, search: string = '') {
v-if="['in', 'not in'].includes(item.operate)">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-autocomplete v-model="item.value" value-key="attr_value" :fetch-suggestions="(query, cb) => querySearch(item, query, cb)" style="width: 320px" v-else />
<el-autocomplete
v-model="item.value"
value-key="attr_value"
:fetch-suggestions="(query, cb) => querySearch(item, query, cb)"
style="width: 320px"
v-else />
</template>
</el-form-item>
</div>
......
import httpRequest from '@/utils/axios'
import type {
GroupListRequest,
StaticGroupCreateRequest,
StaticGroupUpdateRequest,
DynamicGroupCreateRequest,
DynamicGroupUpdateRequest
} from './types'
import type { GroupListRequest, StaticGroupCreateRequest, StaticGroupUpdateRequest, DynamicGroupCreateRequest, DynamicGroupUpdateRequest } from './types'
// 获取群组列表
export function getGroupList(params?: GroupListRequest) {
return httpRequest.get('/api/lab/v1/experiment/group/list', { params })
return httpRequest.get('/api/lab/v1/experiment/group/bda-list', { params })
}
// 获取群组详情
export function getGroupInfo(params: { id: string }) {
return httpRequest.get('/api/lab/v1/experiment/group/detail', { params })
return httpRequest.get('/api/lab/v1/experiment/group/bda-detail', { params })
}
// 创建静态群组
export function createStaticGroup(data: StaticGroupCreateRequest) {
return httpRequest.post('/api/lab/v1/experiment/group/create-static-group', data)
return httpRequest.post('/api/lab/v1/experiment/group/bda-create-static-group', data)
}
// 创建动态群组
export function createDynamicGroup(data: DynamicGroupCreateRequest) {
return httpRequest.post('/api/lab/v1/experiment/group/create-dynamic-group', data)
return httpRequest.post('/api/lab/v1/experiment/group/bda-create-dynamic-group', data)
}
// 更新静态群组
export function updateStaticGroup(data: StaticGroupUpdateRequest) {
return httpRequest.post('/api/lab/v1/experiment/group/update-static-group', data)
return httpRequest.post('/api/lab/v1/experiment/group/bda-update-static-group', data)
}
// 更新动态群组
export function updateDynamicGroup(data: DynamicGroupUpdateRequest) {
return httpRequest.post('/api/lab/v1/experiment/group/update-dynamic-group', data)
return httpRequest.post('/api/lab/v1/experiment/group/bda-update-dynamic-group', data)
}
// 删除群组
export function deleteGroup(data: { ids: string[] }) {
return httpRequest.post('/api/lab/v1/experiment/group/delete', data)
return httpRequest.post('/api/lab/v1/experiment/group/bda-delete', data)
}
// 获取群组数据信息
export function getGroupStatistics(params: { group_id: string }) {
return httpRequest.get('/api/lab/v1/experiment/group/statistics-detail', { params })
return httpRequest.get('/api/lab/v1/experiment/group/bda-statistics-detail', { params })
}
// 更新群组数据信息
export function updateGroupStatistics(data: { id: string }) {
return httpRequest.post('/api/lab/v1/experiment/group/statistics-user-group', data)
return httpRequest.post('/api/lab/v1/experiment/group/bda-statistics-user-group', data)
}
// 获取群组成员
export function getGroupMembers(params: { group_id: string; name?: string; id?: string }) {
return httpRequest.get('/api/lab/v1/experiment/group/members', { params })
return httpRequest.get('/api/lab/v1/experiment/group/bda-members', { params })
}
// 清空静态群组成员
export function clearGroupMembers(data: { group_id: string }) {
return httpRequest.post('/api/lab/v1/experiment/group/clear-members', data)
return httpRequest.post('/api/lab/v1/experiment/group/bda-clear-members', data)
}
// 搜索群组成员
export function searchGroupMembers(params: { group_id: string; name?: string; id?: string }) {
return httpRequest.get('/api/lab/v1/experiment/group/search-members', { params })
return httpRequest.get('/api/lab/v1/experiment/group/bda-search-members', { params })
}
// 手动添加静态群组
export function addGroupMembers(data: { group_id: string; user_ids: string[] }) {
return httpRequest.post('/api/lab/v1/experiment/group/add-members', data)
return httpRequest.post('/api/lab/v1/experiment/group/bda-add-members', data)
}
......@@ -7,6 +7,7 @@ import { createStaticGroup, updateStaticGroup, createDynamicGroup, updateDynamic
import UserRule from '@/components/rule/UserRule.vue'
import EventRule from '@/components/rule/EventRule.vue'
import LabelRule from '@/components/rule/LabelRule.vue'
import UserActionRule from '@/components/rule/UserActionRule.vue'
import { pick } from 'lodash-es'
interface Props {
......@@ -29,7 +30,7 @@ const title = $computed(() => {
})
const formRef = $ref<FormInstance>()
const form = reactive({
const form: any = reactive({
id: '',
name: '',
type: '',
......@@ -38,13 +39,10 @@ const form = reactive({
update_rule: { type: 1, info: 1 },
user_attr_rule: { current_logic_operate: 'and', items: [] },
event_attr_rule: { current_logic_operate: 'and', items: [] },
tag_rule: { current_logic_operate: 'and', items: [] }
tag_rule: { current_logic_operate: 'and', items: [] },
user_action_rule: { current_logic_operate: 'and', items: [] }
})
provide('userAttrRule', toRef(form, 'user_attr_rule'))
provide('eventAttrRule', toRef(form, 'event_attr_rule'))
provide('tagRule', toRef(form, 'tag_rule'))
watchEffect(() => {
if (props.data?.id) {
let updateRule = { type: 1, info: 1 }
......@@ -75,7 +73,12 @@ function fetchInfo() {
return item
})
Object.assign(form, { user_attr_rule: { ...user_attr_rule, attrRuleItems }, event_attr_rule: { ...event_attr_rule, eventRuleItems }, tag_rule })
Object.assign(form, {
user_attr_rule: { ...user_attr_rule, attrRuleItems },
event_attr_rule: { ...event_attr_rule, eventRuleItems },
tag_rule,
user_action_rule: detail.user_action_rule
})
})
}
......@@ -106,7 +109,7 @@ async function handleCreate() {
event_attr_rule: JSON.stringify([form.event_attr_rule]),
tag_rule: JSON.stringify([form.tag_rule])
},
['name', 'update_status', 'update_rule', 'user_attr_rule', 'event_attr_rule', 'tag_rule', 'status']
['name', 'update_status', 'update_rule', 'user_attr_rule', 'event_attr_rule', 'tag_rule', 'user_action_rule', 'status']
)
await createDynamicGroup(params)
}
......@@ -136,9 +139,10 @@ async function handleUpdate() {
update_rule: JSON.stringify(form.update_rule),
user_attr_rule: JSON.stringify([{ ...form.user_attr_rule, items: attrRuleItems }]),
event_attr_rule: JSON.stringify([{ ...form.event_attr_rule, items: eventRuleItems }]),
tag_rule: JSON.stringify([form.tag_rule])
tag_rule: JSON.stringify([form.tag_rule]),
user_action_rule: JSON.stringify(form.user_action_rule)
},
['id', 'name', 'update_status', 'update_rule', 'user_attr_rule', 'event_attr_rule', 'tag_rule', 'status']
['id', 'name', 'update_status', 'update_rule', 'user_attr_rule', 'event_attr_rule', 'tag_rule', 'user_action_rule', 'status']
)
await updateDynamicGroup(params)
}
......@@ -191,11 +195,12 @@ async function handleUpdate() {
</el-form-item>
<template v-if="data.type === '2'">
<!-- 用户属性规则 -->
<UserRule></UserRule>
<UserRule v-model="form.user_attr_rule"></UserRule>
<!-- 事件属性规则 -->
<EventRule style="margin-top: 20px"></EventRule>
<EventRule v-model="form.event_attr_rule" style="margin-top: 20px"></EventRule>
<!-- 标签 -->
<LabelRule style="margin-top: 20px"></LabelRule>
<LabelRule v-model="form.tag_rule" style="margin-top: 20px"></LabelRule>
<UserActionRule v-model="form.user_action_rule" style="margin-top: 20px"></UserActionRule>
</template>
</el-form>
<template #footer>
......
import httpRequest from '@/utils/axios'
import type {
LabelTypeListRequest,
LabelTypeCreateRequest,
LabelTypeUpdateRequest,
LabelListRequest,
LabelCreateRequest,
LabelUpdateRequest
} from './types'
import type { LabelTypeListRequest, LabelTypeCreateRequest, LabelTypeUpdateRequest, LabelListRequest, LabelCreateRequest, LabelUpdateRequest } from './types'
// 获取标签类型列表
export function getLabelTypeList(params?: LabelTypeListRequest) {
......@@ -30,40 +23,40 @@ export function deleteLabelType(data: { id: string }) {
// 获取标签列表
export function getLabelList(params?: LabelListRequest) {
return httpRequest.get('/api/lab/v1/experiment/tag/list', { params })
return httpRequest.get('/api/lab/v1/experiment/tag/bda-list', { params })
}
// 创建标签
export function createLabel(data: LabelCreateRequest) {
return httpRequest.post('/api/lab/v1/experiment/tag/create', data)
return httpRequest.post('/api/lab/v1/experiment/tag/bda-create', data)
}
// 更新标签
export function updateLabel(data: LabelUpdateRequest) {
return httpRequest.post('/api/lab/v1/experiment/tag/update', data)
return httpRequest.post('/api/lab/v1/experiment/tag/bda-update', data)
}
// 更新标签
// 删除标签
export function deleteLabel(data: { id: string }) {
return httpRequest.post('/api/lab/v1/experiment/tag/delete', data)
return httpRequest.post('/api/lab/v1/experiment/tag/bda-delete', data)
}
// 获取标签数据信息
export function getLabelStatistics(params: { id: string }) {
return httpRequest.get('/api/lab/v1/experiment/tag/statistics', { params })
return httpRequest.get('/api/lab/v1/experiment/tag/bda-statistics', { params })
}
// 更新标签数据信息
export function updateLabelStatistics(data: { id: string }) {
return httpRequest.post('/api/lab/v1/experiment/tag/statistics-user-tag', data)
return httpRequest.post('/api/lab/v1/experiment/tag/bda-statistics-user-tag', data)
}
// 获取标签规则
export function getLabelRule(params: { id: string }) {
return httpRequest.get('/api/lab/v1/experiment/tag/rule', { params })
return httpRequest.get('/api/lab/v1/experiment/tag/bda-rules', { params })
}
// 更新标签规则
export function updateLabelRule(data: { id: string; user_attr_rule: string; event_attr_rule: string }) {
return httpRequest.post('/api/lab/v1/experiment/tag/save-rule', data)
export function updateLabelRule(data: { id: string; rules: string }) {
return httpRequest.post('/api/lab/v1/experiment/tag/bda-save-rules', data)
}
......@@ -2,7 +2,7 @@
import type { Label } from '../types'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { updateStatusRuleList, dateUnitList, weekList } from '@/utils/dictionary'
import { updateStatusRuleList, dateUnitList, weekList, labelList } from '@/utils/dictionary'
import { createLabel, updateLabel } from '../api'
import { useLabelType } from '../composables/useLabelType'
import { pick } from 'lodash-es'
......@@ -28,7 +28,8 @@ const form = reactive({
type_id: '',
update_status: '2',
update_rule: { type: 1, info: 1 },
status: '1'
status: '1',
label: ''
})
watchEffect(() => {
if (props.data) {
......@@ -44,7 +45,8 @@ watchEffect(() => {
const rules = ref<FormRules>({
name: [{ required: true, message: '请输入标签名称' }],
type_id: [{ required: true, message: '请选择标签类型' }],
label: [{ required: true, message: '请选择标签类型' }],
type_id: [{ required: true, message: '请选择标签目录' }],
update_status: [{ required: true, message: '请选择更新评率' }]
})
......@@ -54,13 +56,7 @@ function handleSubmit() {
}
// 新建
function handleCreate() {
const params = pick({ ...form, update_rule: JSON.stringify(form.update_rule) }, [
'name',
'type_id',
'update_status',
'update_rule',
'status'
])
const params = pick({ ...form, update_rule: JSON.stringify(form.update_rule) }, ['name', 'type_id', 'update_status', 'update_rule', 'status', 'label'])
createLabel(params).then(() => {
ElMessage({ message: '创建成功', type: 'success' })
emit('update')
......@@ -69,14 +65,7 @@ function handleCreate() {
}
// 修改
function handleUpdate() {
const params = pick({ ...form, update_rule: JSON.stringify(form.update_rule) }, [
'id',
'name',
'type_id',
'update_status',
'update_rule',
'status'
])
const params = pick({ ...form, update_rule: JSON.stringify(form.update_rule) }, ['id', 'name', 'type_id', 'update_status', 'update_rule', 'status'])
updateLabel(params).then(() => {
ElMessage({ message: '修改成功', type: 'success' })
emit('update')
......@@ -91,29 +80,26 @@ function handleUpdate() {
<el-form-item label="标签名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" />
</el-form-item>
<el-form-item label="标签类型" prop="type_id">
<el-form-item label="标签类型" prop="label">
<el-select v-model="form.label" style="width: 100%" :disabled="isUpdate">
<el-option v-for="item in labelList" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="标签目录" prop="type_id">
<el-select v-model="form.type_id" style="width: 100%">
<el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="更新频率" prop="update_status">
<el-radio-group v-model="form.update_status">
<el-radio
v-for="item in updateStatusRuleList"
:key="item.value"
:label="item.value"
:disabled="item.value === '1'">
<el-radio v-for="item in updateStatusRuleList" :key="item.value" :label="item.value" :disabled="item.value === '1'">
{{ item.label }}
</el-radio>
</el-radio-group>
<div class="update-rule-wrap" v-if="form.update_status === '1'">
<span></span>
<el-select v-model="form.update_rule.type" placeholder=" " style="width: 60px">
<el-option
v-for="item in dateUnitList"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
<el-option v-for="item in dateUnitList" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
<template v-if="form.update_rule.type === 1">
<span>的凌晨更新</span>
......
<script setup lang="ts">
import type { Label } from '../types'
import type { FormInstance, FormRules } from 'element-plus'
import type { FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/stores/user'
import { useMapStore } from '@/stores/map'
import { getNameByValue, updateStatusRuleList } from '@/utils/dictionary'
import { getNameByValue, updateStatusRuleList, labelList } from '@/utils/dictionary'
import { getLabelRule, updateLabelRule } from '../api'
import UserRule from '@/components/rule/UserRule.vue'
import EventRule from '@/components/rule/EventRule.vue'
import LevelRule from '@/components/rule/LevelRule.vue'
import EventPreferenceRule from '@/components/rule/EventPreferenceRule.vue'
import EventTargetRule from '@/components/rule/EventTargetRule.vue'
const props = defineProps<{
data: Label
......@@ -27,37 +28,30 @@ const statusList = useMapStore().getMapValuesByKey('system_status')
const formRef = $ref<FormInstance>()
const form = reactive({
id: props.data.id,
user_attr_rule: { current_logic_operate: 'and', items: [] },
event_attr_rule: { current_logic_operate: 'and', items: [] }
id: '',
rules: undefined
})
provide('userAttrRule', toRef(form, 'user_attr_rule'))
provide('eventAttrRule', toRef(form, 'event_attr_rule'))
function fetchInfo() {
getLabelRule({ id: props.data.id }).then(res => {
const { detail } = res.data
const [user_attr_rule = { current_logic_operate: 'and', items: [] }] = detail.user_attr_rule
const [event_attr_rule = { current_logic_operate: 'and', items: [] }] = detail.event_attr_rule
const attrRuleItems = user_attr_rule.items.map((item: any) => {
item.value = ['in', 'not in'].includes(item.operate) ? item.value.split(',') : item.value
return item
})
const eventRuleItems = event_attr_rule.items.map((item: any) => {
item.value = ['in', 'not in'].includes(item.operate) ? item.value.split(',') : item.value
return item
})
Object.assign(form, detail, { user_attr_rule: { ...user_attr_rule, attrRuleItems }, event_attr_rule: { ...event_attr_rule, eventRuleItems } })
// const [user_attr_rule = { current_logic_operate: 'and', items: [] }] = detail.user_attr_rule
// const [event_attr_rule = { current_logic_operate: 'and', items: [] }] = detail.event_attr_rule
// const attrRuleItems = user_attr_rule.items.map((item: any) => {
// item.value = ['in', 'not in'].includes(item.operate) ? item.value.split(',') : item.value
// return item
// })
// const eventRuleItems = event_attr_rule.items.map((item: any) => {
// item.value = ['in', 'not in'].includes(item.operate) ? item.value.split(',') : item.value
// return item
// })
const rules = detail.rules.length === 0 ? undefined : detail.rules
Object.assign(form, { id: props.data.id, rules })
})
}
watchEffect(() => fetchInfo())
const rules = ref<FormRules>({
name: [{ required: true, message: '请输入标签名称' }],
type: [{ required: true, message: '请选择标签类型' }]
})
// 提交
function handleSubmit() {
formRef?.validate().then(handleUpdate)
......@@ -65,18 +59,19 @@ function handleSubmit() {
// 保存
function handleUpdate() {
const attrRuleItems = form.user_attr_rule.items.map((item: any) => {
item.value = Array.isArray(item.value) ? item.value.join(',') : item.value
return item
})
const eventRuleItems = form.event_attr_rule.items.map((item: any) => {
item.value = Array.isArray(item.value) ? item.value.join(',') : item.value
return item
})
// const attrRuleItems = form.user_attr_rule.items.map((item: any) => {
// item.value = Array.isArray(item.value) ? item.value.join(',') : item.value
// return item
// })
// const eventRuleItems = form.event_attr_rule.items.map((item: any) => {
// item.value = Array.isArray(item.value) ? item.value.join(',') : item.value
// return item
// })
const params = {
id: form.id,
user_attr_rule: JSON.stringify([{ ...form.user_attr_rule, items: attrRuleItems }]),
event_attr_rule: JSON.stringify([{ ...form.event_attr_rule, items: eventRuleItems }])
rules: JSON.stringify(form.rules)
// user_attr_rule: JSON.stringify([{ ...form.user_attr_rule, items: attrRuleItems }]),
// event_attr_rule: JSON.stringify([{ ...form.event_attr_rule, items: eventRuleItems }])
}
updateLabelRule(params).then(() => {
ElMessage({ message: '保存成功', type: 'success' })
......@@ -94,7 +89,7 @@ function handleUpdate() {
<el-form-item label="标签名称">{{ data.name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标签类型">{{ data.tag_type.name }}</el-form-item>
<el-form-item label="标签类型">{{ getNameByValue(data.label, labelList) }}</el-form-item>
</el-col>
</el-row>
<el-row>
......@@ -110,11 +105,17 @@ function handleUpdate() {
</el-col>
</el-row>
</el-form>
<el-form :model="form" :rules="rules" inline ref="formRef" :disabled="disabled">
<el-form :model="form" inline ref="formRef" :disabled="disabled" @submit.prevent v-if="form.id">
<!-- 自定义分层 -->
<LevelRule v-model="form.rules" v-if="data.label == 1"></LevelRule>
<!-- 事件偏好 -->
<EventPreferenceRule v-model="form.rules" v-if="data.label == 2"></EventPreferenceRule>
<!-- 事件指标 -->
<EventTargetRule v-model="form.rules" v-if="data.label == 3"></EventTargetRule>
<!-- 用户属性规则 -->
<UserRule></UserRule>
<!-- <UserRule></UserRule> -->
<!-- 事件属性规则 -->
<EventRule style="margin-top: 20px"></EventRule>
<!-- <EventRule style="margin-top: 20px"></EventRule> -->
</el-form>
<template #footer>
<el-row justify="center">
......
......@@ -30,7 +30,7 @@ function handleUpdate(row: LabelType) {
}
// 删除
function handleRemove(row: LabelType) {
ElMessageBox.confirm('确定要删除该类型吗?', '提示').then(() => {
ElMessageBox.confirm('确定要删除该目录吗?', '提示').then(() => {
deleteLabelType({ id: row.id }).then(() => {
ElMessage({ message: '删除成功', type: 'success' })
fetchTypeList()
......@@ -40,7 +40,7 @@ function handleRemove(row: LabelType) {
</script>
<template>
<el-button type="primary" style="width: 100%" @click="handleAdd" v-permission="'experiment_tag_type_create'">添加标签类型</el-button>
<el-button type="primary" style="width: 100%" @click="handleAdd" v-permission="'experiment_tag_type_create'">添加标签目录</el-button>
<div class="label-type-total" @click="$emit('select', '')">
<h4>全部标签</h4>
<p>{{ labelCount }}</p>
......
......@@ -14,7 +14,7 @@ const emit = defineEmits<{
}>()
const isUpdate = $computed(() => !!props.data?.id)
const title = $computed(() => (isUpdate ? '修改标签类型' : '新建标签类型'))
const title = $computed(() => (isUpdate ? '修改标签目录' : '新建标签目录'))
const formRef = $ref<FormInstance>()
const form = reactive({ id: '', name: '', url: '' })
......@@ -24,8 +24,8 @@ watchEffect(() => {
})
const rules = ref<FormRules>({
name: [{ required: true, message: '请输入标签类型名称' }],
url: [{ required: true, message: '请选择标签类型图标' }]
name: [{ required: true, message: '请输入标签目录名称' }],
url: [{ required: true, message: '请选择标签目录图标' }]
})
const iconColorList = $ref(['#AA593B', '#CD9A23', '#20AE6C', '#196D42', '#614BE8', '#6D4E8B', '#A01578', '#BD2547'])
......@@ -58,10 +58,10 @@ function handleUpdate() {
<template>
<el-dialog :title="title" :close-on-click-modal="false" width="600px" @update:modelValue="$emit('update:modelValue')">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":" label-width="100px">
<el-form-item label="类型名称" prop="name">
<el-form-item label="目录名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" />
</el-form-item>
<el-form-item label="类型图标" prop="url">
<el-form-item label="目录图标" prop="url">
<div class="label-type-icon-list">
<div
class="label-type-icon-item"
......
......@@ -2,7 +2,7 @@
import type { Label } from '../types'
import { UserFilled } from '@element-plus/icons-vue'
import { useMapStore } from '@/stores/map'
import { getNameByValue, updateStatusRuleList, updateStatusList } from '@/utils/dictionary'
import { getNameByValue, updateStatusRuleList, updateStatusList, labelList } from '@/utils/dictionary'
import { getLabelStatistics, updateLabelStatistics } from '../api'
import { ElMessage } from 'element-plus'
......@@ -36,7 +36,7 @@ function handleUpdate() {
<el-form-item label="标签名称">{{ data.name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标签类型">{{ data.tag_type.name }}</el-form-item>
<el-form-item label="标签类型">{{ getNameByValue(data.label, labelList) }}</el-form-item>
</el-col>
</el-row>
<el-row>
......@@ -69,14 +69,7 @@ function handleUpdate() {
<dt>更新状态</dt>
<dd>
<span style="margin-right: 10px">{{ getNameByValue(detail.status, updateStatusList) }}</span>
<el-button
type="primary"
plain
@click="handleUpdate"
size="small"
:disabled="['2', '4'].includes(detail.status)"
>立即更新</el-button
>
<el-button type="primary" plain @click="handleUpdate" size="small" :disabled="['2', '4'].includes(detail.status)">立即更新</el-button>
</dd>
</dl>
</div>
......
......@@ -26,6 +26,7 @@ export interface Label {
created_operator: Operator
updated_time: string
updated_operator: Operator
label: number
}
// 标签更新规则
export interface LabelUpdateRule {
......@@ -35,7 +36,7 @@ export interface LabelUpdateRule {
export type LabelListRequest = Pick<Label, 'id' | 'name'> & { experiment_id?: string }
export type LabelUpdateRequest = Pick<Label, 'id' | 'name' | 'type_id' | 'update_status' | 'update_rule' | 'status'> & {
export type LabelUpdateRequest = Pick<Label, 'id' | 'name' | 'type_id' | 'update_status' | 'update_rule' | 'status' | 'label'> & {
experiment_id?: string
}
......
......@@ -6,7 +6,7 @@ import LabelType from '../components/LabelType.vue'
import { ElMessageBox, ElMessage } from 'element-plus'
import { getLabelList, deleteLabel } from '../api'
import { useMapStore } from '@/stores/map'
import { getNameByValue, updateStatusRuleList } from '@/utils/dictionary'
import { getNameByValue, updateStatusRuleList, labelList } from '@/utils/dictionary'
import { useLabelType } from '../composables/useLabelType'
import SelectUser from '@/components/SelectUser.vue'
......@@ -31,7 +31,6 @@ const listOptions = computed(() => {
listParams.type_id = ''
} else {
params.updated_operator = listParams.updated_operator
params.type_id = listParams.type_id
}
return params
}
......@@ -41,11 +40,17 @@ const listOptions = computed(() => {
{
type: 'select',
prop: 'type_id',
placeholder: '请选择标签类型',
placeholder: '请选择标签目录',
options: typeList.value,
labelKey: 'name',
valueKey: 'id'
},
{
type: 'select',
prop: 'label',
placeholder: '请选择标签类型',
options: labelList
},
{ type: 'select', prop: 'status', placeholder: '请选择标签状态', options: statusList },
{ type: 'input', prop: 'updated_operator', placeholder: '更新人', slots: 'filter-user' }
],
......@@ -53,7 +58,14 @@ const listOptions = computed(() => {
{ label: '序号', type: 'index', width: 60 },
{ label: '标签ID', prop: 'id' },
{ label: '标签名称', prop: 'name' },
{ label: '标签类型', prop: 'tag_type.name' },
{
label: '标签类型',
prop: 'label',
computed({ row }: { row: Label }) {
return getNameByValue(row.label, labelList) || row.label
}
},
{ label: '标签目录', prop: 'tag_type.name' },
{
label: '更新频率',
prop: 'update_status',
......@@ -117,7 +129,9 @@ function handleRule(row: Label) {
function handleSelect(id: string) {
listParams.type_id = id
nextTick(() => {
appList?.refetch()
})
}
</script>
......
......@@ -111,6 +111,25 @@ export interface TagRule {
items: string[]
}
// 用户行为规则
export interface UserActionRule {
current_logic_operate: 'and' | 'or'
items: UserActionRuleItem[]
}
export interface UserActionRuleItem {
operate: string
operate_name: string
value: string
event_list: RuleEvent[]
}
export interface RuleEvent {
event_id: string
event_name: string
attr_list: RuleAttr[]
}
// 资料管理
export interface MaterialProp {
id: string
......
......@@ -18,15 +18,15 @@ httpRequest.interceptors.request.use(
if (config.method === 'get')
config.params = Object.assign({}, config.params, {
experiment_id: params.get('experiment_id'),
student_id: params.get('student_id'),
force_tgc: params.get('force_tgc')
student_id: params.get('student_id') || undefined,
force_tgc: params.get('force_tgc') || undefined
})
if (config.method === 'post')
config.data = Object.assign({}, config.data, {
experiment_id: params.get('experiment_id'),
student_id: params.get('student_id'),
force_tgc: params.get('force_tgc')
student_id: params.get('student_id') || undefined,
force_tgc: params.get('force_tgc') || undefined
})
return config
......@@ -45,7 +45,7 @@ httpRequest.interceptors.response.use(
location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.href)}`
return Promise.reject(data)
}
if (data.code === 1) {
if (data.code === 1 || data.code === -1) {
ElMessage.error(data.message || data.msg)
return Promise.reject(data)
}
......
......@@ -94,3 +94,15 @@ export const happenInfoList = [
]
export const triggerInfoList = [{ label: '触发次数', value: '触发次数' }]
export const labelList = [
{ label: '自定义分层标签 ', value: '1' },
{ label: '事件偏好标签 ', value: '2' },
{ label: '事件指标标签 ', value: '3' }
]
export const wayList = [
{ label: '总金额 ', value: '1' },
{ label: '总次数 ', value: '2' },
{ label: '平均金额 ', value: '3' }
]
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论