用户画像模型页面

dev-QQq
HeHaonan 2 years ago
parent dc13938f66
commit 0f24285b24

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 973 B

@ -96,6 +96,19 @@ export const constantRoutes = [
},
],
},
{
path: "",
component: Layout,
redirect: "/portraitModel",
children: [
{
path: "/portraitModel",
component: () => import("@/views/portraitModel/index"),
name: "portraitModel",
meta: { title: "用户画像模型", icon: "dashboard", affix: true },
},
],
},
];
// 动态路由,基于用户权限动态去加载

@ -0,0 +1,35 @@
<template>
<div class="main-content">
<el-scrollbar height="680px">
<component :is="currentComponent" ref="content"></component>
</el-scrollbar>
</div>
</template>
<script setup>
const props = defineProps({
currentComponent: {
type: Object,
required: true,
},
});
const content = ref(null);
const consumerLeft = () => {
content.value.consumer();
};
const resLeft = () => {
content.value.practicalTraining();
};
const submitDataLeft = () => {
content.value.submitData();
};
defineExpose({
consumerLeft,
resLeft,
submitDataLeft,
});
</script>
<style lang="scss" scoped>
.main-content {
width: calc(100% - 60px);
}
</style>

@ -259,7 +259,7 @@ const modelTags = ref([
// background-color: #02112e;
background-color: rgba(2, 17, 46, 0.3);
// padding: 20px;
padding-left: 20px;
padding-left: 45px;
padding-right: 20px;
padding-top: 15px;
padding-bottom: 15px;

@ -0,0 +1,9 @@
<template>
<div class="content">
帕累托/ABC分析
</div>
</template>
<script setup></script>
<style scoped lang="scss"></style>

@ -0,0 +1,342 @@
<template>
<div class="content">
<div class="import">
<img src="@/assets/images/导入.png" alt="" />
<span>任务知识导入</span>
</div>
<div class="caseBack">
<div class="title">
<img src="@/assets/images/caseIcon.png" alt="" />
<span>案例背景</span>
</div>
<span style="line-height: 25px; font-size: 14px">
现有以下原始数据需要采用RFM分析方法对客户进行分类
</span>
<div style="margin-top: 10px; display: flex">
<el-table
:data="fileTable1"
style="width: 650px"
border
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column label="用户ID" align="center" prop="userId">
</el-table-column>
<el-table-column label="用户名称" align="center" prop="userName">
</el-table-column>
<el-table-column label="消费时间" align="center" prop="time">
</el-table-column>
<el-table-column label="消费金额" align="center" prop="amount">
</el-table-column>
</el-table>
<div class="download">下载数据</div>
</div>
</div>
<div class="line"></div>
<div class="caseBack">
<div class="title">
<img src="@/assets/images/步骤.png" alt="" />
<span>第一步确定近一段时间的时间间隔</span>
</div>
<span style="line-height: 25px; font-size: 14px">
计划分析最近30天的用户假设现在是2025.05.30需要对数据进行筛选筛选出统计样本
</span>
<div style="margin-top: 10px; display: flex">
<el-table
:data="fileTable1"
style="width: 650px"
border
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column label="用户ID" align="center" prop="userId">
</el-table-column>
<el-table-column label="用户名称" align="center" prop="userName">
</el-table-column>
<el-table-column label="消费时间" align="center" prop="time">
</el-table-column>
<el-table-column label="消费金额" align="center" prop="amount">
</el-table-column>
<el-table-column label="操作" align="center" prop="opr">
<template #default="scope">
<el-select
v-model="scope.row.params"
placeholder="请选择"
style="width: 100px"
>
<el-option :label="'剔除'" :value="'剔除'" />
<el-option :label="'纳入'" :value="'纳入'" />
</el-select>
</template>
</el-table-column>
</el-table>
<div class="submit">提交</div>
</div>
</div>
<div class="line"></div>
<div class="caseBack">
<div class="title">
<img src="@/assets/images/步骤.png" alt="" />
<span>第二步计算每个用户的RFM值</span>
</div>
<span style="line-height: 25px; font-size: 14px">
以用户为统计对象计算出每个用户的RFM这3个指标
</span>
<div style="margin-top: 10px; display: flex">
<el-table
:data="step2Data"
style="width: 650px"
border
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column label="用户ID" align="center" prop="userId">
</el-table-column>
<el-table-column label="用户名称" align="center" prop="userName">
</el-table-column>
<el-table-column label="最近一次消费时间间隔R" align="center">
<template #default="scope">
<el-input
v-model="scope.row.params1"
placeholder="请输入"
style="width: 100px"
>
</el-input>
</template>
</el-table-column>
<el-table-column label="消费频率F" align="center">
<template #default="scope">
<el-input
v-model="scope.row.params2"
placeholder="请输入"
style="width: 100px"
>
</el-input>
</template>
</el-table-column>
<el-table-column label="消费金额M" align="center">
<template #default="scope">
<el-input
v-model="scope.row.params3"
placeholder="请输入"
style="width: 100px"
>
</el-input>
</template>
</el-table-column>
</el-table>
<div class="submit">提交</div>
</div>
</div>
<div class="line"></div>
<div class="caseBack">
<div class="title">
<img src="@/assets/images/步骤.png" alt="" />
<span>第三步制定RFM评分规则</span>
</div>
<span style="line-height: 25px; font-size: 14px">
最近一次消费时间间隔R上一次消费离得越近也就是R的值越小用户价值越高<br />
消费频率F购买频率越高也就是F值越大用户价值越高<br />
消费金额M消费金额越高也就是M值越大用户价值越高<br />
具体实际业务中如何定义打分的范围要根据具体的业务来灵活定没有统一的标准将RFM3个指标分别按价值从小到大分为1-5如下表所示
</span>
<div style="margin-top: 10px; display: flex">
<el-table
:data="step3Data"
style="width: 650px"
border
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column label="按价值打分" align="center" prop="data1">
</el-table-column>
<el-table-column
label="最近一次消费时间间隔(R)"
align="center"
prop="data2"
>
</el-table-column>
<el-table-column label="消费频率(F)" align="center" prop="data3">
</el-table-column>
<el-table-column label="消费金额(M)" align="center" prop="data4">
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script setup>
const fileTable1 = ref([
{
userId: "1",
userName: "小明",
time: "2024.04.28",
amount: "800",
},
{
userId: "2",
userName: "小红",
time: "2024.05.03",
amount: "300",
},
{
userId: "1",
userName: "小明",
time: "2024.05.06",
amount: "3000",
},
{
userId: "1",
userName: "小明",
time: "2024.05.26",
amount: "2000",
},
{
userId: "2",
userName: "小红",
time: "2024.05.27",
amount: "300",
},
{
userId: "2",
userName: "小红",
time: "2024.05.28",
amount: "400",
},
{
userId: "3",
userName: "小李",
time: "2024.05.29",
amount: "500",
},
]);
const step2Data = ref([
{
userId: "1",
userName: "小明",
},
{ userId: "2", userName: "小红" },
{ userId: "3", userName: "小李" },
]);
const step3Data = ref([
{
data1: "1",
data2: "20天以上",
data3: "2次以内",
data4: "1000元以内",
},
{
data1: "2",
data2: "10-20天",
data3: "2-6次",
data4: "1000-1500元",
},
{
data1: "3",
data2: "5-10天",
data3: "6-8次",
data4: "1500-3000元",
},
{
data1: "4",
data2: "3-5天",
data3: "10-20次",
data4: "3000-5000元",
},
{
data1: "5",
data2: "3天以内",
data3: "20次以上",
data4: "5000元以上",
},
]);
</script>
<style scoped lang="scss">
.content {
width: 100%;
background: rgba(0, 29, 64, 0.5);
border: 1px solid #0452c6;
padding: 10px;
// opacity: 0.5;
.import {
display: flex;
font-size: 15px;
font-weight: bold;
width: 180px;
height: 56px;
background-image: url("@/assets/images/01.png");
background-size: 180px 56px;
text-align: center;
align-items: center;
line-height: 56px;
cursor: pointer;
img {
margin-left: 20px;
margin-right: 15px;
}
}
.caseBack {
.title {
font-weight: bold;
margin-top: 10px;
display: flex;
align-items: center;
span {
margin-left: 10px;
}
}
.download {
cursor: pointer;
margin-left: 20px;
color: #000;
padding-left: 10px;
font-size: 14px;
text-align: center;
line-height: 31px;
width: 89px;
height: 31px;
background: url("@/assets/images/downloadIcon.png");
}
.submit {
cursor: pointer;
margin-left: 20px;
color: #000;
padding-left: 10px;
font-size: 14px;
text-align: center;
line-height: 31px;
width: 99px;
height: 31px;
background: url("@/assets/images/提交任务.png");
}
}
.line {
width: 1400px;
height: 1px;
border: 1px solid #0452c6;
opacity: 0.5;
margin-top: 20px;
margin-bottom: 20px;
}
}
::v-deep .el-table tr {
background-color: #002652 !important;
color: #fff;
}
</style>

@ -0,0 +1,440 @@
<template>
<div class="content">
<div class="tabList">
<div
class="tabs"
v-for="item in tabList"
:key="item.id"
@click="changeTab(item)"
>
<div style="display: flex; align-items: center">
<img :src="item.backImg" alt="" />
<span>{{ item.title }}</span>
</div>
</div>
</div>
<div class="container" v-if="menuIndex != 0">
<div class="leftContent">
<div class="title">
<img src="@/assets/images/图标1.png" alt="" />
<span>内置表</span>
</div>
<el-menu
default-active="1"
@open="handleOpen"
@close="handleClose"
@select="handleChange"
background-color="#041C49"
style="border-right: none"
active-text-color="#ffffff"
text-color="#9BD1FF"
>
<el-menu-item index="1">
<span>用户属性表</span>
</el-menu-item>
<el-menu-item index="2">
<span>用户登录活跃表</span>
</el-menu-item>
<el-menu-item index="3">
<span>用户消费能力表</span>
</el-menu-item>
<el-menu-item index="4">
<span>用户行为表</span>
</el-menu-item>
<el-menu-item index="5">
<span>用户评论表</span>
</el-menu-item>
</el-menu>
</div>
<div class="table">
<el-table
v-if="menuIndex == 1"
:data="fileTable"
style="width: 1350px"
:header-cell-style="{
color: '#fff',
fontSize: '14px',
background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`,
}"
>
<el-table-column label="用户ID" align="center" prop="a1">
</el-table-column>
<el-table-column label="登录名" align="center" prop="a1">
</el-table-column>
<el-table-column label="用户姓名" align="center" prop="a1">
</el-table-column>
<el-table-column label="学号" align="center" prop="a1">
</el-table-column>
<el-table-column label="班级" align="center" prop="a1">
</el-table-column>
<el-table-column label="专业" align="center" prop="a1">
</el-table-column>
<el-table-column label="学校" align="center" prop="a1">
</el-table-column>
<el-table-column label="角色名称" align="center" prop="a1">
</el-table-column>
<el-table-column label="角色性别" align="center" prop="a1">
</el-table-column>
<el-table-column label="角色年龄" align="center" prop="a1">
</el-table-column>
<el-table-column label="注册时间" align="center" prop="a1">
</el-table-column>
<el-table-column label="所在地" align="center" prop="a1">
</el-table-column>
</el-table>
<el-table
v-if="menuIndex == 2"
:data="fileTable"
style="width: 1350px"
:header-cell-style="{
color: '#fff',
fontSize: '14px',
background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`,
}"
>
<el-table-column label="用户ID" align="center" prop="a1">
</el-table-column>
<el-table-column label="登录名" align="center" prop="a1">
</el-table-column>
<el-table-column label="用户姓名" align="center" prop="a1">
</el-table-column>
<el-table-column label="学号" align="center" prop="a1">
</el-table-column>
<el-table-column label="班级" align="center" prop="a1">
</el-table-column>
<el-table-column label="专业" align="center" prop="a1">
</el-table-column>
<el-table-column label="学校" align="center" prop="a1">
</el-table-column>
<el-table-column label="角色名称" align="center" prop="a1">
</el-table-column>
<el-table-column label="常登录地" align="center" prop="a1">
</el-table-column>
<el-table-column label="最近登录日期" align="center" prop="a1">
</el-table-column>
<el-table-column label="登录频次" align="center" prop="a1">
</el-table-column>
<el-table-column label="登录时长" align="center" prop="a1">
</el-table-column>
</el-table>
<el-table
v-if="menuIndex == 3"
:data="fileTable"
style="width: 1350px"
:header-cell-style="{
color: '#fff',
fontSize: '14px',
background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`,
}"
>
<el-table-column label="用户ID" align="center" prop="a1">
</el-table-column>
<el-table-column label="登录名" align="center" prop="a1">
</el-table-column>
<el-table-column label="用户姓名" align="center" prop="a1">
</el-table-column>
<el-table-column label="学号" align="center" prop="a1">
</el-table-column>
<el-table-column label="班级" align="center" prop="a1">
</el-table-column>
<el-table-column label="专业" align="center" prop="a1">
</el-table-column>
<el-table-column label="学校" align="center" prop="a1">
</el-table-column>
<el-table-column label="角色名称" align="center" prop="a1">
</el-table-column>
<el-table-column
label="消费商品小类"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="消费商品类型"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="累计消费金额"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="累计消费次数"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="近七天消费金额"
align="center"
prop="a1"
width="130"
>
</el-table-column>
<el-table-column
label="近七天消费次数"
align="center"
prop="a1"
width="130"
>
</el-table-column>
<el-table-column
label="最近消费时间"
align="center"
prop="a1"
width="110"
>
</el-table-column>
</el-table>
<el-table
v-if="menuIndex == 4"
:data="fileTable"
style="width: 1350px"
:header-cell-style="{
color: '#fff',
fontSize: '14px',
background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`,
}"
>
<el-table-column label="用户ID" align="center" prop="a1">
</el-table-column>
<el-table-column label="登录名" align="center" prop="a1">
</el-table-column>
<el-table-column label="用户姓名" align="center" prop="a1">
</el-table-column>
<el-table-column label="学号" align="center" prop="a1">
</el-table-column>
<el-table-column label="班级" align="center" prop="a1">
</el-table-column>
<el-table-column label="专业" align="center" prop="a1">
</el-table-column>
<el-table-column label="学校" align="center" prop="a1">
</el-table-column>
<el-table-column label="角色名称" align="center" prop="a1">
</el-table-column>
<el-table-column
label="商品名称"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="商品小类"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="商品类型"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="用户行为类型"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="行为日期"
align="center"
prop="a1"
width="130"
>
</el-table-column>
</el-table>
</div>
</div>
<main-content
v-if="menuIndex == 0"
:currentComponent="currentComponent"
></main-content>
</div>
</template>
<script setup>
import mainContent from "@/views/components/mainContent.vue";
import rfmAnalysis from "./components/rfmAnalysis.vue";
import abcAnalysis from "./components/abcAnalysis.vue";
const currentComponent = ref(null);
const menuIndex = ref(1);
const tabIndex = ref(0);
const fileTable = ref([
{
a1: "666",
},
{
a1: "111",
},
]);
const tabList = ref([
{
id: "1",
key: rfmAnalysis,
title: "RFM分析",
backImg: "src/assets/images/icon1.png",
},
{
id: "2",
key: abcAnalysis,
title: "帕累托/ABC分析",
backImg: "src/assets/images/icon2.png",
},
{
id: "3",
title: "波士顿矩阵分析",
backImg: "src/assets/images/icon3.png",
},
{
id: "4",
title: "转化分析-漏斗模型",
backImg: "src/assets/images/icon4.png",
},
{
id: "5",
title: "购物篮分析",
backImg: "src/assets/images/icon5.png",
},
{
id: "6",
title: "复购分析",
backImg: "src/assets/images/icon6.png",
},
{
id: "7",
title: "留存分析",
backImg: "src/assets/images/icon7.png",
},
{
id: "8",
title: "用户粘性分析",
backImg: "src/assets/images/icon8.png",
},
{
id: "9",
title: "AARRR用户运营分析",
backImg: "src/assets/images/icon9.png",
},
{
id: "10",
title: "用户画像分析",
backImg: "src/assets/images/icon10.png",
},
]);
const handleChange = (index) => {
console.log(index);
menuIndex.value = index;
};
const changeTab = (item) => {
currentComponent.value = item.key;
menuIndex.value = 0;
// tabIndex = item.id;
};
</script>
<style lang="scss" scoped>
.content {
color: #fff;
.tabList {
// display: flex;
width: 1060px;
.tabs {
cursor: pointer;
font-size: 14px;
margin-right: 20px;
margin-bottom: 20px;
width: 188px;
height: 61px;
background-image: url("@/assets/images/itembg1.png");
// display: flex;
// justify-content: center;
// align-items: center;
padding-left: 30px;
line-height: 60px;
display: inline-block;
img {
margin-right: 15px;
}
}
.tabs:nth-of-type(2),
.tabs:nth-of-type(9) {
background-image: url("@/assets/images/itembg2.png");
}
.tabs:nth-of-type(3),
.tabs:nth-of-type(10) {
background-image: url("@/assets/images/itembg3.png");
}
.tabs:nth-of-type(4),
.tabs:nth-of-type(6) {
background-image: url("@/assets/images/itembg4.png");
}
.tabs:nth-of-type(5),
.tabs:nth-of-type(7) {
background-image: url("@/assets/images/itembg5.png");
}
.tabs:nth-of-type(8) {
background-image: url("@/assets/images/itembg1.png");
}
.tabs:nth-of-type(4),
.tabs:nth-of-type(9) {
padding-left: 20px;
img {
margin-right: 5px;
}
}
}
.container {
display: flex;
.leftContent {
width: 205px;
height: 691px;
background: #041c49;
border: 1px solid #063373;
.title {
padding-left: 10px;
display: flex;
align-items: center;
font-size: 18px;
color: #3596eb;
font-weight: bold;
height: 50px;
border-bottom: 1px solid #063373;
span {
margin-left: 10px;
}
}
.el-menu-item {
padding-left: 40px;
height: 40px;
}
}
.table {
margin-left: 20px;
}
}
}
.el-menu-item.is-active {
// color: var(--el-menu-active-color);
background-color: #1983dd !important;
}
::v-deep .el-table tr {
background-color: #002652 !important;
color: #fff;
}
::v-deep .el-table--enable-row-hover .el-table__body tr:hover > td {
background-color: #0077dd !important;
/* color: #fff; */
}
</style>
Loading…
Cancel
Save