Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-dml
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-dml
Commits
4e99f391
提交
4e99f391
authored
6月 04, 2024
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: RFM优化
上级
68fd12c1
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
97 行增加
和
15 行删除
+97
-15
rfm.ts
src/api/rfm.ts
+5
-0
LabelRule.vue
src/components/rule/LabelRule.vue
+36
-8
RFMRule.vue
src/components/rule/RFMRule.vue
+18
-3
RFMRuleItem.vue
src/components/rule/RFMRuleItem.vue
+14
-2
useRFMData.ts
src/composables/useRFMData.ts
+23
-1
LabelRuleDialog.vue
src/modules/label/components/LabelRuleDialog.vue
+1
-1
没有找到文件。
src/api/rfm.ts
浏览文件 @
4e99f391
...
@@ -19,3 +19,8 @@ export function getMemberAttrRange(params: { member_meta_id: string }) {
...
@@ -19,3 +19,8 @@ export function getMemberAttrRange(params: { member_meta_id: string }) {
export
function
getRfmRes
()
{
export
function
getRfmRes
()
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/group/bda-rfm-res'
)
return
httpRequest
.
get
(
'/api/lab/v1/experiment/group/bda-rfm-res'
)
}
}
// 获取最近一次Rfm标签的统计结果
export
function
getRfmStatistics
(
params
:
{
tag_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/tag/bda-rfm-statistics-result'
,
{
params
})
}
src/components/rule/LabelRule.vue
浏览文件 @
4e99f391
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
type
{
TagRule
}
from
'@/types'
import
type
{
TagRule
}
from
'@/types'
import
{
PriceTag
,
Plus
,
CloseBold
}
from
'@element-plus/icons-vue'
import
{
PriceTag
,
Plus
,
CloseBold
,
QuestionFilled
}
from
'@element-plus/icons-vue'
import
{
useTag
}
from
'@/composables/useAllData'
import
{
useTag
}
from
'@/composables/useAllData'
import
{
useRfmRes
}
from
'@/composables/useRFMData'
import
{
useRfmRes
}
from
'@/composables/useRFMData'
...
@@ -38,6 +38,23 @@ function handleRfmChange(rfmKey: string, item: any) {
...
@@ -38,6 +38,23 @@ function handleRfmChange(rfmKey: string, item: any) {
const
found
=
rfmResList
.
value
.
find
(
item
=>
item
.
frm_key
===
rfmKey
)
const
found
=
rfmResList
.
value
.
find
(
item
=>
item
.
frm_key
===
rfmKey
)
item
.
rfm_value
=
found
?.
frm_value
item
.
rfm_value
=
found
?.
frm_value
}
}
const
a
=
[
{
label
:
'重要价值用户'
,
r
:
'高'
,
f
:
'高'
,
m
:
'高'
,
group
:
'最近一次消费时间近,消费频率高,消费金额大'
,
guide
:
'重点维系和保持'
},
{
label
:
'重要发展用户'
,
r
:
'高'
,
f
:
'低'
,
m
:
'高'
,
group
:
'最近一次消费时间较近,消费频率高,消费金额大'
,
guide
:
'促进其持续消费'
},
{
label
:
'重要保持用户'
,
r
:
'低'
,
f
:
'高'
,
m
:
'高'
,
group
:
'最近一次消费时间较远,消费频率低,消费金额大'
,
guide
:
'尽快采取措施挽回'
},
{
label
:
'重要挽留用户'
,
r
:
'低'
,
f
:
'低'
,
m
:
'高'
,
group
:
'最近一次消费时间远,消费频率高,消费金额低'
,
guide
:
'引导其提升消费水平'
},
{
label
:
'一般价值用户'
,
r
:
'高'
,
f
:
'高'
,
m
:
'低'
,
group
:
'最近一次消费时间近,消费频率低,消费金额大'
,
guide
:
'尝试提高其消费频率'
},
{
label
:
'一般发展用户'
,
r
:
'高'
,
f
:
'低'
,
m
:
'低'
,
group
:
'最近一次消费时间近,消费频率高,消费金额低'
,
guide
:
'可考虑通过提升产品或服务质量来提高其消费水平'
},
{
label
:
'一般保持用户'
,
r
:
'低'
,
f
:
'高'
,
m
:
'低'
,
group
:
'最近一次消费时间远,消费频率低,消费金额低'
,
guide
:
'根据资源和战略考虑是否进行挽回'
},
{
label
:
'一般挽留用户'
,
r
:
'低'
,
f
:
'低'
,
m
:
'低'
,
group
:
'最近一次消费时间近,消费频率低,消费金额低'
,
guide
:
'根据其消费习惯和变化进行适当调整'
}
]
</
script
>
</
script
>
<
template
>
<
template
>
...
@@ -58,13 +75,24 @@ function handleRfmChange(rfmKey: string, item: any) {
...
@@ -58,13 +75,24 @@ function handleRfmChange(rfmKey: string, item: any) {
<el-select
v-model=
"item.tag_id"
style=
"width: 400px"
>
<el-select
v-model=
"item.tag_id"
style=
"width: 400px"
>
<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-select>
<el-select
<
template
v-if=
"showRfm(item.tag_id)"
>
v-model=
"item.rfm_key"
<el-select
v-model=
"item.rfm_key"
@
change=
"value => handleRfmChange(value, item)"
style=
"width: 200px; margin-left: 10px"
>
@
change=
"value => handleRfmChange(value, item)"
<el-option
v-for=
"item in rfmResList"
:key=
"item.frm_key"
:label=
"item.frm_value"
:value=
"item.frm_key"
></el-option>
v-if=
"showRfm(item.tag_id)"
</el-select>
style=
"width: 200px; margin-left: 10px"
>
<el-popover
popper-class=
"rfm-popover"
placement=
"top"
:width=
"800"
trigger=
"hover"
>
<el-option
v-for=
"item in rfmResList"
:key=
"item.frm_key"
:label=
"item.frm_value"
:value=
"item.frm_key"
></el-option>
<el-table
:data=
"a"
border
stripe
>
</el-select>
<el-table-column
prop=
"label"
label=
"标签值"
width=
"110"
/>
<el-table-column
prop=
"r"
label=
"R"
width=
"40"
/>
<el-table-column
prop=
"f"
label=
"F"
width=
"40"
/>
<el-table-column
prop=
"m"
label=
"M"
width=
"40"
/>
<el-table-column
prop=
"group"
label=
"运营群组"
/>
<el-table-column
prop=
"guide"
label=
"营销策略建议"
/>
</el-table>
<template
#
reference
>
<el-icon><QuestionFilled
/></el-icon>
</
template
>
</el-popover>
</template>
</el-form-item>
</el-form-item>
</div>
</div>
<el-button
text
:icon=
"CloseBold"
@
click=
"handleRemove(tagRule.items, index)"
></el-button>
<el-button
text
:icon=
"CloseBold"
@
click=
"handleRemove(tagRule.items, index)"
></el-button>
...
...
src/components/rule/RFMRule.vue
浏览文件 @
4e99f391
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
RFMRuleItem
from
'./RFMRuleItem.vue'
import
RFMRuleItem
from
'./RFMRuleItem.vue'
import
{
useRfmStatistics
}
from
'@/composables/useRFMData'
const
props
=
defineProps
<
{
tagId
?:
string
}
>
()
const
form
=
defineModel
<
any
>
({
const
form
=
defineModel
<
any
>
({
default
:
{
default
:
{
R
:
{},
R
:
{},
...
@@ -8,10 +10,23 @@ const form = defineModel<any>({
...
@@ -8,10 +10,23 @@ const form = defineModel<any>({
M
:
{}
M
:
{}
}
}
})
})
const
{
rfmStatistics
}
=
useRfmStatistics
(
props
.
tagId
||
''
)
</
script
>
</
script
>
<
template
>
<
template
>
<RFMRuleItem
label=
"R"
v-model=
"form.R"
/>
<RFMRuleItem
label=
"R"
v-model=
"form.R"
>
<RFMRuleItem
label=
"F"
v-model=
"form.F"
style=
"margin-top: 20px"
/>
<template
#
header-aside=
"
{ data }">
<RFMRuleItem
label=
"M"
v-model=
"form.M"
style=
"margin-top: 20px"
/>
<template
v-if=
"data.rule === '101' && rfmStatistics.is_complete"
>
R值计算结果为:
{{
rfmStatistics
.
rfm_tag_res
.
r
}}
</
template
>
</template>
</RFMRuleItem>
<RFMRuleItem
label=
"F"
v-model=
"form.F"
style=
"margin-top: 20px"
>
<
template
#
header-aside=
"{ data }"
>
<template
v-if=
"data.rule === '101' && rfmStatistics.is_complete"
>
F值计算结果为:
{{
rfmStatistics
.
rfm_tag_res
.
f
}}
</
template
>
</template>
</RFMRuleItem>
<RFMRuleItem
label=
"M"
v-model=
"form.M"
style=
"margin-top: 20px"
>
<
template
#
header-aside=
"{ data }"
>
<template
v-if=
"data.rule === '101' && rfmStatistics.is_complete"
>
M值计算结果为:
{{
rfmStatistics
.
rfm_tag_res
.
m
}}
</
template
>
</template>
</RFMRuleItem>
</template>
</template>
src/components/rule/RFMRuleItem.vue
浏览文件 @
4e99f391
...
@@ -116,8 +116,15 @@ const a = [
...
@@ -116,8 +116,15 @@ const a = [
<
template
>
<
template
>
<el-card
shadow=
"never"
>
<el-card
shadow=
"never"
>
<template
#
header
>
<template
#
header
>
<el-button
circle
type=
"primary"
style=
"width: 32px; margin-right: 10px"
>
{{
label
}}
</el-button>
<div
class=
"rfm-top"
>
{{
label
}}
值计算规则
<div>
<el-button
circle
type=
"primary"
style=
"width: 32px; margin-right: 10px"
>
{{
label
}}
</el-button>
{{
label
}}
值计算规则
</div>
<div>
<slot
name=
"header-aside"
:data=
"form"
></slot>
</div>
</div>
</
template
>
</
template
>
<div
class=
"rfm-header"
>
<div
class=
"rfm-header"
>
<p
style=
"margin-right: 10px"
>
{{ label }}值计算依据
</p>
<p
style=
"margin-right: 10px"
>
{{ label }}值计算依据
</p>
...
@@ -198,6 +205,11 @@ const a = [
...
@@ -198,6 +205,11 @@ const a = [
</template>
</template>
<
style
lang=
"scss"
>
<
style
lang=
"scss"
>
.rfm-top
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
}
.rfm-header
{
.rfm-header
{
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
...
...
src/composables/useRFMData.ts
浏览文件 @
4e99f391
import
{
getMemberAttrList
,
getEventAttrList
,
getMemberAttrRange
,
getRfmRes
}
from
'@/api/rfm'
import
{
getMemberAttrList
,
getEventAttrList
,
getMemberAttrRange
,
getRfmRes
,
getRfmStatistics
}
from
'@/api/rfm'
// 用户属性类型
// 用户属性类型
export
interface
AttrType
{
export
interface
AttrType
{
...
@@ -67,3 +67,25 @@ export function useRfmRes() {
...
@@ -67,3 +67,25 @@ export function useRfmRes() {
})
})
return
{
fetchRfmResList
,
rfmResList
}
return
{
fetchRfmResList
,
rfmResList
}
}
}
interface
RfmStatistics
{
is_complete
:
boolean
rfm_tag_res
:
{
r
:
number
f
:
number
m
:
number
}
}
const
rfmStatistics
=
ref
<
RfmStatistics
>
({
is_complete
:
false
,
rfm_tag_res
:
{
r
:
0
,
f
:
0
,
m
:
0
}
})
export
function
useRfmStatistics
(
tagId
:
string
)
{
async
function
fetchRfmStatistics
()
{
if
(
!
tagId
)
return
await
getRfmStatistics
({
tag_id
:
tagId
}).
then
((
res
:
any
)
=>
{
rfmStatistics
.
value
=
res
.
data
})
}
onMounted
(()
=>
{
fetchRfmStatistics
()
})
return
{
fetchRfmStatistics
,
rfmStatistics
}
}
src/modules/label/components/LabelRuleDialog.vue
浏览文件 @
4e99f391
...
@@ -146,7 +146,7 @@ function handleUpdate() {
...
@@ -146,7 +146,7 @@ function handleUpdate() {
<!-- 事件指标 -->
<!-- 事件指标 -->
<EventTargetRule
v-model=
"form.rules"
v-if=
"data.label == '3'"
></EventTargetRule>
<EventTargetRule
v-model=
"form.rules"
v-if=
"data.label == '3'"
></EventTargetRule>
<!-- RFM模型 -->
<!-- RFM模型 -->
<RFMRule
v-model=
"form.rules"
v-if=
"data.label == '4'"
></RFMRule>
<RFMRule
v-model=
"form.rules"
:tagId=
"form.id"
v-if=
"data.label == '4'"
></RFMRule>
<!-- 自定义 -->
<!-- 自定义 -->
<CustomRule
v-model=
"form.rules"
v-if=
"data.label == '7'"
></CustomRule>
<CustomRule
v-model=
"form.rules"
v-if=
"data.label == '7'"
></CustomRule>
<!-- 单属性 -->
<!-- 单属性 -->
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论