|
|
<template>
|
|
|
<div class="content">
|
|
|
<div class="import" @click="dialogVisible = true">
|
|
|
<img src="@/assets/images/导入.png" alt="" />
|
|
|
<span>任务知识导入</span>
|
|
|
</div>
|
|
|
<!-- <div v-html="knowledge" v-if="knowledgeFlag"></div> -->
|
|
|
<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: 550px"
|
|
|
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" @click="downloadData">下载数据</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" @click="step1Submit">提交</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、F、M这3个指标
|
|
|
</span>
|
|
|
<div style="margin-top: 10px; display: flex">
|
|
|
<el-table
|
|
|
:data="step2Data"
|
|
|
style="width: 720px"
|
|
|
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"
|
|
|
width="210"
|
|
|
>
|
|
|
<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" @click="step2Submit">提交</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="line"></div>
|
|
|
<div class="caseBack">
|
|
|
<div class="title">
|
|
|
<img src="@/assets/images/步骤.png" alt="" />
|
|
|
<span>第三步,制定R、F、M评分规则</span>
|
|
|
</div>
|
|
|
<span style="line-height: 25px; font-size: 14px">
|
|
|
最近一次消费时间间隔(R),上一次消费离得越近,也就是R的值越小,用户价值越高。<br />
|
|
|
消费频率(F),购买频率越高,也就是F值越大,用户价值越高。<br />
|
|
|
消费金额(M),消费金额越高,也就是M值越大,用户价值越高。<br />
|
|
|
具体实际业务中,如何定义打分的范围,要根据具体的业务来灵活定,没有统一的标准。将R、F、M3个指标分别按价值从小到大分为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"
|
|
|
width="210"
|
|
|
>
|
|
|
</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 class="line"></div>
|
|
|
<div class="caseBack">
|
|
|
<div class="title">
|
|
|
<img src="@/assets/images/步骤.png" alt="" />
|
|
|
<span>第四步,给R、F、M按价值打分</span>
|
|
|
</div>
|
|
|
<span style="line-height: 25px; font-size: 14px">
|
|
|
按照第二步统计的数值,结合第三步的评估规则,对用户R、F、M值进行评分
|
|
|
</span>
|
|
|
<div style="margin-top: 10px; display: flex">
|
|
|
<el-table
|
|
|
:data="step4Data"
|
|
|
style="width: 1080px"
|
|
|
border
|
|
|
:header-cell-style="{
|
|
|
color: '#fff',
|
|
|
fontSize: '14px',
|
|
|
backgroundColor: '#6A7DE9!important',
|
|
|
}"
|
|
|
>
|
|
|
<el-table-column
|
|
|
label="用户ID"
|
|
|
align="center"
|
|
|
prop="data1"
|
|
|
width="70"
|
|
|
>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="用户名称" align="center" prop="data2">
|
|
|
</el-table-column>
|
|
|
<el-table-column
|
|
|
label="最近一次消费时间间隔(R)"
|
|
|
align="center"
|
|
|
prop="data3"
|
|
|
width="210"
|
|
|
>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="消费频率(F)" align="center" prop="data4">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="消费金额(M)" align="center" prop="data5">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="R值打分" align="center" prop="data4">
|
|
|
<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" prop="data4">
|
|
|
<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" prop="data4">
|
|
|
<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" @click="step4Submit">提交</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="line"></div>
|
|
|
<div class="caseBack">
|
|
|
<div class="title">
|
|
|
<img src="@/assets/images/步骤.png" alt="" />
|
|
|
<span>第五步,计算所有用户R、F、M打分值的平均数</span>
|
|
|
</div>
|
|
|
<span style="line-height: 25px; font-size: 14px">
|
|
|
按照第四步给各个用户R、F、M的打分值,分别计算各自的平均数(小数点后保留两位小数)
|
|
|
</span>
|
|
|
<div style="margin-top: 10px; display: flex">
|
|
|
<el-table
|
|
|
:data="step5Data"
|
|
|
style="width: 680px"
|
|
|
border
|
|
|
:header-cell-style="{
|
|
|
color: '#fff',
|
|
|
fontSize: '14px',
|
|
|
backgroundColor: '#6A7DE9!important',
|
|
|
}"
|
|
|
>
|
|
|
<el-table-column label="" align="center" prop="title" />
|
|
|
<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" @click="step5Submit">提交</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="line"></div>
|
|
|
<div class="caseBack">
|
|
|
<div class="title">
|
|
|
<img src="@/assets/images/步骤.png" alt="" />
|
|
|
<span>第六步,计算所有用户R、F、M打分值与平均数的高低情况</span>
|
|
|
</div>
|
|
|
<span style="line-height: 25px; font-size: 14px">
|
|
|
判断每个用户的价值值R、F、M3个值是高于平均值,还是低于平均值。如果一行里的R值打分大于平均值,就在R值高低列里记录为“高”,否则记录为“低”
|
|
|
</span>
|
|
|
<div style="margin-top: 10px; display: flex">
|
|
|
<el-table
|
|
|
:data="step6Data"
|
|
|
:span-method="tableSpanMethod"
|
|
|
style="width: 980px"
|
|
|
border
|
|
|
:header-cell-style="{
|
|
|
color: '#fff',
|
|
|
fontSize: '14px',
|
|
|
backgroundColor: '#6A7DE9!important',
|
|
|
}"
|
|
|
>
|
|
|
<el-table-column label="用户ID" align="center" prop="data1" />
|
|
|
<el-table-column label="用户名称" align="center" prop="data2" />
|
|
|
<el-table-column label="R值打分" align="center" prop="data3">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="F值打分" align="center" prop="data4">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="M值打分" align="center" prop="data5">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="R值高低" align="center" width="130">
|
|
|
<template #default="scope">
|
|
|
<!-- <el-input
|
|
|
v-model="scope.row.params1"
|
|
|
placeholder="请输入"
|
|
|
style="width: 100px"
|
|
|
v-if="scope.$index != 3"
|
|
|
>
|
|
|
</el-input> -->
|
|
|
<el-select
|
|
|
v-model="scope.row.params1"
|
|
|
placeholder="请选择"
|
|
|
style="width: 100px"
|
|
|
v-if="scope.$index != 3"
|
|
|
>
|
|
|
<el-option :label="'高'" :value="'高'" />
|
|
|
<el-option :label="'低'" :value="'低'" />
|
|
|
</el-select>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="F值高低" align="center" width="130">
|
|
|
<template #default="scope">
|
|
|
<!-- <el-input
|
|
|
v-model="scope.row.params2"
|
|
|
placeholder="请输入"
|
|
|
style="width: 100px"
|
|
|
v-if="scope.$index != 3"
|
|
|
>
|
|
|
</el-input> -->
|
|
|
<el-select
|
|
|
v-model="scope.row.params2"
|
|
|
placeholder="请选择"
|
|
|
style="width: 100px"
|
|
|
v-if="scope.$index != 3"
|
|
|
>
|
|
|
<el-option :label="'高'" :value="'高'" />
|
|
|
<el-option :label="'低'" :value="'低'" />
|
|
|
</el-select>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="M值高低" align="center" width="130">
|
|
|
<template #default="scope">
|
|
|
<!-- <el-input
|
|
|
v-model="scope.row.params3"
|
|
|
placeholder="请输入"
|
|
|
style="width: 100px"
|
|
|
v-if="scope.$index != 3"
|
|
|
>
|
|
|
</el-input> -->
|
|
|
<el-select
|
|
|
v-model="scope.row.params3"
|
|
|
placeholder="请选择"
|
|
|
style="width: 100px"
|
|
|
v-if="scope.$index != 3"
|
|
|
>
|
|
|
<el-option :label="'高'" :value="'高'" />
|
|
|
<el-option :label="'低'" :value="'低'" />
|
|
|
</el-select>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
<div class="submit" @click="step6Submit">提交</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">
|
|
|
按照用户分类表格里定义的规则进行比较,就可以得出用户属于哪种类。
|
|
|
</span>
|
|
|
<div style="text-align: center; width: 800px">
|
|
|
<p>用户分类规则</p>
|
|
|
<el-table
|
|
|
:data="rulesTable"
|
|
|
style="width: 800px"
|
|
|
border
|
|
|
:header-cell-style="{
|
|
|
color: '#fff',
|
|
|
fontSize: '14px',
|
|
|
backgroundColor: '#6A7DE9!important',
|
|
|
}"
|
|
|
>
|
|
|
<el-table-column label="用户分类" align="center" prop="data1" />
|
|
|
<el-table-column
|
|
|
label="最近一次消费时间间隔(R)"
|
|
|
align="center"
|
|
|
prop="data2"
|
|
|
width="220"
|
|
|
/>
|
|
|
<el-table-column
|
|
|
label="消费频率(F)"
|
|
|
align="center"
|
|
|
prop="data3"
|
|
|
/>
|
|
|
<el-table-column
|
|
|
label="消费金额(M)"
|
|
|
align="center"
|
|
|
prop="data4"
|
|
|
/>
|
|
|
</el-table>
|
|
|
</div>
|
|
|
<div style="margin-top: 10px; display: flex">
|
|
|
<el-table
|
|
|
:data="step7Data"
|
|
|
style="width: 980px"
|
|
|
border
|
|
|
:header-cell-style="{
|
|
|
color: '#fff',
|
|
|
fontSize: '14px',
|
|
|
backgroundColor: '#6A7DE9!important',
|
|
|
}"
|
|
|
>
|
|
|
<el-table-column label="用户ID" align="center" prop="data1" />
|
|
|
<el-table-column label="用户名称" align="center" prop="data2" />
|
|
|
<el-table-column label="R值高低" align="center" prop="data3">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="F值高低" align="center" prop="data4">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="M值高低" align="center" prop="data5">
|
|
|
</el-table-column>
|
|
|
<el-table-column label="用户分类" align="center" width="200">
|
|
|
<template #default="scope">
|
|
|
<el-select
|
|
|
v-model="scope.row.params"
|
|
|
placeholder="请选择"
|
|
|
style="width: 170px"
|
|
|
>
|
|
|
<el-option
|
|
|
:label="item.label"
|
|
|
:value="item.value"
|
|
|
v-for="item in classifyList"
|
|
|
:key="item.value"
|
|
|
/>
|
|
|
</el-select>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
<div class="submit" @click="step7Submit">提交</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">
|
|
|
对用户分类以后要做什么呢?那就是针对每类用户如何制定运营策略,这个具体公司业务不同,方法也不一样。这里举例说明前4类用户。
|
|
|
</span>
|
|
|
<div class="customerType">
|
|
|
<img src="@/assets/images/icon001.png" alt="" />
|
|
|
<span>重要价值用户,RFM三个值都很高,要提供VIP服务</span>
|
|
|
</div>
|
|
|
<div class="customerType">
|
|
|
<img src="@/assets/images/icon002.png" alt="" />
|
|
|
<span
|
|
|
>重要发展用户,消费频率低,但是其他两个值很高,就要想办法提高他的消费频率。</span
|
|
|
>
|
|
|
</div>
|
|
|
<div class="customerType">
|
|
|
<img src="@/assets/images/icon003.png" alt="" />
|
|
|
<span
|
|
|
>重要保持用户,最近消费距离现在时间较远,也就是F值低,但是消费频次和消费金额高。这种用户,是一段时间没来的忠实客户。应该主动和他保持联系,提高复购率。</span
|
|
|
>
|
|
|
</div>
|
|
|
<div class="customerType">
|
|
|
<img src="@/assets/images/icon004.png" alt="" />
|
|
|
<span
|
|
|
>重要挽留客户,最近消费时间距离现在较远、消费频率低,但消费金额高。这种用户,即将流失,要主动联系用户,调查清楚哪里出了问题,并想办法挽回。</span
|
|
|
>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<el-dialog
|
|
|
v-model="dialogVisible"
|
|
|
title="任务知识导入"
|
|
|
style="width: 1108px; height: 798px"
|
|
|
custom-class="dialogClass"
|
|
|
:show-close="false"
|
|
|
class="dialog"
|
|
|
>
|
|
|
<template #header="{ close, titleId, titleClass }">
|
|
|
<div class="my-header">
|
|
|
<span :id="titleId" :class="titleClass">任务知识导入</span>
|
|
|
<img
|
|
|
class="gbImg"
|
|
|
src="../../../assets/images/关闭.png"
|
|
|
@click="close"
|
|
|
alt=""
|
|
|
/>
|
|
|
</div>
|
|
|
<img class="xtImg" src="../../../assets/images/线条.png" alt="" />
|
|
|
</template>
|
|
|
<div
|
|
|
style="
|
|
|
color: #fff;
|
|
|
margin-top: -35px;
|
|
|
padding: 10px;
|
|
|
padding-left: 20px;
|
|
|
"
|
|
|
>
|
|
|
<el-scrollbar height="650px">
|
|
|
<div v-html="knowledge"></div>
|
|
|
</el-scrollbar>
|
|
|
</div>
|
|
|
<!-- <template #footer>
|
|
|
<div class="dialog-footer">
|
|
|
<el-button @click="dialogVisible = false">确定</el-button>
|
|
|
<el-button type="primary" @click="dialogVisible = false">
|
|
|
返回
|
|
|
</el-button>
|
|
|
</div>
|
|
|
</template> -->
|
|
|
</el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import { getUserInfo } from "@/utils/auth";
|
|
|
import * as portraitModel from "@/api/portraitModel";
|
|
|
import { downBlobFile } from "@/utils/index.js";
|
|
|
import { onBeforeUnmount, onMounted } from "vue";
|
|
|
// const baseURL = "http://192.168.2.16:9868/";
|
|
|
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
|
|
const dialogVisible = ref(false);
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
const errorNum = ref(0); //总错误次数
|
|
|
const stepError1 = ref(0);
|
|
|
const stepError2 = ref(0);
|
|
|
const step3Error = ref(0);
|
|
|
const step4Error = ref(0);
|
|
|
const step5Error = ref(0);
|
|
|
const step6Error = ref(0);
|
|
|
const step7Error = ref(0);
|
|
|
//判断每一步是否提交
|
|
|
const step1AnswerFlag = ref(false);
|
|
|
const step2AnswerFlag = ref(false);
|
|
|
const step4AnswerFlag = ref(false);
|
|
|
const step5AnswerFlag = ref(false);
|
|
|
const step6AnswerFlag = ref(false);
|
|
|
const step7AnswerFlag = ref(false);
|
|
|
const knowledgeFlag = ref(false);
|
|
|
const knowledge = ref(
|
|
|
'<p style="text-align: start;"><strong>1.什么是RFM分析方法?</strong></p><p style="text-align: start;"><img src="https://pic1.zhimg.com/80/v2-706d62e4bc20f677b4dca950b09d05e8_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;">RFM是3个指标的缩写,最近一次消费时间间隔(Recency),消费频率(Frequency),消费金额(Monetary)。通过这3个指标对用户分类。</p><p style="text-align: start;">这里举个例子来说明这3个指标是什么意思。</p><p style="text-align: start;">比如我有一家店铺,小明是这家店铺的用户。现在是这个月的30号。</p><p style="text-align: start;">1)最近1次消费时间间隔(R)是指用户最近一次消费距离现在多长时间了。</p><p style="text-align: start;">小明最近1次在这就店铺买东西是这个月25号,上一次消费距离现在过去了5天,所以小明的最近1次消费时间间隔是5天。</p><p style="text-align: start;">2)消费频率(F)是指用户一段时间内消费了多少次。</p><p style="text-align: start;">比如“一段时间”定义是最近30天,发现小明最近30天在店铺消费了3次。</p><p style="text-align: start;">3)消费金额(M)是指用户一段时间内的消费金额。</p><p style="text-align: start;">比如“一段时间”是最近30天,发现小明最近30天总共在店铺消费了1000元。</p><p style="text-align: start;">这3个指标业务不同,定义也不同,要根据业务来灵活定义。</p><p style="text-align: start;">最近一次消费时间间隔(R),上一次消费离得越近,也就是R的值越小,用户价值越高。</p><p style="text-align: start;">消费频率(F),购买频率越高,也就是F的值越大,用户价值越高。</p><p style="text-align: start;">消费金额(M),消费金额越高,也就是M的值越大,用户价值越高。</p><p style="text-align: start;">我们把这3个指标按价值从低到高排序,并把这3个指标作为XYZ坐标轴,就可以把空间分为8部分,这样就可以把用户分为下图的8类。</p><p style="text-align: start;"><img src="https://pic4.zhimg.com/80/v2-81a7b7fcf8e7eac1fec021df9b588ba7_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;">我们把这个图里对应的RFM这3个值对应的价值是高还是低,对应到下面这张表里就得到了用户分类的规则。</p><p style="text-align: start;"><img src="https://pic2.zhimg.com/80/v2-56b745a6b404767a24a07b0d9ba7f469_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>2.RFM分析方法有什么用?</strong></p><p style="text-align: start;">小明的店铺某个月收入大幅下跌。他赶快分析数据,发行原来几个重要的用户被竞争对手挖走了,而这几个用户贡献了店铺80%的收入。</p><p style="text-align: start;">出现这个问题,是因为小明没有对用户分类,对全部用户采取的都是一样的运营决策。怎么对用户分类,识别出有价值的用户呢?</p><p style="text-align: start;">这时候就可以用RFM分析方法把用户分为8类,这样就可以对不同价值用户使用不同的营销决策,把公司有限的资源发挥最大的效果,这就是我们常常听到的精细化运营。比如第1类是重要价值用户,这类用户最近一次消费较近,消费频率也搞,消费金额也搞,要提供vip服务。</p><p style="text-align: start;"><img src="https://pic1.zhimg.com/80/v2-1388ee45f2b119b250a63b8b90ee1d4c_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;">我们日常生活中接触到的会员服务就是这方面的经典案例。根据企鹅智库《2017中国会员经济数据报告》数据显示,用户对信用卡、酒店、航空公司的会员体系最满意。</p><p style="text-align: start;"><img src="https://pic2.zhimg.com/80/v2-cc52043b1db0fb6510643a9afc53a2cd_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>3.如何使用RFM分析方法?</strong></p><p style="text-align: start;">前面我们说RFM分析方法把用户分为8类,具体是如何做到的呢?</p><p style="text-align: start;"><strong>第1步)计算R、F、M值</strong></p><p style="text-align: start;">要得到R、F、M这3个指标,我们一般需要数据的3个字段:用户ID或者用户名称、消费时间、消费金额。从这3个字段我们可以计算出R、F、M这3个指标。</p><p style="text-align: start;"><img src="https://pic3.zhimg.com/80/v2-d59fcc5cee9672b1956f6ef12c3e6d2e_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;">以图片中的原始数据为例,现在比如是2020年1月30日,分析最近30天的用户。</p><p style="text-align: start;">小明最近一次消费是(2020.1.26)与现在时间的间隔是4天。在最近30天消费了2次,总共消费金额是5000元。</p><p style="text-align: start;">用这个方法,假如我们这个案例里计算出的是下面表格里的R、F、M值,并在表格里加了3列,用于后面对计算出的R、F、M3个值打分。</p><p style="text-align: start;"><img src="https://pic4.zhimg.com/80/v2-cb68fe4eef54361b996625c76e8c415b_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>第2步)给R、F、M按价值打分</strong></p><p style="text-align: start;">注意这里是按指标的价值打分,不是按指标数值大小打分。最近一次消费时间间隔(R),上一次消费离得越近,也就是R的值越小,用户价值越高。</p><p style="text-align: start;">将R、F、M3个指标分别按价值从小到大分为1-5分。</p><p style="text-align: start;">这个案例里,将最近消费时间间隔(R)距离越近价值越大,大于20天的打1分,10-20天的打2分,5-10天打2分,3-5天打4分,3天以内打5分。</p><p style="text-align: start;"><img src="https://pic1.zhimg.com/80/v2-e8e718025df50de093bf78ad38659d90_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;">我们把这3个指标分别是如何打分的,整理到下面这个表里。</p><p style="text-align: start;"><img src="https://pic1.zhimg.com/80/v2-49e44dbc0cf6523f646c8d2f2e53d250_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;">最近一次消费时间间隔(R),上一次消费离得越近,也就是R的值越小,用户价值越高。</p><p style="text-align: start;">消费频率(F),购买频率越高,也就是F值越大,用户价值越高。</p><p style="text-align: start;">消费金额(M),消费金额越高,也就是M值越大,用户价值越高。</p><p style="text-align: start;">具体实际业务中,如何定义打分的范围,要根据具体的业务来灵活定,没有统一的标准。</p><p style="text-align: start;">根据这个打分规则,我们可以把前面计算出的R、F、M值表格里的R值分类、F值分类、M值分类这3列填上上对应的RFM值的打分值:</p><p style="text-align: start;"><img src="https://pic3.zhimg.com/80/v2-10a6e2b28ee8601f39d5f1a933db406a_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>第3步)计算价值平均值</strong></p><p style="text-align: start;">分别计算出R值打分、F值打分、M值打分这3列的平均值</p><p style="text-align: start;"><img src="https://pic4.zhimg.com/80/v2-2ca43d50ca68c21bd881e2a1cfb8c9ef_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>第4步)用户分类</strong></p><p style="text-align: start;">在表格里增加3列,分别用于记录R、F、M3个值是高于平均值,还是低于平均值。</p><p style="text-align: start;">如果一行里的R值打分大于平均值,就在R值高低列里记录为“高”,否则记录为“低”。其他F值,M值也这样比较。最终得到了下面表格里的值</p><p style="text-align: start;"><img src="https://pic4.zhimg.com/80/v2-11740b17822be8e437308d7cf85554a3_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;">然后和用户分类表格里定义的规则进行比较,就可以得出用户属于哪种类</p><p style="text-align: start;"><img src="https://pic4.zhimg.com/80/v2-1efd09365fafaeb87c5bb34efd578437_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>我们总结下前面的内容:如何用RFM对用户分类?</strong></p><p style="text-align: start;">1)使用原始数据计算出R、F、M值</p><p style="text-align: start;">2)给R、F、M按价值打分,比如按价值从低到高分为1-5分</p><p style="text-align: start;">3)计算价值的平均值,如果某个指标的得分比价值的平均值低,标记为低。如果某个指标的得分比价值的平均值高,标记为高</p><p style="text-align: start;">4)用户分类规则表比较,得出用户分类</p><p style="text-align: start;"><img src="https://pic3.zhimg.com/80/v2-47cd755badfe74716445a095acb30b56_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;">我们再回过头看前面这个分类图,你就会恍然大悟。在坐标轴的中心,可以理解为某个指标价值的平均值。</p><p style="text-align: start;"><img src="https://pic4.zhimg.com/80/v2-8192671fc5b710dc6c4377e057f6e6b7_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>用户分类后,如何精细化运营呢?</strong></p><p style="text-align: start;">对用户分类以后要做什么呢?那就是针对每类用户如何制定运营策略,这个具体公司业务不同,方法也不一样。这里举例说明前4类用户。</p><p style="text-align: start;">1)重要价值用户,RFM三个值都很高,要提供vip服务</p><p style="text-align: start;">2)重要发展用户,消费频率低,但是其他两个值很高,就要想办法提高他的消费频率</p><p style="text-align: start;">3) 重要保持用户,最近消费距离现在时间较远,也就是F值低,但是消费频次和消费金额高。这种用户,是一段时间没来的忠实客户。应该主动和他保持联系,提高复购率</p><p style="text-align: start;">4) 重要挽留客户,最近消费时间距离现在较远、消费频率低,但消费金额高。这种用户,即将流失,要主动联系用户,调查清楚哪里出了问题,并想办法挽回。</p><p style="text-align: start;">这样通过RFM分析方法来分析用户,对用户进行精细化运营。不断将用户转化为重要价值用户。</p><p style="text-align: start;"><img src="https://pic3.zhimg.com/80/v2-f1ddf89d2ae09cdf49a982de0cd5a4e6_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>4.使用RFM分析方法需要注意什么?</strong></p><p style="text-align: start;">第1个问题:什么是? 我们学习了,RFM是3个指标的缩写,最近一次消费的时间间隔(R),消费频率(F),消费金额(M)。RFM分析方法可以把用户分为8类。</p><p style="text-align: start;">第2个问题:有什么用?我们学习了,通RFM分析方法,我们可以把用户分为8类,这样就可以对不同用户使用不同的营销策略。比如信用卡的会员服务。</p><p style="text-align: start;">第3个问题:如何用?通过一个案例学会了如何用RFM分析方法对用户分类,了解了RFM背后的原理。现在有很多工具,比如excel,sql,pytho等都可以实现RFM。工作里用到的时候,可以再用搜索引擎去搜对应的实现工具,就可以快速实现了,现在把基本原理掌握了就可以。</p><p style="text-align: start;">现在我们来看<strong>第4个问题:有哪些注意事项?</strong></p><p style="text-align: start;"><strong>(1)第1个注意事项:R、F、M指标定义,不同业务定义不同。要根据具体业务灵活应用。</strong></p><p style="text-align: start;"><img src="https://pic3.zhimg.com/80/v2-7a75f7ab10161102193b0d3598841156_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;">这里举个例子。</p><p style="text-align: start;">很多人会有这样的疑问,朋友之间不经常联系,慢慢就淡了。那么,如何管理人脉关系呢?</p><p style="text-align: start;">我们还可以用RFM分析方法来分析你的人脉,针对不同的人,制定不同的联系决策。</p><p style="text-align: start;">最近一次消费时间间隔(R)可以定义为最近一次见面距离现在的时间。</p><p style="text-align: start;">消费频率(F)可以定义为最近1年见面的频率。</p><p style="text-align: start;">消费金额(M)可以定义为最近1年见面深度,比如见面是只打个招呼,还是一起吃个饭,还是畅谈人生。</p><p style="text-align: start;">按照这个定义,我们可以重点关注前3类人脉关系。</p><p style="text-align: start;"><img src="https://pic2.zhimg.com/80/v2-def34ab2289af8e2327390e9b47cc649_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p><p style="text-align: start;">按照这个定义,我们可以重点关注前3类人脉关系</p><p style="text-align: start;">1)重要价值关系:对你的生活和工作非常有价值。他几乎是你最亲密的亲戚、朋友、客户。面对这些人,你应该经常联系,彼此帮助,时不时约出来聊聊天。</p><p style="text-align: start;">2)重要发展关系:联系比较多、一起做过点事,但是聊天是有一句没一句的,这种要重点发展关系。比如把你的困惑或者小秘密和他分享,产生情感连接。</p><p style="text-align: start;">3)重要保持的关系:所谓的熟人,也就是打起电话来记得住这个人,而且也大概了解他的背景,可能很长时间都没有见的那种“朋友”。这种要主动联系,利用节假日登门拜访、共同的朋友持续保持沟通。</p><p style="text-align: start;"><br></p><p style="text-align: start;">冯仑讲过一段话:在正常情况下,人一生交往的关系是三个数:10、30和60。这句话是什么意思呢?其实正好对应我们刚才讲的三种人脉关系。</p><p style="text-align: start;">你遇到危难的时候,能借钱的对象不超过10个人。就算是把亲戚、朋友、父母全算上,你到时候能张口借钱的对象不会超过10个人。</p><p style="text-align: start;">再一层就是属于朋友,经常打交道的、做过点事的,大概不超过30个人。这30人还包括前面说的那10个人。</p><p style="text-align: start;">最外一圈是所谓的熟人,也就是打起电话来记得住这个人,而且也大概了解他的背景,可能很长时间都没有见的那种“朋友”,最多也就是60个。这60个人还包括了前面说的30人。</p><p style="text-align: start;">所以,人这一生,其实不需要太多的关系就能应付得了。需要花精力去了解的人,其实很少,不会很多,不会超过60个。只要把这60个人的名单每天都盘好,能够用一生了。</p><p style="text-align: start;">我有个朋友是这方面高手,他把经常要联系的人记下来,每个月翻出来看看,“这个朋友有3个月没联系了,要约出来聊聊天”。</p><p style="text-align: start;">你看,在关系中,如果两个都被动,那只能慢慢断了联系。所以,保持关系的秘密就是需要其中的一方主动。</p><p style="text-align: start;">人脉比你想象的重要,为了保持有效关系,你必须把自己变成一个在这方面主动的人。</p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>(2)第2个注意事项:R、F、M按价值如何确定打分的规则?</strong></p><p style="text-align: start;">一般分为1-5分,也可以根据具体业务灵活来调整。</p><p style="text-align: start;">每个分数的范围是多少?这要根据具体业务来定范围的阈值,这就好比你在开车,车速控制在哪个范围内,可以根据路况灵活把握。</p><p style="text-align: start;">同样的,FRM打分的规则可以与业务部门沟通,进行头脑风暴。或者使用聚类的方法对R、F、M的值进行分类,然后给每个类别打分。</p><p style="text-align: start;"><br></p><p style="text-align: start;"><strong>5.总结</strong></p><p style="text-align: start;">我把前面的知识点总结到下面这张图里</p><p style="text-align: start;"><img src="https://pic2.zhimg.com/80/v2-995cac1ee4b4ff5d3a5c932d6cde2f89_720w.webp" alt="" data-href="" style="width: 690px;height: auto;"></p>'
|
|
|
);
|
|
|
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元以上",
|
|
|
},
|
|
|
]);
|
|
|
const step4Data = ref([
|
|
|
{
|
|
|
data1: "1",
|
|
|
data2: "小明",
|
|
|
data3: "4",
|
|
|
data4: "2",
|
|
|
data5: "5000",
|
|
|
},
|
|
|
{
|
|
|
data1: "2",
|
|
|
data2: "小红",
|
|
|
data3: "2",
|
|
|
data4: "3",
|
|
|
data5: "1000",
|
|
|
},
|
|
|
{
|
|
|
data1: "3",
|
|
|
data2: "小李",
|
|
|
data3: "1",
|
|
|
data4: "1",
|
|
|
data5: "500",
|
|
|
},
|
|
|
]);
|
|
|
const step5Data = ref([
|
|
|
{
|
|
|
title: "平均值",
|
|
|
},
|
|
|
]);
|
|
|
const step6Data = ref([
|
|
|
{
|
|
|
data1: "1",
|
|
|
data2: "小明",
|
|
|
data3: "4",
|
|
|
data4: "2",
|
|
|
data5: "4",
|
|
|
},
|
|
|
{
|
|
|
data1: "2",
|
|
|
data2: "小红",
|
|
|
data3: "5",
|
|
|
data4: "2",
|
|
|
data5: "2",
|
|
|
},
|
|
|
{
|
|
|
data1: "3",
|
|
|
data2: "小李",
|
|
|
data3: "5",
|
|
|
data4: "1",
|
|
|
data5: "1",
|
|
|
},
|
|
|
{
|
|
|
data1: "平均值",
|
|
|
data2: "",
|
|
|
data3: "5",
|
|
|
data4: "1",
|
|
|
data5: "1",
|
|
|
},
|
|
|
]);
|
|
|
const step7Data = ref([
|
|
|
{
|
|
|
data1: "1",
|
|
|
data2: "小明",
|
|
|
data3: "",
|
|
|
data4: "",
|
|
|
data5: "",
|
|
|
},
|
|
|
{
|
|
|
data1: "2",
|
|
|
data2: "小红",
|
|
|
data3: "",
|
|
|
data4: "",
|
|
|
data5: "",
|
|
|
},
|
|
|
{
|
|
|
data1: "3",
|
|
|
data2: "小李",
|
|
|
data3: "",
|
|
|
data4: "",
|
|
|
data5: "",
|
|
|
},
|
|
|
]);
|
|
|
const rulesTable = ref([
|
|
|
{
|
|
|
data1: "1.重要价值用户",
|
|
|
data2: "高",
|
|
|
data3: "高",
|
|
|
data4: "高",
|
|
|
},
|
|
|
{
|
|
|
data1: "2.重要发展用户",
|
|
|
data2: "高",
|
|
|
data3: "低",
|
|
|
data4: "高",
|
|
|
},
|
|
|
{
|
|
|
data1: "3.重要保持用户",
|
|
|
data2: "低",
|
|
|
data3: "高",
|
|
|
data4: "高",
|
|
|
},
|
|
|
{
|
|
|
data1: "4.重要挽留用户",
|
|
|
data2: "低",
|
|
|
data3: "低",
|
|
|
data4: "高",
|
|
|
},
|
|
|
{
|
|
|
data1: "5.一般价值用户",
|
|
|
data2: "高",
|
|
|
data3: "高",
|
|
|
data4: "低",
|
|
|
},
|
|
|
{
|
|
|
data1: "6.一般发展用户",
|
|
|
data2: "高",
|
|
|
data3: "低",
|
|
|
data4: "低",
|
|
|
},
|
|
|
{
|
|
|
data1: "7.一般保持用户",
|
|
|
data2: "低",
|
|
|
data3: "高",
|
|
|
data4: "低",
|
|
|
},
|
|
|
{
|
|
|
data1: "6.一般挽留用户",
|
|
|
data2: "低",
|
|
|
data3: "低",
|
|
|
data4: "低",
|
|
|
},
|
|
|
]);
|
|
|
const classifyList = ref([
|
|
|
{
|
|
|
value: "重要价值用户",
|
|
|
label: "1.重要价值用户",
|
|
|
},
|
|
|
{
|
|
|
value: "重要发展用户",
|
|
|
label: "2.重要发展用户",
|
|
|
},
|
|
|
{
|
|
|
value: "重要保持用户",
|
|
|
label: "3.重要保持用户",
|
|
|
},
|
|
|
{
|
|
|
value: "重要挽留用户",
|
|
|
label: "4.重要挽留用户",
|
|
|
},
|
|
|
{
|
|
|
value: "一般价值用户",
|
|
|
label: "5.一般价值用户",
|
|
|
},
|
|
|
{
|
|
|
value: "一般发展用户",
|
|
|
label: "6.一般发展用户",
|
|
|
},
|
|
|
{
|
|
|
value: "一般保持用户",
|
|
|
label: "7.一般保持用户",
|
|
|
},
|
|
|
{
|
|
|
value: "一般挽留用户",
|
|
|
label: "8.一般挽留用户",
|
|
|
},
|
|
|
]);
|
|
|
onBeforeUnmount(() => {
|
|
|
saveData();
|
|
|
});
|
|
|
onMounted(() => {
|
|
|
getData();
|
|
|
});
|
|
|
const downloadData = () => {
|
|
|
// portraitModel
|
|
|
// .downloadDataByRFM({})
|
|
|
// .then((res) => {
|
|
|
// // console.log(res,'--');
|
|
|
// const blob = new Blob([res], {
|
|
|
// type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
|
// });
|
|
|
// downBlobFile(`案例数据-RFM分析`, blob);
|
|
|
// })
|
|
|
// .catch((error) => {});
|
|
|
window.open(baseUrl + "/api/downDataByUserPortrait/analysisByRfmDown");
|
|
|
};
|
|
|
const step1Submit = () => {
|
|
|
// errorNum.value = 0;
|
|
|
stepError1.value = 0;
|
|
|
for (let i in fileTable1.value) {
|
|
|
// console.log(fileTable1.value[i]);
|
|
|
if (!fileTable1.value[i].params) {
|
|
|
proxy.$modal.msgError("请先完成所有填空");
|
|
|
return;
|
|
|
}
|
|
|
if (i == 0) {
|
|
|
if (fileTable1.value[0].params && fileTable1.value[0].params == "纳入") {
|
|
|
stepError1.value++;
|
|
|
}
|
|
|
// console.log(fileTable1.value[0].params);
|
|
|
} else {
|
|
|
if (fileTable1.value[i].params && fileTable1.value[i].params == "剔除") {
|
|
|
stepError1.value++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
console.log(stepError1.value, "错误次数");
|
|
|
step1AnswerFlag.value = true;
|
|
|
};
|
|
|
const step2Submit = () => {
|
|
|
stepError2.value = 0;
|
|
|
for (let i in step2Data.value) {
|
|
|
// console.log(fileTable1.value[i]);
|
|
|
if (!step2Data.value[i].params1) {
|
|
|
proxy.$modal.msgError("请先完成所有填空");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
// let stepError2 = 0;
|
|
|
console.log(555);
|
|
|
if (step2Data.value[0].params1 && step2Data.value[0].params1 !== "4") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
if (step2Data.value[0].params2 && step2Data.value[0].params2 !== "2") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
if (step2Data.value[0].params3 && step2Data.value[0].params3 !== "5000") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
if (step2Data.value[1].params1 && step2Data.value[1].params1 !== "2") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
if (step2Data.value[1].params2 && step2Data.value[1].params2 !== "3") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
if (step2Data.value[1].params3 && step2Data.value[1].params3 !== "1000") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
if (step2Data.value[2].params1 && step2Data.value[2].params1 !== "1") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
if (step2Data.value[2].params2 && step2Data.value[2].params2 !== "1") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
if (step2Data.value[2].params3 && step2Data.value[2].params3 !== "500") {
|
|
|
stepError2.value++;
|
|
|
}
|
|
|
console.log(stepError2.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step2AnswerFlag.value = true;
|
|
|
//将所填值同步到第四步表格
|
|
|
step4Data.value[0].data3 = step2Data.value[0].params1;
|
|
|
step4Data.value[0].data4 = step2Data.value[0].params2;
|
|
|
step4Data.value[0].data5 = step2Data.value[0].params3;
|
|
|
step4Data.value[1].data3 = step2Data.value[1].params1;
|
|
|
step4Data.value[1].data4 = step2Data.value[1].params2;
|
|
|
step4Data.value[1].data5 = step2Data.value[1].params3;
|
|
|
step4Data.value[2].data3 = step2Data.value[2].params1;
|
|
|
step4Data.value[2].data4 = step2Data.value[2].params2;
|
|
|
step4Data.value[2].data5 = step2Data.value[2].params3;
|
|
|
};
|
|
|
const step4Submit = () => {
|
|
|
// console.log(6454546);
|
|
|
step4Error.value = 0;
|
|
|
for (let i in step4Data.value) {
|
|
|
if (!step4Data.value[i].params1) {
|
|
|
proxy.$modal.msgError("请先完成所有填空");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
// let step4Error = 0;
|
|
|
if (step4Data.value[0].params1 && step4Data.value[0].params1 !== "4") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
if (step4Data.value[0].params2 && step4Data.value[0].params2 !== "2") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
if (step4Data.value[0].params3 && step4Data.value[0].params3 !== "4") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
if (step4Data.value[1].params1 && step4Data.value[1].params1 !== "5") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
if (step4Data.value[1].params2 && step4Data.value[1].params2 !== "2") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
if (step4Data.value[1].params3 && step4Data.value[1].params3 !== "2") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
if (step4Data.value[2].params1 && step4Data.value[2].params1 !== "5") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
if (step4Data.value[2].params2 && step4Data.value[2].params2 !== "1") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
if (step4Data.value[2].params3 && step4Data.value[2].params3 !== "1") {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
console.log(step4Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step4AnswerFlag.value = true;
|
|
|
//将所填值同步到第六步表格
|
|
|
step6Data.value[0].data3 = step4Data.value[0].params1;
|
|
|
step6Data.value[0].data4 = step4Data.value[0].params2;
|
|
|
step6Data.value[0].data5 = step4Data.value[0].params3;
|
|
|
step6Data.value[1].data3 = step4Data.value[1].params1;
|
|
|
step6Data.value[1].data4 = step4Data.value[1].params2;
|
|
|
step6Data.value[1].data5 = step4Data.value[1].params3;
|
|
|
step6Data.value[2].data3 = step4Data.value[2].params1;
|
|
|
step6Data.value[2].data4 = step4Data.value[2].params2;
|
|
|
step6Data.value[2].data5 = step4Data.value[2].params3;
|
|
|
};
|
|
|
const step5Submit = () => {
|
|
|
// console.log(6333);
|
|
|
step5Error.value = 0;
|
|
|
for (let i in step5Data.value) {
|
|
|
if (!step5Data.value[i].params1) {
|
|
|
proxy.$modal.msgError("请先完成所有填空");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
// let step5Error = 0;
|
|
|
if (step5Data.value[0].params1 && step5Data.value[0].params1 !== "4.67") {
|
|
|
step5Error.value++;
|
|
|
}
|
|
|
if (step5Data.value[0].params2 && step5Data.value[0].params2 !== "1.67") {
|
|
|
step5Error.value++;
|
|
|
}
|
|
|
if (step5Data.value[0].params3 && step5Data.value[0].params3 !== "2.33") {
|
|
|
step5Error.value++;
|
|
|
}
|
|
|
console.log(step5Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step5AnswerFlag.value = true;
|
|
|
//将所填值同步到第六步表格
|
|
|
step6Data.value[3].data3 = step5Data.value[0].params1;
|
|
|
step6Data.value[3].data4 = step5Data.value[0].params2;
|
|
|
step6Data.value[3].data5 = step5Data.value[0].params3;
|
|
|
};
|
|
|
const step6Submit = () => {
|
|
|
// console.log(555);
|
|
|
step6Error.value = 0;
|
|
|
for (let i in step6Data.value.slice(0, step6Data.value.length - 1)) {
|
|
|
if (
|
|
|
!step6Data.value[i].params1 ||
|
|
|
!step6Data.value[i].params2 ||
|
|
|
!step6Data.value[i].params3
|
|
|
) {
|
|
|
proxy.$modal.msgError("请先完成所有填空");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
// let step6Error = 0;
|
|
|
if (step6Data.value[0].params1 && step6Data.value[0].params1 !== "低") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
if (step6Data.value[0].params2 && step6Data.value[0].params2 !== "高") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
if (step6Data.value[0].params3 && step6Data.value[0].params3 !== "高") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
if (step6Data.value[1].params1 && step6Data.value[1].params1 !== "高") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
if (step6Data.value[1].params2 && step6Data.value[1].params2 !== "高") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
if (step6Data.value[1].params3 && step6Data.value[1].params3 !== "高") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
if (step6Data.value[2].params1 && step6Data.value[2].params1 !== "高") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
if (step6Data.value[2].params2 && step6Data.value[2].params2 !== "低") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
if (step6Data.value[2].params3 && step6Data.value[2].params3 !== "低") {
|
|
|
step6Error.value++;
|
|
|
}
|
|
|
console.log(step6Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step6AnswerFlag.value = true;
|
|
|
//将所填值同步到第六步表格
|
|
|
step7Data.value[0].data3 = step6Data.value[0].params1;
|
|
|
step7Data.value[0].data4 = step6Data.value[0].params2;
|
|
|
step7Data.value[0].data5 = step6Data.value[0].params3;
|
|
|
step7Data.value[1].data3 = step6Data.value[1].params1;
|
|
|
step7Data.value[1].data4 = step6Data.value[1].params2;
|
|
|
step7Data.value[1].data5 = step6Data.value[1].params3;
|
|
|
step7Data.value[2].data3 = step6Data.value[2].params1;
|
|
|
step7Data.value[2].data4 = step6Data.value[2].params2;
|
|
|
step7Data.value[2].data5 = step6Data.value[2].params3;
|
|
|
};
|
|
|
const step7Submit = () => {
|
|
|
// console.log(111);
|
|
|
step7Error.value = 0;
|
|
|
for (let i in step7Data.value) {
|
|
|
if (!step7Data.value[i].params) {
|
|
|
proxy.$modal.msgError("请先完成所有填空");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
// let step7Error = 0;
|
|
|
if (
|
|
|
step7Data.value[0].params &&
|
|
|
step7Data.value[0].params !== "重要保持用户"
|
|
|
) {
|
|
|
step7Error.value++;
|
|
|
}
|
|
|
if (
|
|
|
step7Data.value[1].params &&
|
|
|
step7Data.value[1].params !== "重要价值用户"
|
|
|
) {
|
|
|
step7Error.value++;
|
|
|
}
|
|
|
if (
|
|
|
step7Data.value[2].params &&
|
|
|
step7Data.value[2].params !== "一般发展用户"
|
|
|
) {
|
|
|
step7Error.value++;
|
|
|
}
|
|
|
console.log(step7Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step7AnswerFlag.value = true;
|
|
|
};
|
|
|
const submitData = () => {
|
|
|
if (
|
|
|
!step1AnswerFlag.value ||
|
|
|
!step2AnswerFlag.value ||
|
|
|
!step4AnswerFlag.value ||
|
|
|
!step5AnswerFlag.value ||
|
|
|
!step6AnswerFlag.value ||
|
|
|
!step7AnswerFlag.value
|
|
|
) {
|
|
|
proxy.$modal.msgError("请先完成所有步骤!");
|
|
|
return;
|
|
|
}
|
|
|
errorNum.value =
|
|
|
stepError1.value +
|
|
|
stepError2.value +
|
|
|
step4Error.value +
|
|
|
step5Error.value +
|
|
|
step6Error.value +
|
|
|
step7Error.value;
|
|
|
console.log(errorNum.value, "总错误次数");
|
|
|
portraitModel
|
|
|
.submit({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
taskName: "RFM分析",
|
|
|
numberOfErrors: errorNum.value,
|
|
|
})
|
|
|
.then((res) => {
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
})
|
|
|
.catch((error) => {});
|
|
|
};
|
|
|
const saveData = () => {
|
|
|
const params = {
|
|
|
stepFiveA: fileTable1.value[0].params,
|
|
|
stepFiveB: fileTable1.value[1].params,
|
|
|
stepFiveC: fileTable1.value[2].params,
|
|
|
stepFiveD: fileTable1.value[3].params,
|
|
|
stepSixA: fileTable1.value[4].params,
|
|
|
stepSixB: fileTable1.value[5].params,
|
|
|
stepSixC: fileTable1.value[6].params,
|
|
|
stepSixD: step2Data.value[0].params1,
|
|
|
stepSevenA: step2Data.value[0].params2,
|
|
|
stepSevenB: step2Data.value[0].params3,
|
|
|
stepSevenC: step2Data.value[1].params1,
|
|
|
stepSevenD: step2Data.value[1].params2,
|
|
|
stepEightA: step2Data.value[1].params3,
|
|
|
stepEightB: step2Data.value[2].params1,
|
|
|
stepEightC: step2Data.value[2].params2,
|
|
|
stepEightD: step2Data.value[2].params3,
|
|
|
stepNineA: step4Data.value[0].params1,
|
|
|
stepNineB: step4Data.value[0].params2,
|
|
|
stepNineC: step4Data.value[0].params3,
|
|
|
stepNineD: step4Data.value[1].params1,
|
|
|
stepTenA: step4Data.value[1].params2,
|
|
|
stepTenB: step4Data.value[1].params3,
|
|
|
stepTenC: step4Data.value[2].params1,
|
|
|
stepTenD: step4Data.value[2].params2,
|
|
|
stepElevenA: step4Data.value[2].params3,
|
|
|
stepOneA: step5Data.value[0].params1,
|
|
|
stepOneB: step5Data.value[0].params2,
|
|
|
stepOneC: step5Data.value[0].params3,
|
|
|
stepOneD: step6Data.value[0].params1,
|
|
|
stepTwoA: step6Data.value[0].params2,
|
|
|
stepTwoB: step6Data.value[0].params3,
|
|
|
stepTwoC: step6Data.value[1].params1,
|
|
|
stepThreeA: step6Data.value[1].params2,
|
|
|
stepThreeB: step6Data.value[1].params3,
|
|
|
stepThreeC: step6Data.value[2].params1,
|
|
|
stepThreeD: step6Data.value[2].params2,
|
|
|
stepFourA: step6Data.value[2].params3,
|
|
|
stepFourB: step7Data.value[0].params,
|
|
|
stepFourC: step7Data.value[1].params,
|
|
|
stepFourD: step7Data.value[2].params,
|
|
|
};
|
|
|
portraitModel
|
|
|
.saveData({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
module: "RFM分析",
|
|
|
...params,
|
|
|
})
|
|
|
.then((res) => {})
|
|
|
.catch((error) => {});
|
|
|
};
|
|
|
const getData = () => {
|
|
|
portraitModel
|
|
|
.getData({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
module: "RFM分析",
|
|
|
})
|
|
|
.then((res) => {
|
|
|
fileTable1.value[0].params = res.data.stepFiveA;
|
|
|
fileTable1.value[1].params = res.data.stepFiveB;
|
|
|
fileTable1.value[2].params = res.data.stepFiveC;
|
|
|
fileTable1.value[3].params = res.data.stepFiveD;
|
|
|
fileTable1.value[4].params = res.data.stepSixA;
|
|
|
fileTable1.value[5].params = res.data.stepSixB;
|
|
|
fileTable1.value[6].params = res.data.stepSixC;
|
|
|
step2Data.value[0].params1 = res.data.stepSixD;
|
|
|
step2Data.value[0].params2 = res.data.stepSevenA;
|
|
|
step2Data.value[0].params3 = res.data.stepSevenB;
|
|
|
step2Data.value[1].params1 = res.data.stepSevenC;
|
|
|
step2Data.value[1].params2 = res.data.stepSevenD;
|
|
|
step2Data.value[1].params3 = res.data.stepEightA;
|
|
|
step2Data.value[2].params1 = res.data.stepEightB;
|
|
|
step2Data.value[2].params2 = res.data.stepEightC;
|
|
|
step2Data.value[2].params3 = res.data.stepEightD;
|
|
|
step4Data.value[0].params1 = res.data.stepNineA;
|
|
|
step4Data.value[0].params2 = res.data.stepNineB;
|
|
|
step4Data.value[0].params3 = res.data.stepNineC;
|
|
|
step4Data.value[1].params1 = res.data.stepNineD;
|
|
|
step4Data.value[1].params2 = res.data.stepTenA;
|
|
|
step4Data.value[1].params3 = res.data.stepTenB;
|
|
|
step4Data.value[2].params1 = res.data.stepTenC;
|
|
|
step4Data.value[2].params2 = res.data.stepTenD;
|
|
|
step4Data.value[2].params3 = res.data.stepElevenA;
|
|
|
step5Data.value[0].params1 = res.data.stepOneA;
|
|
|
step5Data.value[0].params2 = res.data.stepOneB;
|
|
|
step5Data.value[0].params3 = res.data.stepOneC;
|
|
|
step6Data.value[0].params1 = res.data.stepOneD;
|
|
|
step6Data.value[0].params2 = res.data.stepTwoA;
|
|
|
step6Data.value[0].params3 = res.data.stepTwoB;
|
|
|
step6Data.value[1].params1 = res.data.stepTwoC;
|
|
|
step6Data.value[1].params2 = res.data.stepThreeA;
|
|
|
step6Data.value[1].params3 = res.data.stepThreeB;
|
|
|
step6Data.value[2].params1 = res.data.stepThreeC;
|
|
|
step6Data.value[2].params2 = res.data.stepThreeD;
|
|
|
step6Data.value[2].params3 = res.data.stepFourA;
|
|
|
step7Data.value[0].params = res.data.stepFourB;
|
|
|
step7Data.value[1].params = res.data.stepFourC;
|
|
|
step7Data.value[2].params = res.data.stepFourD;
|
|
|
})
|
|
|
.catch((error) => {});
|
|
|
};
|
|
|
const retrain = () => {
|
|
|
portraitModel
|
|
|
.retrain({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
module: "RFM分析",
|
|
|
})
|
|
|
.then((res) => {
|
|
|
proxy.$modal.msgSuccess("重新实训成功");
|
|
|
for (let i in fileTable1.value) {
|
|
|
fileTable1.value[i].params = "";
|
|
|
}
|
|
|
for (let i in step2Data.value) {
|
|
|
step2Data.value[i].params1 = "";
|
|
|
step2Data.value[i].params2 = "";
|
|
|
step2Data.value[i].params3 = "";
|
|
|
}
|
|
|
for (let i in step4Data.value) {
|
|
|
step4Data.value[i].params1 = "";
|
|
|
step4Data.value[i].params2 = "";
|
|
|
step4Data.value[i].params3 = "";
|
|
|
}
|
|
|
step5Data.value[0].params1 = "";
|
|
|
step5Data.value[0].params2 = "";
|
|
|
step5Data.value[0].params3 = "";
|
|
|
for (let i in step6Data.value) {
|
|
|
step6Data.value[i].params1 = "";
|
|
|
step6Data.value[i].params2 = "";
|
|
|
step6Data.value[i].params3 = "";
|
|
|
}
|
|
|
for (let i in step7Data.value) {
|
|
|
step7Data.value[i].params = "";
|
|
|
}
|
|
|
})
|
|
|
.catch((error) => {});
|
|
|
};
|
|
|
defineExpose({
|
|
|
submitData,
|
|
|
retrain,
|
|
|
// practicalTraining,
|
|
|
});
|
|
|
const tableSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
|
|
if (rowIndex === 3) {
|
|
|
if (columnIndex === 0) {
|
|
|
return [1, 2];
|
|
|
} else if (columnIndex === 1) {
|
|
|
return [0, 0];
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
</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: 150px;
|
|
|
height: 50px;
|
|
|
background-image: url("@/assets/images/taskImport.png");
|
|
|
background-size: 150px 50px;
|
|
|
text-align: center;
|
|
|
align-items: center;
|
|
|
line-height: 50px;
|
|
|
cursor: pointer;
|
|
|
img {
|
|
|
margin-left: 20px;
|
|
|
margin-right: 8px;
|
|
|
}
|
|
|
}
|
|
|
.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");
|
|
|
}
|
|
|
.customerType {
|
|
|
padding-left: 10px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
width: 945px;
|
|
|
height: 26px;
|
|
|
background: #003b75;
|
|
|
border-radius: 10px;
|
|
|
border: 1px solid #0052a3;
|
|
|
font-size: 12px;
|
|
|
margin-top: 10px;
|
|
|
img {
|
|
|
margin-right: 10px;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
.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;
|
|
|
}
|
|
|
|
|
|
::v-deep .el-dialog {
|
|
|
background: url("../../../assets/images/弹框@2x.png") !important;
|
|
|
background-size: 1108px 798px !important;
|
|
|
.el-dialog__header {
|
|
|
padding: 5px 0px;
|
|
|
margin-right: 5px !important;
|
|
|
.gbImg {
|
|
|
cursor: pointer;
|
|
|
margin-top: 3px;
|
|
|
// margin-left: -30px;
|
|
|
width: 51px;
|
|
|
height: 35px;
|
|
|
background-size: 100% 100%;
|
|
|
}
|
|
|
}
|
|
|
.xtImg {
|
|
|
margin-left: 18px;
|
|
|
width: 530px;
|
|
|
}
|
|
|
}
|
|
|
.my-header {
|
|
|
display: flex;
|
|
|
flex-direction: row;
|
|
|
justify-content: space-between;
|
|
|
gap: 16px;
|
|
|
text-align: center;
|
|
|
margin-right: 9px;
|
|
|
margin-bottom: 0;
|
|
|
span {
|
|
|
color: #ffffff;
|
|
|
padding: 38px 20px 0;
|
|
|
margin-top: 10px;
|
|
|
margin-left: 20px;
|
|
|
}
|
|
|
}
|
|
|
::v-deep .el-table td {
|
|
|
padding-top: 4px;
|
|
|
padding-bottom: 4px;
|
|
|
}
|
|
|
</style>
|