Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-dml
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-dml
Commits
0dfd43a6
提交
0dfd43a6
authored
11月 06, 2023
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: 修改标签管理和群组管理
上级
202fa072
隐藏空白字符变更
内嵌
并排
正在显示
21 个修改的文件
包含
704 行增加
和
168 行删除
+704
-168
rule.scss
src/assets/styles/rule.scss
+20
-1
EventPreferenceRule.vue
src/components/rule/EventPreferenceRule.vue
+94
-0
EventRule.vue
src/components/rule/EventRule.vue
+13
-5
EventTargetRule.vue
src/components/rule/EventTargetRule.vue
+67
-0
LabelRule.vue
src/components/rule/LabelRule.vue
+3
-6
LevelRule.vue
src/components/rule/LevelRule.vue
+76
-0
UserActionRule.vue
src/components/rule/UserActionRule.vue
+252
-0
UserRule.vue
src/components/rule/UserRule.vue
+14
-9
api.ts
src/modules/group/api.ts
+14
-20
FormDialog.vue
src/modules/group/components/FormDialog.vue
+18
-13
api.ts
src/modules/label/api.ts
+11
-18
LabelFormDialog.vue
src/modules/label/components/LabelFormDialog.vue
+15
-29
LabelRuleDialog.vue
src/modules/label/components/LabelRuleDialog.vue
+40
-39
LabelType.vue
src/modules/label/components/LabelType.vue
+2
-2
LabelTypeFormDialog.vue
src/modules/label/components/LabelTypeFormDialog.vue
+5
-5
LabelViewDialog.vue
src/modules/label/components/LabelViewDialog.vue
+3
-10
types.ts
src/modules/label/types.ts
+2
-1
Index.vue
src/modules/label/views/Index.vue
+19
-5
types.ts
src/types.ts
+19
-0
axios.ts
src/utils/axios.ts
+5
-5
dictionary.ts
src/utils/dictionary.ts
+12
-0
没有找到文件。
src/assets/styles/rule.scss
浏览文件 @
0dfd43a6
...
@@ -56,8 +56,27 @@
...
@@ -56,8 +56,27 @@
.rule-item
{
.rule-item
{
margin
:
10px
0
;
margin
:
10px
0
;
}
}
.event-rule
{
.event-rule
,
.user-action-rule
{
section
+
section
{
section
+
section
{
margin-top
:
30px
;
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
;
}
src/components/rule/EventPreferenceRule.vue
0 → 100644
浏览文件 @
0dfd43a6
<
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
>
src/components/rule/EventRule.vue
浏览文件 @
0dfd43a6
...
@@ -5,7 +5,10 @@ import { useMetaEvent } from '@/composables/useAllData'
...
@@ -5,7 +5,10 @@ import { useMetaEvent } from '@/composables/useAllData'
import
{
stringOperatorList
,
numberOperatorList
,
dateOperatorList
,
happenInfoList
,
triggerInfoList
}
from
'@/utils/dictionary'
import
{
stringOperatorList
,
numberOperatorList
,
dateOperatorList
,
happenInfoList
,
triggerInfoList
}
from
'@/utils/dictionary'
import
{
searchEventAttrs
}
from
'@/api/base'
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
()
const
{
metaEventList
}
=
useMetaEvent
()
...
@@ -72,7 +75,7 @@ function handleHappenOperateChange(value: string, item: EventRuleItem) {
...
@@ -72,7 +75,7 @@ function handleHappenOperateChange(value: string, item: EventRuleItem) {
// 事件改变
// 事件改变
function
handleEventChange
(
value
:
string
,
item
:
EventRuleItem
)
{
function
handleEventChange
(
value
:
string
,
item
:
EventRuleItem
)
{
const
currentEvent
=
m
etaEventList
.
value
.
find
(
item
=>
item
.
id
===
value
)
const
currentEvent
=
currentM
etaEventList
.
value
.
find
(
item
=>
item
.
id
===
value
)
item
.
happen_info
.
event_name
=
currentEvent
?.
name
||
''
item
.
happen_info
.
event_name
=
currentEvent
?.
name
||
''
item
.
happen_info
.
attr_list
=
[]
item
.
happen_info
.
attr_list
=
[]
}
}
...
@@ -173,7 +176,7 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
...
@@ -173,7 +176,7 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<el-button
text
:icon=
"Plus"
@
click=
"handleAttrAdd(rule.happen_info.attr_list)"
>
添加条件
</el-button>
<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>
<!-- 属性条件 -->
<!-- 属性条件 -->
<el-row
justify=
"space-between"
class=
"rule-item"
v-for=
"(attr, index) in rule.happen_info.attr_list"
:key=
"index"
>
<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) {
...
@@ -185,7 +188,11 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
</el-form-item>
</el-form-item>
<el-form-item>
<el-form-item>
<el-select
v-model=
"attr.operate"
@
change=
"value => handleOperateChange(value, attr)"
>
<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-select>
</el-form-item>
</el-form-item>
<el-form-item
v-if=
"!['null', 'not null'].includes(attr.operate)"
>
<el-form-item
v-if=
"!['null', 'not null'].includes(attr.operate)"
>
...
@@ -248,7 +255,8 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
...
@@ -248,7 +255,8 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
</section>
</section>
</div>
</div>
</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>
</el-card>
</template>
</template>
...
...
src/components/rule/EventTargetRule.vue
0 → 100644
浏览文件 @
0dfd43a6
<
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
>
src/components/rule/LabelRule.vue
浏览文件 @
0dfd43a6
...
@@ -3,7 +3,8 @@ import type { TagRule } from '@/types'
...
@@ -3,7 +3,8 @@ import type { TagRule } from '@/types'
import
{
PriceTag
,
Plus
,
CloseBold
}
from
'@element-plus/icons-vue'
import
{
PriceTag
,
Plus
,
CloseBold
}
from
'@element-plus/icons-vue'
import
{
useTag
}
from
'@/composables/useAllData'
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
()
const
{
tagList
}
=
useTag
()
...
@@ -44,11 +45,7 @@ function handleRemove(items: string[], index: number) {
...
@@ -44,11 +45,7 @@ function handleRemove(items: string[], index: number) {
标签 等于
标签 等于
<el-form-item>
<el-form-item>
<el-select
v-model=
"tagRule.items[index]"
>
<el-select
v-model=
"tagRule.items[index]"
>
<el-option
<el-option
v-for=
"option in tagList"
:key=
"option.id"
:label=
"option.name"
:value=
"option.id"
></el-option>
v-for=
"option in tagList"
:key=
"option.id"
:label=
"option.name"
:value=
"option.id"
></el-option>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
</div>
</div>
...
...
src/components/rule/LevelRule.vue
0 → 100644
浏览文件 @
0dfd43a6
<
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
>
src/components/rule/UserActionRule.vue
0 → 100644
浏览文件 @
0dfd43a6
<
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
>
src/components/rule/UserRule.vue
浏览文件 @
0dfd43a6
...
@@ -5,7 +5,8 @@ import { useUserAttr } from '@/composables/useAllData'
...
@@ -5,7 +5,8 @@ import { useUserAttr } from '@/composables/useAllData'
import
{
stringOperatorList
,
numberOperatorList
,
dateOperatorList
}
from
'@/utils/dictionary'
import
{
stringOperatorList
,
numberOperatorList
,
dateOperatorList
}
from
'@/utils/dictionary'
import
{
searchMetaMemberAttrs
}
from
'@/api/base'
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
()
const
{
userAttrList
}
=
useUserAttr
()
...
@@ -107,17 +108,16 @@ function remoteMethod(item: RuleAttr, search: string = '') {
...
@@ -107,17 +108,16 @@ function remoteMethod(item: RuleAttr, search: string = '') {
</el-form-item>
</el-form-item>
<el-form-item>
<el-form-item>
<el-select
v-model=
"item.operate"
@
change=
"value => handleOperateChange(value, 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-select>
</el-form-item>
</el-form-item>
<el-form-item
v-if=
"!['null', 'not null'].includes(item.operate)"
>
<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.start"
type=
"date"
value-format=
"YYYY-MM-DD"
/>
<el-date-picker
v-model=
"item.value.end"
type=
"date"
value-format=
"YYYY-MM-DD"
/>
<el-date-picker
v-model=
"item.value.end"
type=
"date"
value-format=
"YYYY-MM-DD"
/>
</
template
>
</
template
>
...
@@ -145,7 +145,12 @@ function remoteMethod(item: RuleAttr, search: string = '') {
...
@@ -145,7 +145,12 @@ function remoteMethod(item: RuleAttr, search: string = '') {
v-if=
"['in', 'not in'].includes(item.operate)"
>
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-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</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
>
</
template
>
</el-form-item>
</el-form-item>
</div>
</div>
...
...
src/modules/group/api.ts
浏览文件 @
0dfd43a6
import
httpRequest
from
'@/utils/axios'
import
httpRequest
from
'@/utils/axios'
import
type
{
import
type
{
GroupListRequest
,
StaticGroupCreateRequest
,
StaticGroupUpdateRequest
,
DynamicGroupCreateRequest
,
DynamicGroupUpdateRequest
}
from
'./types'
GroupListRequest
,
StaticGroupCreateRequest
,
StaticGroupUpdateRequest
,
DynamicGroupCreateRequest
,
DynamicGroupUpdateRequest
}
from
'./types'
// 获取群组列表
// 获取群组列表
export
function
getGroupList
(
params
?:
GroupListRequest
)
{
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
})
{
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
)
{
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
)
{
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
)
{
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
)
{
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
[]
})
{
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
})
{
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
})
{
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
})
{
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
})
{
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
})
{
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
[]
})
{
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
)
}
}
src/modules/group/components/FormDialog.vue
浏览文件 @
0dfd43a6
...
@@ -7,6 +7,7 @@ import { createStaticGroup, updateStaticGroup, createDynamicGroup, updateDynamic
...
@@ -7,6 +7,7 @@ import { createStaticGroup, updateStaticGroup, createDynamicGroup, updateDynamic
import
UserRule
from
'@/components/rule/UserRule.vue'
import
UserRule
from
'@/components/rule/UserRule.vue'
import
EventRule
from
'@/components/rule/EventRule.vue'
import
EventRule
from
'@/components/rule/EventRule.vue'
import
LabelRule
from
'@/components/rule/LabelRule.vue'
import
LabelRule
from
'@/components/rule/LabelRule.vue'
import
UserActionRule
from
'@/components/rule/UserActionRule.vue'
import
{
pick
}
from
'lodash-es'
import
{
pick
}
from
'lodash-es'
interface
Props
{
interface
Props
{
...
@@ -29,7 +30,7 @@ const title = $computed(() => {
...
@@ -29,7 +30,7 @@ const title = $computed(() => {
})
})
const
formRef
=
$ref
<
FormInstance
>
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
({
const
form
:
any
=
reactive
({
id
:
''
,
id
:
''
,
name
:
''
,
name
:
''
,
type
:
''
,
type
:
''
,
...
@@ -38,13 +39,10 @@ const form = reactive({
...
@@ -38,13 +39,10 @@ const form = reactive({
update_rule
:
{
type
:
1
,
info
:
1
},
update_rule
:
{
type
:
1
,
info
:
1
},
user_attr_rule
:
{
current_logic_operate
:
'and'
,
items
:
[]
},
user_attr_rule
:
{
current_logic_operate
:
'and'
,
items
:
[]
},
event_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
(()
=>
{
watchEffect
(()
=>
{
if
(
props
.
data
?.
id
)
{
if
(
props
.
data
?.
id
)
{
let
updateRule
=
{
type
:
1
,
info
:
1
}
let
updateRule
=
{
type
:
1
,
info
:
1
}
...
@@ -75,7 +73,12 @@ function fetchInfo() {
...
@@ -75,7 +73,12 @@ function fetchInfo() {
return
item
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() {
...
@@ -106,7 +109,7 @@ async function handleCreate() {
event_attr_rule
:
JSON
.
stringify
([
form
.
event_attr_rule
]),
event_attr_rule
:
JSON
.
stringify
([
form
.
event_attr_rule
]),
tag_rule
:
JSON
.
stringify
([
form
.
tag_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
)
await
createDynamicGroup
(
params
)
}
}
...
@@ -136,9 +139,10 @@ async function handleUpdate() {
...
@@ -136,9 +139,10 @@ async function handleUpdate() {
update_rule
:
JSON
.
stringify
(
form
.
update_rule
),
update_rule
:
JSON
.
stringify
(
form
.
update_rule
),
user_attr_rule
:
JSON
.
stringify
([{
...
form
.
user_attr_rule
,
items
:
attrRuleItems
}]),
user_attr_rule
:
JSON
.
stringify
([{
...
form
.
user_attr_rule
,
items
:
attrRuleItems
}]),
event_attr_rule
:
JSON
.
stringify
([{
...
form
.
event_attr_rule
,
items
:
eventRuleItems
}]),
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
)
await
updateDynamicGroup
(
params
)
}
}
...
@@ -191,11 +195,12 @@ async function handleUpdate() {
...
@@ -191,11 +195,12 @@ async function handleUpdate() {
</el-form-item>
</el-form-item>
<
template
v-if=
"data.type === '2'"
>
<
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
>
</
template
>
</el-form>
</el-form>
<
template
#
footer
>
<
template
#
footer
>
...
...
src/modules/label/api.ts
浏览文件 @
0dfd43a6
import
httpRequest
from
'@/utils/axios'
import
httpRequest
from
'@/utils/axios'
import
type
{
import
type
{
LabelTypeListRequest
,
LabelTypeCreateRequest
,
LabelTypeUpdateRequest
,
LabelListRequest
,
LabelCreateRequest
,
LabelUpdateRequest
}
from
'./types'
LabelTypeListRequest
,
LabelTypeCreateRequest
,
LabelTypeUpdateRequest
,
LabelListRequest
,
LabelCreateRequest
,
LabelUpdateRequest
}
from
'./types'
// 获取标签类型列表
// 获取标签类型列表
export
function
getLabelTypeList
(
params
?:
LabelTypeListRequest
)
{
export
function
getLabelTypeList
(
params
?:
LabelTypeListRequest
)
{
...
@@ -30,40 +23,40 @@ export function deleteLabelType(data: { id: string }) {
...
@@ -30,40 +23,40 @@ export function deleteLabelType(data: { id: string }) {
// 获取标签列表
// 获取标签列表
export
function
getLabelList
(
params
?:
LabelListRequest
)
{
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
)
{
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
)
{
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
})
{
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
})
{
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
})
{
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
})
{
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
})
{
export
function
updateLabelRule
(
data
:
{
id
:
string
;
rules
:
string
})
{
return
httpRequest
.
post
(
'/api/lab/v1/experiment/tag/
save-rule
'
,
data
)
return
httpRequest
.
post
(
'/api/lab/v1/experiment/tag/
bda-save-rules
'
,
data
)
}
}
src/modules/label/components/LabelFormDialog.vue
浏览文件 @
0dfd43a6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
import
type
{
Label
}
from
'../types'
import
type
{
Label
}
from
'../types'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
{
ElMessage
}
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
{
createLabel
,
updateLabel
}
from
'../api'
import
{
useLabelType
}
from
'../composables/useLabelType'
import
{
useLabelType
}
from
'../composables/useLabelType'
import
{
pick
}
from
'lodash-es'
import
{
pick
}
from
'lodash-es'
...
@@ -28,7 +28,8 @@ const form = reactive({
...
@@ -28,7 +28,8 @@ const form = reactive({
type_id
:
''
,
type_id
:
''
,
update_status
:
'2'
,
update_status
:
'2'
,
update_rule
:
{
type
:
1
,
info
:
1
},
update_rule
:
{
type
:
1
,
info
:
1
},
status
:
'1'
status
:
'1'
,
label
:
''
})
})
watchEffect
(()
=>
{
watchEffect
(()
=>
{
if
(
props
.
data
)
{
if
(
props
.
data
)
{
...
@@ -44,7 +45,8 @@ watchEffect(() => {
...
@@ -44,7 +45,8 @@ watchEffect(() => {
const
rules
=
ref
<
FormRules
>
({
const
rules
=
ref
<
FormRules
>
({
name
:
[{
required
:
true
,
message
:
'请输入标签名称'
}],
name
:
[{
required
:
true
,
message
:
'请输入标签名称'
}],
type_id
:
[{
required
:
true
,
message
:
'请选择标签类型'
}],
label
:
[{
required
:
true
,
message
:
'请选择标签类型'
}],
type_id
:
[{
required
:
true
,
message
:
'请选择标签目录'
}],
update_status
:
[{
required
:
true
,
message
:
'请选择更新评率'
}]
update_status
:
[{
required
:
true
,
message
:
'请选择更新评率'
}]
})
})
...
@@ -54,13 +56,7 @@ function handleSubmit() {
...
@@ -54,13 +56,7 @@ function handleSubmit() {
}
}
// 新建
// 新建
function
handleCreate
()
{
function
handleCreate
()
{
const
params
=
pick
({
...
form
,
update_rule
:
JSON
.
stringify
(
form
.
update_rule
)
},
[
const
params
=
pick
({
...
form
,
update_rule
:
JSON
.
stringify
(
form
.
update_rule
)
},
[
'name'
,
'type_id'
,
'update_status'
,
'update_rule'
,
'status'
,
'label'
])
'name'
,
'type_id'
,
'update_status'
,
'update_rule'
,
'status'
])
createLabel
(
params
).
then
(()
=>
{
createLabel
(
params
).
then
(()
=>
{
ElMessage
({
message
:
'创建成功'
,
type
:
'success'
})
ElMessage
({
message
:
'创建成功'
,
type
:
'success'
})
emit
(
'update'
)
emit
(
'update'
)
...
@@ -69,14 +65,7 @@ function handleCreate() {
...
@@ -69,14 +65,7 @@ function handleCreate() {
}
}
// 修改
// 修改
function
handleUpdate
()
{
function
handleUpdate
()
{
const
params
=
pick
({
...
form
,
update_rule
:
JSON
.
stringify
(
form
.
update_rule
)
},
[
const
params
=
pick
({
...
form
,
update_rule
:
JSON
.
stringify
(
form
.
update_rule
)
},
[
'id'
,
'name'
,
'type_id'
,
'update_status'
,
'update_rule'
,
'status'
])
'id'
,
'name'
,
'type_id'
,
'update_status'
,
'update_rule'
,
'status'
])
updateLabel
(
params
).
then
(()
=>
{
updateLabel
(
params
).
then
(()
=>
{
ElMessage
({
message
:
'修改成功'
,
type
:
'success'
})
ElMessage
({
message
:
'修改成功'
,
type
:
'success'
})
emit
(
'update'
)
emit
(
'update'
)
...
@@ -91,29 +80,26 @@ function handleUpdate() {
...
@@ -91,29 +80,26 @@ function handleUpdate() {
<el-form-item
label=
"标签名称"
prop=
"name"
>
<el-form-item
label=
"标签名称"
prop=
"name"
>
<el-input
v-model=
"form.name"
placeholder=
"请输入"
/>
<el-input
v-model=
"form.name"
placeholder=
"请输入"
/>
</el-form-item>
</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-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-option
v-for=
"item in typeList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
></el-option>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<el-form-item
label=
"更新频率"
prop=
"update_status"
>
<el-form-item
label=
"更新频率"
prop=
"update_status"
>
<el-radio-group
v-model=
"form.update_status"
>
<el-radio-group
v-model=
"form.update_status"
>
<el-radio
<el-radio
v-for=
"item in updateStatusRuleList"
:key=
"item.value"
:label=
"item.value"
:disabled=
"item.value === '1'"
>
v-for=
"item in updateStatusRuleList"
:key=
"item.value"
:label=
"item.value"
:disabled=
"item.value === '1'"
>
{{
item
.
label
}}
{{
item
.
label
}}
</el-radio>
</el-radio>
</el-radio-group>
</el-radio-group>
<div
class=
"update-rule-wrap"
v-if=
"form.update_status === '1'"
>
<div
class=
"update-rule-wrap"
v-if=
"form.update_status === '1'"
>
<span>
每
</span>
<span>
每
</span>
<el-select
v-model=
"form.update_rule.type"
placeholder=
" "
style=
"width: 60px"
>
<el-select
v-model=
"form.update_rule.type"
placeholder=
" "
style=
"width: 60px"
>
<el-option
<el-option
v-for=
"item in dateUnitList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
></el-option>
v-for=
"item in dateUnitList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
></el-option>
</el-select>
</el-select>
<template
v-if=
"form.update_rule.type === 1"
>
<template
v-if=
"form.update_rule.type === 1"
>
<span>
的凌晨更新
</span>
<span>
的凌晨更新
</span>
...
...
src/modules/label/components/LabelRuleDialog.vue
浏览文件 @
0dfd43a6
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
type
{
Label
}
from
'../types'
import
type
{
Label
}
from
'../types'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
FormInstance
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useMapStore
}
from
'@/stores/map'
import
{
useMapStore
}
from
'@/stores/map'
import
{
getNameByValue
,
updateStatusRuleList
}
from
'@/utils/dictionary'
import
{
getNameByValue
,
updateStatusRuleList
,
labelList
}
from
'@/utils/dictionary'
import
{
getLabelRule
,
updateLabelRule
}
from
'../api'
import
{
getLabelRule
,
updateLabelRule
}
from
'../api'
import
UserRule
from
'@/components/rule/UserRule.vue'
import
LevelRule
from
'@/components/rule/LevelRule.vue'
import
EventRule
from
'@/components/rule/EventRule.vue'
import
EventPreferenceRule
from
'@/components/rule/EventPreferenceRule.vue'
import
EventTargetRule
from
'@/components/rule/EventTargetRule.vue'
const
props
=
defineProps
<
{
const
props
=
defineProps
<
{
data
:
Label
data
:
Label
...
@@ -27,37 +28,30 @@ const statusList = useMapStore().getMapValuesByKey('system_status')
...
@@ -27,37 +28,30 @@ const statusList = useMapStore().getMapValuesByKey('system_status')
const
formRef
=
$ref
<
FormInstance
>
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
({
const
form
=
reactive
({
id
:
props
.
data
.
id
,
id
:
''
,
user_attr_rule
:
{
current_logic_operate
:
'and'
,
items
:
[]
},
rules
:
undefined
event_attr_rule
:
{
current_logic_operate
:
'and'
,
items
:
[]
}
})
})
provide
(
'userAttrRule'
,
toRef
(
form
,
'user_attr_rule'
))
provide
(
'eventAttrRule'
,
toRef
(
form
,
'event_attr_rule'
))
function
fetchInfo
()
{
function
fetchInfo
()
{
getLabelRule
({
id
:
props
.
data
.
id
}).
then
(
res
=>
{
getLabelRule
({
id
:
props
.
data
.
id
}).
then
(
res
=>
{
const
{
detail
}
=
res
.
data
const
{
detail
}
=
res
.
data
const
[
user_attr_rule
=
{
current_logic_operate
:
'and'
,
items
:
[]
}]
=
detail
.
user_attr_rule
// 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 [event_attr_rule = { current_logic_operate: 'and', items: [] }] = detail.event_attr_rule
const
attrRuleItems
=
user_attr_rule
.
items
.
map
((
item
:
any
)
=>
{
// const attrRuleItems = user_attr_rule.items.map((item: any) => {
item
.
value
=
[
'in'
,
'not in'
].
includes
(
item
.
operate
)
?
item
.
value
.
split
(
','
)
:
item
.
value
// item.value = ['in', 'not in'].includes(item.operate) ? item.value.split(',') : item.value
return
item
// return item
})
// })
const
eventRuleItems
=
event_attr_rule
.
items
.
map
((
item
:
any
)
=>
{
// const eventRuleItems = event_attr_rule.items.map((item: any) => {
item
.
value
=
[
'in'
,
'not in'
].
includes
(
item
.
operate
)
?
item
.
value
.
split
(
','
)
:
item
.
value
// item.value = ['in', 'not in'].includes(item.operate) ? item.value.split(',') : item.value
return
item
// return item
})
// })
Object
.
assign
(
form
,
detail
,
{
user_attr_rule
:
{
...
user_attr_rule
,
attrRuleItems
},
event_attr_rule
:
{
...
event_attr_rule
,
eventRuleItems
}
})
const
rules
=
detail
.
rules
.
length
===
0
?
undefined
:
detail
.
rules
Object
.
assign
(
form
,
{
id
:
props
.
data
.
id
,
rules
})
})
})
}
}
watchEffect
(()
=>
fetchInfo
())
watchEffect
(()
=>
fetchInfo
())
const
rules
=
ref
<
FormRules
>
({
name
:
[{
required
:
true
,
message
:
'请输入标签名称'
}],
type
:
[{
required
:
true
,
message
:
'请选择标签类型'
}]
})
// 提交
// 提交
function
handleSubmit
()
{
function
handleSubmit
()
{
formRef
?.
validate
().
then
(
handleUpdate
)
formRef
?.
validate
().
then
(
handleUpdate
)
...
@@ -65,18 +59,19 @@ function handleSubmit() {
...
@@ -65,18 +59,19 @@ function handleSubmit() {
// 保存
// 保存
function
handleUpdate
()
{
function
handleUpdate
()
{
const
attrRuleItems
=
form
.
user_attr_rule
.
items
.
map
((
item
:
any
)
=>
{
//
const attrRuleItems = form.user_attr_rule.items.map((item: any) => {
item
.
value
=
Array
.
isArray
(
item
.
value
)
?
item
.
value
.
join
(
','
)
:
item
.
value
//
item.value = Array.isArray(item.value) ? item.value.join(',') : item.value
return
item
//
return item
})
//
})
const
eventRuleItems
=
form
.
event_attr_rule
.
items
.
map
((
item
:
any
)
=>
{
//
const eventRuleItems = form.event_attr_rule.items.map((item: any) => {
item
.
value
=
Array
.
isArray
(
item
.
value
)
?
item
.
value
.
join
(
','
)
:
item
.
value
//
item.value = Array.isArray(item.value) ? item.value.join(',') : item.value
return
item
//
return item
})
//
})
const
params
=
{
const
params
=
{
id
:
form
.
id
,
id
:
form
.
id
,
user_attr_rule
:
JSON
.
stringify
([{
...
form
.
user_attr_rule
,
items
:
attrRuleItems
}]),
rules
:
JSON
.
stringify
(
form
.
rules
)
event_attr_rule
:
JSON
.
stringify
([{
...
form
.
event_attr_rule
,
items
:
eventRuleItems
}])
// 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
(()
=>
{
updateLabelRule
(
params
).
then
(()
=>
{
ElMessage
({
message
:
'保存成功'
,
type
:
'success'
})
ElMessage
({
message
:
'保存成功'
,
type
:
'success'
})
...
@@ -94,7 +89,7 @@ function handleUpdate() {
...
@@ -94,7 +89,7 @@ function handleUpdate() {
<el-form-item
label=
"标签名称"
>
{{
data
.
name
}}
</el-form-item>
<el-form-item
label=
"标签名称"
>
{{
data
.
name
}}
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<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-col>
</el-row>
</el-row>
<el-row>
<el-row>
...
@@ -110,11 +105,17 @@ function handleUpdate() {
...
@@ -110,11 +105,17 @@ function handleUpdate() {
</el-col>
</el-col>
</el-row>
</el-row>
</el-form>
</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>
</el-form>
<template
#
footer
>
<template
#
footer
>
<el-row
justify=
"center"
>
<el-row
justify=
"center"
>
...
...
src/modules/label/components/LabelType.vue
浏览文件 @
0dfd43a6
...
@@ -30,7 +30,7 @@ function handleUpdate(row: LabelType) {
...
@@ -30,7 +30,7 @@ function handleUpdate(row: LabelType) {
}
}
// 删除
// 删除
function
handleRemove
(
row
:
LabelType
)
{
function
handleRemove
(
row
:
LabelType
)
{
ElMessageBox
.
confirm
(
'确定要删除该
类型
吗?'
,
'提示'
).
then
(()
=>
{
ElMessageBox
.
confirm
(
'确定要删除该
目录
吗?'
,
'提示'
).
then
(()
=>
{
deleteLabelType
({
id
:
row
.
id
}).
then
(()
=>
{
deleteLabelType
({
id
:
row
.
id
}).
then
(()
=>
{
ElMessage
({
message
:
'删除成功'
,
type
:
'success'
})
ElMessage
({
message
:
'删除成功'
,
type
:
'success'
})
fetchTypeList
()
fetchTypeList
()
...
@@ -40,7 +40,7 @@ function handleRemove(row: LabelType) {
...
@@ -40,7 +40,7 @@ function handleRemove(row: LabelType) {
</
script
>
</
script
>
<
template
>
<
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', '')"
>
<div
class=
"label-type-total"
@
click=
"$emit('select', '')"
>
<h4>
全部标签
</h4>
<h4>
全部标签
</h4>
<p>
{{
labelCount
}}
</p>
<p>
{{
labelCount
}}
</p>
...
...
src/modules/label/components/LabelTypeFormDialog.vue
浏览文件 @
0dfd43a6
...
@@ -14,7 +14,7 @@ const emit = defineEmits<{
...
@@ -14,7 +14,7 @@ const emit = defineEmits<{
}
>
()
}
>
()
const
isUpdate
=
$computed
(()
=>
!!
props
.
data
?.
id
)
const
isUpdate
=
$computed
(()
=>
!!
props
.
data
?.
id
)
const
title
=
$computed
(()
=>
(
isUpdate
?
'修改标签
类型'
:
'新建标签类型
'
))
const
title
=
$computed
(()
=>
(
isUpdate
?
'修改标签
目录'
:
'新建标签目录
'
))
const
formRef
=
$ref
<
FormInstance
>
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
({
id
:
''
,
name
:
''
,
url
:
''
})
const
form
=
reactive
({
id
:
''
,
name
:
''
,
url
:
''
})
...
@@ -24,8 +24,8 @@ watchEffect(() => {
...
@@ -24,8 +24,8 @@ watchEffect(() => {
})
})
const
rules
=
ref
<
FormRules
>
({
const
rules
=
ref
<
FormRules
>
({
name
:
[{
required
:
true
,
message
:
'请输入标签
类型
名称'
}],
name
:
[{
required
:
true
,
message
:
'请输入标签
目录
名称'
}],
url
:
[{
required
:
true
,
message
:
'请选择标签
类型
图标'
}]
url
:
[{
required
:
true
,
message
:
'请选择标签
目录
图标'
}]
})
})
const
iconColorList
=
$ref
([
'#AA593B'
,
'#CD9A23'
,
'#20AE6C'
,
'#196D42'
,
'#614BE8'
,
'#6D4E8B'
,
'#A01578'
,
'#BD2547'
])
const
iconColorList
=
$ref
([
'#AA593B'
,
'#CD9A23'
,
'#20AE6C'
,
'#196D42'
,
'#614BE8'
,
'#6D4E8B'
,
'#A01578'
,
'#BD2547'
])
...
@@ -58,10 +58,10 @@ function handleUpdate() {
...
@@ -58,10 +58,10 @@ function handleUpdate() {
<
template
>
<
template
>
<el-dialog
:title=
"title"
:close-on-click-modal=
"false"
width=
"600px"
@
update:modelValue=
"$emit('update:modelValue')"
>
<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
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-input
v-model=
"form.name"
placeholder=
"请输入"
/>
</el-form-item>
</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-list"
>
<div
<div
class=
"label-type-icon-item"
class=
"label-type-icon-item"
...
...
src/modules/label/components/LabelViewDialog.vue
浏览文件 @
0dfd43a6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
import
type
{
Label
}
from
'../types'
import
type
{
Label
}
from
'../types'
import
{
UserFilled
}
from
'@element-plus/icons-vue'
import
{
UserFilled
}
from
'@element-plus/icons-vue'
import
{
useMapStore
}
from
'@/stores/map'
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
{
getLabelStatistics
,
updateLabelStatistics
}
from
'../api'
import
{
ElMessage
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
...
@@ -36,7 +36,7 @@ function handleUpdate() {
...
@@ -36,7 +36,7 @@ function handleUpdate() {
<el-form-item
label=
"标签名称"
>
{{
data
.
name
}}
</el-form-item>
<el-form-item
label=
"标签名称"
>
{{
data
.
name
}}
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<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-col>
</el-row>
</el-row>
<el-row>
<el-row>
...
@@ -69,14 +69,7 @@ function handleUpdate() {
...
@@ -69,14 +69,7 @@ function handleUpdate() {
<dt>
更新状态
</dt>
<dt>
更新状态
</dt>
<dd>
<dd>
<span
style=
"margin-right: 10px"
>
{{
getNameByValue
(
detail
.
status
,
updateStatusList
)
}}
</span>
<span
style=
"margin-right: 10px"
>
{{
getNameByValue
(
detail
.
status
,
updateStatusList
)
}}
</span>
<el-button
<el-button
type=
"primary"
plain
@
click=
"handleUpdate"
size=
"small"
:disabled=
"['2', '4'].includes(detail.status)"
>
立即更新
</el-button>
type=
"primary"
plain
@
click=
"handleUpdate"
size=
"small"
:disabled=
"['2', '4'].includes(detail.status)"
>
立即更新
</el-button
>
</dd>
</dd>
</dl>
</dl>
</div>
</div>
...
...
src/modules/label/types.ts
浏览文件 @
0dfd43a6
...
@@ -26,6 +26,7 @@ export interface Label {
...
@@ -26,6 +26,7 @@ export interface Label {
created_operator
:
Operator
created_operator
:
Operator
updated_time
:
string
updated_time
:
string
updated_operator
:
Operator
updated_operator
:
Operator
label
:
number
}
}
// 标签更新规则
// 标签更新规则
export
interface
LabelUpdateRule
{
export
interface
LabelUpdateRule
{
...
@@ -35,7 +36,7 @@ export interface LabelUpdateRule {
...
@@ -35,7 +36,7 @@ export interface LabelUpdateRule {
export
type
LabelListRequest
=
Pick
<
Label
,
'id'
|
'name'
>
&
{
experiment_id
?:
string
}
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
experiment_id
?:
string
}
}
...
...
src/modules/label/views/Index.vue
浏览文件 @
0dfd43a6
...
@@ -6,7 +6,7 @@ import LabelType from '../components/LabelType.vue'
...
@@ -6,7 +6,7 @@ import LabelType from '../components/LabelType.vue'
import
{
ElMessageBox
,
ElMessage
}
from
'element-plus'
import
{
ElMessageBox
,
ElMessage
}
from
'element-plus'
import
{
getLabelList
,
deleteLabel
}
from
'../api'
import
{
getLabelList
,
deleteLabel
}
from
'../api'
import
{
useMapStore
}
from
'@/stores/map'
import
{
useMapStore
}
from
'@/stores/map'
import
{
getNameByValue
,
updateStatusRuleList
}
from
'@/utils/dictionary'
import
{
getNameByValue
,
updateStatusRuleList
,
labelList
}
from
'@/utils/dictionary'
import
{
useLabelType
}
from
'../composables/useLabelType'
import
{
useLabelType
}
from
'../composables/useLabelType'
import
SelectUser
from
'@/components/SelectUser.vue'
import
SelectUser
from
'@/components/SelectUser.vue'
...
@@ -31,7 +31,6 @@ const listOptions = computed(() => {
...
@@ -31,7 +31,6 @@ const listOptions = computed(() => {
listParams
.
type_id
=
''
listParams
.
type_id
=
''
}
else
{
}
else
{
params
.
updated_operator
=
listParams
.
updated_operator
params
.
updated_operator
=
listParams
.
updated_operator
params
.
type_id
=
listParams
.
type_id
}
}
return
params
return
params
}
}
...
@@ -41,11 +40,17 @@ const listOptions = computed(() => {
...
@@ -41,11 +40,17 @@ const listOptions = computed(() => {
{
{
type
:
'select'
,
type
:
'select'
,
prop
:
'type_id'
,
prop
:
'type_id'
,
placeholder
:
'请选择标签
类型
'
,
placeholder
:
'请选择标签
目录
'
,
options
:
typeList
.
value
,
options
:
typeList
.
value
,
labelKey
:
'name'
,
labelKey
:
'name'
,
valueKey
:
'id'
valueKey
:
'id'
},
},
{
type
:
'select'
,
prop
:
'label'
,
placeholder
:
'请选择标签类型'
,
options
:
labelList
},
{
type
:
'select'
,
prop
:
'status'
,
placeholder
:
'请选择标签状态'
,
options
:
statusList
},
{
type
:
'select'
,
prop
:
'status'
,
placeholder
:
'请选择标签状态'
,
options
:
statusList
},
{
type
:
'input'
,
prop
:
'updated_operator'
,
placeholder
:
'更新人'
,
slots
:
'filter-user'
}
{
type
:
'input'
,
prop
:
'updated_operator'
,
placeholder
:
'更新人'
,
slots
:
'filter-user'
}
],
],
...
@@ -53,7 +58,14 @@ const listOptions = computed(() => {
...
@@ -53,7 +58,14 @@ const listOptions = computed(() => {
{
label
:
'序号'
,
type
:
'index'
,
width
:
60
},
{
label
:
'序号'
,
type
:
'index'
,
width
:
60
},
{
label
:
'标签ID'
,
prop
:
'id'
},
{
label
:
'标签ID'
,
prop
:
'id'
},
{
label
:
'标签名称'
,
prop
:
'name'
},
{
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
:
'更新频率'
,
label
:
'更新频率'
,
prop
:
'update_status'
,
prop
:
'update_status'
,
...
@@ -117,7 +129,9 @@ function handleRule(row: Label) {
...
@@ -117,7 +129,9 @@ function handleRule(row: Label) {
function
handleSelect
(
id
:
string
)
{
function
handleSelect
(
id
:
string
)
{
listParams
.
type_id
=
id
listParams
.
type_id
=
id
appList
?.
refetch
()
nextTick
(()
=>
{
appList
?.
refetch
()
})
}
}
</
script
>
</
script
>
...
...
src/types.ts
浏览文件 @
0dfd43a6
...
@@ -111,6 +111,25 @@ export interface TagRule {
...
@@ -111,6 +111,25 @@ export interface TagRule {
items
:
string
[]
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
{
export
interface
MaterialProp
{
id
:
string
id
:
string
...
...
src/utils/axios.ts
浏览文件 @
0dfd43a6
...
@@ -18,15 +18,15 @@ httpRequest.interceptors.request.use(
...
@@ -18,15 +18,15 @@ httpRequest.interceptors.request.use(
if
(
config
.
method
===
'get'
)
if
(
config
.
method
===
'get'
)
config
.
params
=
Object
.
assign
({},
config
.
params
,
{
config
.
params
=
Object
.
assign
({},
config
.
params
,
{
experiment_id
:
params
.
get
(
'experiment_id'
),
experiment_id
:
params
.
get
(
'experiment_id'
),
student_id
:
params
.
get
(
'student_id'
),
student_id
:
params
.
get
(
'student_id'
)
||
undefined
,
force_tgc
:
params
.
get
(
'force_tgc'
)
force_tgc
:
params
.
get
(
'force_tgc'
)
||
undefined
})
})
if
(
config
.
method
===
'post'
)
if
(
config
.
method
===
'post'
)
config
.
data
=
Object
.
assign
({},
config
.
data
,
{
config
.
data
=
Object
.
assign
({},
config
.
data
,
{
experiment_id
:
params
.
get
(
'experiment_id'
),
experiment_id
:
params
.
get
(
'experiment_id'
),
student_id
:
params
.
get
(
'student_id'
),
student_id
:
params
.
get
(
'student_id'
)
||
undefined
,
force_tgc
:
params
.
get
(
'force_tgc'
)
force_tgc
:
params
.
get
(
'force_tgc'
)
||
undefined
})
})
return
config
return
config
...
@@ -45,7 +45,7 @@ httpRequest.interceptors.response.use(
...
@@ -45,7 +45,7 @@ httpRequest.interceptors.response.use(
location
.
href
=
`
${
import
.
meta
.
env
.
VITE_LOGIN_URL
}
?rd=
${
encodeURIComponent
(
location
.
href
)}
`
location
.
href
=
`
${
import
.
meta
.
env
.
VITE_LOGIN_URL
}
?rd=
${
encodeURIComponent
(
location
.
href
)}
`
return
Promise
.
reject
(
data
)
return
Promise
.
reject
(
data
)
}
}
if
(
data
.
code
===
1
)
{
if
(
data
.
code
===
1
||
data
.
code
===
-
1
)
{
ElMessage
.
error
(
data
.
message
||
data
.
msg
)
ElMessage
.
error
(
data
.
message
||
data
.
msg
)
return
Promise
.
reject
(
data
)
return
Promise
.
reject
(
data
)
}
}
...
...
src/utils/dictionary.ts
浏览文件 @
0dfd43a6
...
@@ -94,3 +94,15 @@ export const happenInfoList = [
...
@@ -94,3 +94,15 @@ export const happenInfoList = [
]
]
export
const
triggerInfoList
=
[{
label
:
'触发次数'
,
value
:
'触发次数'
}]
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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论