|
|
<template>
|
|
|
<div class="content">
|
|
|
<div class="import" @click="dialogVisible = true">
|
|
|
<img src="@/assets/images/导入.png" alt="" />
|
|
|
<span>任务知识导入</span>
|
|
|
</div>
|
|
|
<!-- <div v-if="knowledgeFlag">
|
|
|
<p style="line-height: 25px; font-size: 14px">
|
|
|
波士顿矩阵(BCG
|
|
|
Matrix),又称市场增长率-相对市场份额矩阵,由美国著名的管理学家、波士顿咨询公司创始人布鲁斯·亨德森于1970年首创,它是通过销售增长率(反应市场引力的指标)和市场占有率(反应企业实力的指标)来分析决定企业的产品结构。<br />
|
|
|
市场吸引力包括企业销售量增长率、目标市场容量、竞争对手强弱、利润高低等。其中最重要的是反映市场引力的综合指标——销售增长率,这是决定企业产品结构是否合理的外在因素。<br />
|
|
|
企业实力包括市场占有率、技术、设备、资金利用能力等,其中市场占有率是决定企业产品结构的内在因素,他直接显示出企业的竞争实力。
|
|
|
</p>
|
|
|
|
|
|
<img src="@/assets/images/u3678.png" alt="" /><br />
|
|
|
<span style="line-height: 25px; font-size: 14px">
|
|
|
波士顿矩阵将产品类型分为四种:<br />
|
|
|
1,明星类产品:高增长且高市占,发展前景好,竞争力强,需加大投资以支持其发展;<br />
|
|
|
2,问题类产品:高增长但低市占,发展前景好但市场开拓不足,需谨慎投资;<br />
|
|
|
3,现金牛产品:低增长但高市占,成熟市场的领导者,应降低投资,维持市占并延缓衰退;<br />
|
|
|
4,瘦狗类产品:低增长且低市占,理论率低甚至亏损,应采取撤退战略。 </span
|
|
|
><br />
|
|
|
<img src="@/assets/images/u3682.png" alt="" />
|
|
|
</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">现有以下某商店的客户消费原始数据,需要采用波士顿矩阵分析方法,对客户进行分类:</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="id"></el-table-column>
|
|
|
<el-table-column label="消费金额" align="center" prop="amount"></el-table-column>
|
|
|
<el-table-column label="消费时间" align="center" prop="time"></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">以客户ID为统计单元,分别计算各个客户累计的消费次数、消费金额。</span>
|
|
|
<div style="margin-top: 10px; display: flex">
|
|
|
<el-table
|
|
|
:data="step1Data"
|
|
|
style="width: 550px"
|
|
|
border
|
|
|
:header-cell-style="{
|
|
|
color: '#fff',
|
|
|
fontSize: '14px',
|
|
|
backgroundColor: '#6A7DE9!important',
|
|
|
}"
|
|
|
>
|
|
|
<el-table-column label="客户ID" align="center" prop="name"></el-table-column>
|
|
|
<el-table-column label="消费次数" align="center" prop="amount">
|
|
|
<template #default="scope">
|
|
|
<el-input v-model="scope.row.params1" placeholder="请输入" style="width: 130px"></el-input>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="消费金额" align="center" prop="amount">
|
|
|
<template #default="scope">
|
|
|
<el-input v-model="scope.row.params2" placeholder="请输入" style="width: 130px"></el-input>
|
|
|
</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>第二步,确定象限测度划分标准</span>
|
|
|
</div>
|
|
|
<span style="line-height: 25px; font-size: 14px">以客户ID为统计单元,分别计算各个客户的平均消费次数、平均消费金额。</span>
|
|
|
<div style="margin-top: 10px; display: flex" v-if="step1AnswerFlag">
|
|
|
<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="name"></el-table-column>
|
|
|
<el-table-column label="消费次数" align="center" prop="amount">
|
|
|
<template #default="scope">
|
|
|
<el-input v-model="scope.row.params1" placeholder="请输入" style="width: 130px" v-if="scope.$index == 4"></el-input>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="消费金额" align="center" prop="account">
|
|
|
<template #default="scope">
|
|
|
<el-input v-model="scope.row.params2" placeholder="请输入" style="width: 130px" v-if="scope.$index == 4"></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>第三步,绘制散点图</span>
|
|
|
</div>
|
|
|
<span style="line-height: 25px; font-size: 14px">以消费金额为纵轴,消费次数为横轴,将第一步的客户数据绘制于坐标轴中</span>
|
|
|
<div style="margin-top: 10px; display: flex">
|
|
|
<div id="charts1" style="width: 500px; height: 400px"></div>
|
|
|
<div>
|
|
|
<div class="submit" @click="step3Submit">提交</div>
|
|
|
<div class="drawPoint">
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawPoint('A', '#009FF1')">绘制A</div>
|
|
|
<span>(3,800)</span>
|
|
|
</div>
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawPoint('B', '#FB54A1')">绘制B</div>
|
|
|
<span>(4,1200)</span>
|
|
|
</div>
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawPoint('C', '#FE8D2A')">绘制C</div>
|
|
|
<span>(6,600)</span>
|
|
|
</div>
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawPoint('D', '#6E70F0')">绘制D</div>
|
|
|
<span>(7,1400)</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</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="margin-top: 10px; display: flex">
|
|
|
<div id="charts2" style="width: 500px; height: 400px"></div>
|
|
|
<div>
|
|
|
<div class="submit" @click="step4Submit">提交</div>
|
|
|
<div class="drawPoint">
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawPointStep4('A', '#009FF1')">绘制平均消费次数X,平均消费金额Y</div>
|
|
|
<span>(5,1000)</span>
|
|
|
</div>
|
|
|
<!-- <div class="point">
|
|
|
<div class="pointItem" @click="drawPointStep4('Y', '#FB54A1')">
|
|
|
绘制平均消费金额Y
|
|
|
</div>
|
|
|
<span>1000</span>
|
|
|
</div> -->
|
|
|
</div>
|
|
|
</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">
|
|
|
按照客户标准,划分A、B、C、D各属于哪类客户。
|
|
|
<br />
|
|
|
1、消费次数超过平均值,每次消费力度也超过平均水平的客户:判定为明星客户
|
|
|
<br />
|
|
|
2、消费次数超过平均值,但每次消费力度未达到平均水平的客户:被判定为现金流客户
|
|
|
<br />
|
|
|
3、消费未达到平均值,但每次消费力度超过平均水平的客户:是问题客户
|
|
|
<br />
|
|
|
4、消费未达到平均值,消费力度也未达到平均水平的客户:属于瘦狗客户
|
|
|
</span>
|
|
|
<div style="margin-top: 10px; display: flex">
|
|
|
<div id="charts3" style="width: 500px; height: 400px"></div>
|
|
|
<div>
|
|
|
<div class="submit" @click="step5Submit">提交</div>
|
|
|
<div class="drawPoint">
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawQuadrant('明星客户', 'rgba(52, 134, 207, 0.8)')">明星客户</div>
|
|
|
</div>
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawQuadrant('现金流客户', 'rgba(0, 184, 105, 0.8)')">现金流客户</div>
|
|
|
</div>
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawQuadrant('问题客户', 'rgba(177, 130, 192, 0.8)')">问题客户</div>
|
|
|
</div>
|
|
|
<div class="point">
|
|
|
<div class="pointItem" @click="drawQuadrant('瘦狗客户', 'rgba(254, 141, 42, 0.8)')">瘦狗客户</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</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 class="customerType" style="width: 887px">
|
|
|
<img src="@/assets/images/客户1.png" alt="" />
|
|
|
<span>明星客户,这类客户需要重点关注,并给予最高的礼遇;</span>
|
|
|
</div>
|
|
|
<div class="customerType" style="width: 887px">
|
|
|
<img src="@/assets/images/客户2.png" alt="" />
|
|
|
<span>现金流客户,这类客户通常消费频次比较频繁,能给企业带来较为稳定的现金流,这类客户是企业利润基石;</span>
|
|
|
</div>
|
|
|
<div class="customerType" style="width: 887px">
|
|
|
<img src="@/assets/images/客户3.png" alt="" />
|
|
|
<span>问题客户,这类客户最有希望转化为明星客户,但是因为客户存在一定的潜在问题,导致消费频次不高,这类客户需要利用客服进行重点跟进和长期跟踪;</span>
|
|
|
</div>
|
|
|
<div class="customerType" style="width: 887px">
|
|
|
<img src="@/assets/images/客户1.png" alt="" />
|
|
|
<span>瘦狗客户,这类客户通常占企业客户的大多数,只需要一般性维护,不需要投入重点维系。</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<pop-modal :showModel="dialogVisible" @closePop="dialogVisible = false">
|
|
|
<template v-slot:content>
|
|
|
<p style="line-height: 25px; font-size: 14px">
|
|
|
波士顿矩阵(BCG Matrix),又称市场增长率-相对市场份额矩阵,由美国著名的管理学家、波士顿咨询公司创始人布鲁斯·亨德森于1970年首创,它是通过销售增长率(反应市场引力的指标)和市场占有率(反应企业实力的指标)来分析决定企业的产品结构。
|
|
|
<br />
|
|
|
市场吸引力包括企业销售量增长率、目标市场容量、竞争对手强弱、利润高低等。其中最重要的是反映市场引力的综合指标——销售增长率,这是决定企业产品结构是否合理的外在因素。
|
|
|
<br />
|
|
|
企业实力包括市场占有率、技术、设备、资金利用能力等,其中市场占有率是决定企业产品结构的内在因素,他直接显示出企业的竞争实力。
|
|
|
</p>
|
|
|
|
|
|
<img src="@/assets/images/u3678.png" alt="" />
|
|
|
<br />
|
|
|
<span style="line-height: 25px; font-size: 14px">
|
|
|
波士顿矩阵将产品类型分为四种:
|
|
|
<br />
|
|
|
1,明星类产品:高增长且高市占,发展前景好,竞争力强,需加大投资以支持其发展;
|
|
|
<br />
|
|
|
2,问题类产品:高增长但低市占,发展前景好但市场开拓不足,需谨慎投资;
|
|
|
<br />
|
|
|
3,现金牛产品:低增长但高市占,成熟市场的领导者,应降低投资,维持市占并延缓衰退;
|
|
|
<br />
|
|
|
4,瘦狗类产品:低增长且低市占,理论率低甚至亏损,应采取撤退战略。
|
|
|
</span>
|
|
|
<br />
|
|
|
<br />
|
|
|
<span style="line-height: 25px; font-size: 14px">
|
|
|
当波士顿矩阵应用于客户画像时候,可以大致分析出不同用户的客户画像:
|
|
|
<br />
|
|
|
1、消费次数超过平均值,每次消费力度也超过平均水平的客户:判定为明星客户,这类客户需要重点关注,并给予最高的礼遇;
|
|
|
<br />
|
|
|
2、消费次数超过平均值,但每次消费力度未达到平均水平的客户:被判定为现金流客户,这类客户通常消费频次比较频繁,能给企业带来较为稳定的现金流,这类客户是企业利润基石;
|
|
|
<br />
|
|
|
3、消费未达到平均值,但每次消费力度超过平均水平的客户:是问题客户,这类客户最有希望转化为明星客户,但是因为客户存在一定的潜在问题,导致消费频次不高,这类客户需要利用客服进行重点跟进和长期跟踪;
|
|
|
<br />
|
|
|
4、消费未达到平均值,消费力度也未达到平均水平的客户:属于瘦狗客户,这类客户通常占企业客户的大多数,只需要一般性维护,不需要投入重点维系。
|
|
|
<br />
|
|
|
</span>
|
|
|
<br />
|
|
|
<img src="@/assets/images/u3682.png" alt="" />
|
|
|
</template>
|
|
|
</pop-modal>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import popModal from "@/views/components/popModal.vue";
|
|
|
import { getUserInfo } from "@/utils/auth";
|
|
|
import * as echarts from "echarts";
|
|
|
import { Chart } from "@antv/g2";
|
|
|
import * as portraitModel from "@/api/portraitModel";
|
|
|
import { downBlobFile } from "@/utils/index.js";
|
|
|
import { onMounted } from "vue";
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
|
|
const dialogVisible = ref(false);
|
|
|
const knowledgeFlag = ref(false);
|
|
|
const step1Data = ref([
|
|
|
{
|
|
|
name: "A",
|
|
|
amount: "2300",
|
|
|
},
|
|
|
{
|
|
|
name: "B",
|
|
|
amount: "2300",
|
|
|
},
|
|
|
{
|
|
|
name: "C",
|
|
|
amount: "2300",
|
|
|
},
|
|
|
{
|
|
|
name: "D",
|
|
|
amount: "2300",
|
|
|
},
|
|
|
]);
|
|
|
const fileTable1 = ref([
|
|
|
{
|
|
|
id: "A",
|
|
|
amount: "200",
|
|
|
time: "2023.02.01",
|
|
|
},
|
|
|
{
|
|
|
id: "B",
|
|
|
amount: "300",
|
|
|
time: "2023.02.02",
|
|
|
},
|
|
|
{
|
|
|
id: "A",
|
|
|
time: "2023.02.03",
|
|
|
amount: "200",
|
|
|
},
|
|
|
{
|
|
|
id: "D",
|
|
|
time: "2023.02.04",
|
|
|
amount: "150",
|
|
|
},
|
|
|
{
|
|
|
id: "C",
|
|
|
time: "2023.02.05",
|
|
|
amount: "100",
|
|
|
},
|
|
|
{
|
|
|
id: "B",
|
|
|
time: "2023.02.06",
|
|
|
amount: "400",
|
|
|
},
|
|
|
{
|
|
|
id: "C",
|
|
|
time: "2023.02.07",
|
|
|
amount: "50",
|
|
|
},
|
|
|
{
|
|
|
id: "D",
|
|
|
time: "2023.02.08",
|
|
|
amount: "250",
|
|
|
},
|
|
|
{
|
|
|
id: "D",
|
|
|
time: "2023.02.09",
|
|
|
amount: "200",
|
|
|
},
|
|
|
{
|
|
|
id: "B",
|
|
|
time: "2023.02.10",
|
|
|
amount: "300",
|
|
|
},
|
|
|
{
|
|
|
id: "D",
|
|
|
time: "2023.02.11",
|
|
|
amount: "200",
|
|
|
},
|
|
|
{
|
|
|
id: "C",
|
|
|
time: "2023.02.12",
|
|
|
amount: "50",
|
|
|
},
|
|
|
{
|
|
|
id: "D",
|
|
|
time: "2023.02.13",
|
|
|
amount: "100",
|
|
|
},
|
|
|
{
|
|
|
id: "A",
|
|
|
time: "2023.02.14",
|
|
|
amount: "400",
|
|
|
},
|
|
|
{
|
|
|
id: "C",
|
|
|
time: "2023.02.15",
|
|
|
amount: "200",
|
|
|
},
|
|
|
{
|
|
|
id: "B",
|
|
|
time: "2023.02.16",
|
|
|
amount: "200",
|
|
|
},
|
|
|
{
|
|
|
id: "C",
|
|
|
time: "2023.02.17",
|
|
|
amount: "150",
|
|
|
},
|
|
|
{
|
|
|
id: "D",
|
|
|
time: "2023.02.18",
|
|
|
amount: "300",
|
|
|
},
|
|
|
{
|
|
|
id: "C",
|
|
|
time: "2023.02.19",
|
|
|
amount: "50",
|
|
|
},
|
|
|
{
|
|
|
id: "D",
|
|
|
time: "2023.02.20",
|
|
|
amount: "200",
|
|
|
},
|
|
|
]);
|
|
|
const step2Data = ref([
|
|
|
{
|
|
|
name: "A",
|
|
|
amount: "3",
|
|
|
account: "800",
|
|
|
},
|
|
|
{ name: "B", amount: "4", account: "1200" },
|
|
|
{ name: "C", amount: "6", account: "600" },
|
|
|
{ name: "D", amount: "7", account: "1400" },
|
|
|
{ name: "平均值", amount: "7", account: "1400" },
|
|
|
]);
|
|
|
const step3Data = ref([
|
|
|
{
|
|
|
data1: "男士配饰",
|
|
|
data2: "5900",
|
|
|
},
|
|
|
{
|
|
|
data1: "床上用品",
|
|
|
data2: "2400",
|
|
|
},
|
|
|
{
|
|
|
data1: "婴儿用品",
|
|
|
data2: "1100",
|
|
|
},
|
|
|
|
|
|
{
|
|
|
data1: "儿童服装",
|
|
|
data2: "600",
|
|
|
},
|
|
|
]);
|
|
|
const step4Data = ref([
|
|
|
{
|
|
|
data1: "男士配饰",
|
|
|
data2: "5900",
|
|
|
data3: "59%",
|
|
|
data4: "2",
|
|
|
},
|
|
|
{
|
|
|
data1: "床上用品",
|
|
|
data2: "2400",
|
|
|
data3: "83%",
|
|
|
data4: "3",
|
|
|
},
|
|
|
{
|
|
|
data1: "婴儿用品",
|
|
|
data2: "1100",
|
|
|
data3: "94%",
|
|
|
data4: "1",
|
|
|
},
|
|
|
{
|
|
|
data1: "儿童服装",
|
|
|
data2: "600",
|
|
|
data3: "100%",
|
|
|
data4: "1",
|
|
|
},
|
|
|
]);
|
|
|
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",
|
|
|
},
|
|
|
]);
|
|
|
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 typeData = ref([
|
|
|
{
|
|
|
data1: "A类商品",
|
|
|
data2: "占总销售额的80%,需要重点关注",
|
|
|
},
|
|
|
{
|
|
|
data1: "B类商品",
|
|
|
data2: "占总销售额的10%,给予次要关注",
|
|
|
},
|
|
|
{
|
|
|
data1: "C类商品",
|
|
|
data2: "占总销售额的10%,给予一般关注",
|
|
|
},
|
|
|
]);
|
|
|
//第三步定义数据
|
|
|
const option = ref({});
|
|
|
const drawPointName = ref("");
|
|
|
const drawPointColor = ref("");
|
|
|
const pointInGrid = ref([]);
|
|
|
//第四步定义数据
|
|
|
const option2 = ref({});
|
|
|
const drawPointNameStep4 = ref("");
|
|
|
const drawPointColorStep4 = ref("");
|
|
|
const pointInGridStep4 = ref([]);
|
|
|
//第五步定义数据
|
|
|
const optionStep5 = ref({});
|
|
|
const drawPointNameStep5 = ref("");
|
|
|
const drawPointColorStep5 = ref("");
|
|
|
const pointInGridStep5 = ref([]);
|
|
|
const errorNum = ref(0);
|
|
|
const step1Error = ref(0);
|
|
|
const step2Error = ref(0);
|
|
|
const step3Error = ref(0);
|
|
|
const step4Error = ref(0);
|
|
|
const step5Error = ref(0);
|
|
|
const step1AnswerFlag = ref(false);
|
|
|
const step2AnswerFlag = ref(false);
|
|
|
const step3AnswerFlag = ref(false);
|
|
|
const step4AnswerFlag = ref(false);
|
|
|
const step5AnswerFlag = ref(false);
|
|
|
onMounted(() => {
|
|
|
getData();
|
|
|
step3EchartInit();
|
|
|
step4EchartInit();
|
|
|
step5EchartInit();
|
|
|
});
|
|
|
onBeforeUnmount(() => {
|
|
|
saveData();
|
|
|
});
|
|
|
const drawPoint = (point, color) => {
|
|
|
// console.log(point);
|
|
|
// let Apoint = point
|
|
|
// if(Apoint == drawPointName.value){
|
|
|
// proxy.$modal.msgError("请勿绘制重复的点");
|
|
|
// return;
|
|
|
// }
|
|
|
drawPointName.value = point;
|
|
|
drawPointColor.value = color;
|
|
|
// option.value.series[0].data.push(pointInGrid);
|
|
|
// option.value && myChart.setOption(option.value);
|
|
|
};
|
|
|
const drawPointStep4 = (point, color) => {
|
|
|
drawPointNameStep4.value = point;
|
|
|
drawPointColorStep4.value = color;
|
|
|
};
|
|
|
const step3EchartInit = () => {
|
|
|
var chartDom = document.getElementById("charts1");
|
|
|
var myChart = echarts.init(chartDom, "dark");
|
|
|
// var option;
|
|
|
|
|
|
option.value = {
|
|
|
xAxis: {
|
|
|
name: "X",
|
|
|
show: true,
|
|
|
max: 10,
|
|
|
min: 0,
|
|
|
interval: 1,
|
|
|
axisPointer: {
|
|
|
show: true,
|
|
|
label: {
|
|
|
precision: 0,
|
|
|
},
|
|
|
// snap: true,
|
|
|
},
|
|
|
},
|
|
|
yAxis: {
|
|
|
name: "Y",
|
|
|
show: true,
|
|
|
interval: 200,
|
|
|
max: 2000,
|
|
|
min: 0,
|
|
|
axisPointer: {
|
|
|
show: true,
|
|
|
// snap: true,
|
|
|
label: {
|
|
|
precision: 0,
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
series: [
|
|
|
{
|
|
|
symbolSize: 20,
|
|
|
label: {
|
|
|
show: true, // 显示标签
|
|
|
formatter: function (params) {
|
|
|
// 自定义显示的文本内容,params是包含数据信息的对象
|
|
|
return params.data.name;
|
|
|
},
|
|
|
position: "top", // 文本位置,可以是 'top', 'left', 'right', 'bottom', 'inside', 或者是 {top, left} 形式的具体位置
|
|
|
},
|
|
|
itemStyle: {
|
|
|
color: function (params) {
|
|
|
// 自定义显示的文本内容,params是包含数据信息的对象
|
|
|
return params.data.color;
|
|
|
},
|
|
|
borderColor: "#fff",
|
|
|
},
|
|
|
data: [
|
|
|
// { value: [3, 800], name: "A" },
|
|
|
// { value: [4, 1200], name: "B" },
|
|
|
// { value: [6, 600], name: "C" },
|
|
|
// { value: [7, 1400], name: "D" },
|
|
|
// { value: [10, 1400], },
|
|
|
// [4, 1200],
|
|
|
// [6, 600],
|
|
|
// [7, 1400],
|
|
|
],
|
|
|
type: "scatter",
|
|
|
},
|
|
|
],
|
|
|
};
|
|
|
|
|
|
option.value && myChart.setOption(option.value);
|
|
|
myChart.getZr().on("click", function (param) {
|
|
|
if (drawPointName.value == "") {
|
|
|
proxy.$modal.msgError("请选择要绘制的点");
|
|
|
return;
|
|
|
}
|
|
|
const pointInPixel = [param.offsetX, param.offsetY];
|
|
|
console.log("pointInPixel", pointInPixel);
|
|
|
// 使用 convertFromPixel方法 转换像素坐标值到逻辑坐标系上的点。获取点击位置对应的x轴数据的索引 值,借助于索引值的获取到其它的信息
|
|
|
// 转换X轴坐标
|
|
|
// let pointInGrid = myChart.convertFromPixel(
|
|
|
// { seriesIndex: 0 },
|
|
|
// pointInPixel
|
|
|
// );
|
|
|
pointInGrid.value = myChart.convertFromPixel({ seriesIndex: 0 }, pointInPixel);
|
|
|
// 转换Y轴坐标
|
|
|
// let pointInGrid2 = myChart.convertFromPixel({ seriesIndex: 1 }, pointInPixel);
|
|
|
// x轴数据的索引值
|
|
|
console.log("pointInGrid", pointInGrid.value);
|
|
|
option.value.series[0].data.push({
|
|
|
value: pointInGrid.value,
|
|
|
name: drawPointName.value,
|
|
|
color: drawPointColor.value,
|
|
|
});
|
|
|
option.value && myChart.setOption(option.value);
|
|
|
// console.log();
|
|
|
// 所点击点的X轴坐标点所在X轴data的下标
|
|
|
// let xIndex = pointInGrid[0];
|
|
|
// // 所点击点的Y轴坐标点数值
|
|
|
// let yIndex = pointInGrid2[1];
|
|
|
// // 使用getOption() 获取图表的option
|
|
|
// let op = myChart.getOption();
|
|
|
// //获取到x轴的索引值和option之后,我们就可以获取我们需要的任意数据。
|
|
|
// // 点击点的X轴对应坐标的名称
|
|
|
// var time = op.xAxis[0].data[xIndex];
|
|
|
// // 点击点的series -- data对应的值
|
|
|
// var value = op.series[0].data[xIndex];
|
|
|
// console.log("val", time);
|
|
|
});
|
|
|
};
|
|
|
const step4EchartInit = () => {
|
|
|
var chartDom = document.getElementById("charts2");
|
|
|
var myChart = echarts.init(chartDom, "dark");
|
|
|
// var option;
|
|
|
|
|
|
option2.value = {
|
|
|
xAxis: {
|
|
|
name: "X",
|
|
|
show: true,
|
|
|
max: 10,
|
|
|
min: 0,
|
|
|
interval: 1,
|
|
|
axisPointer: {
|
|
|
show: true,
|
|
|
label: {
|
|
|
precision: 0,
|
|
|
},
|
|
|
// snap: true,
|
|
|
},
|
|
|
},
|
|
|
yAxis: {
|
|
|
name: "Y",
|
|
|
show: true,
|
|
|
interval: 200,
|
|
|
max: 2000,
|
|
|
min: 0,
|
|
|
axisPointer: {
|
|
|
show: true,
|
|
|
// snap: true,
|
|
|
label: {
|
|
|
precision: 0,
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
series: [
|
|
|
{
|
|
|
symbolSize: 20,
|
|
|
label: {
|
|
|
show: true, // 显示标签
|
|
|
formatter: function (params) {
|
|
|
// 自定义显示的文本内容,params是包含数据信息的对象
|
|
|
return params.data.name;
|
|
|
},
|
|
|
position: "top", // 文本位置,可以是 'top', 'left', 'right', 'bottom', 'inside', 或者是 {top, left} 形式的具体位置
|
|
|
},
|
|
|
itemStyle: {
|
|
|
color: function (params) {
|
|
|
// 自定义显示的文本内容,params是包含数据信息的对象
|
|
|
return params.data.color;
|
|
|
},
|
|
|
borderColor: "#fff",
|
|
|
},
|
|
|
data: [
|
|
|
// { value: [3, 800], name: "A" },
|
|
|
// { value: [4, 1200], name: "B" },
|
|
|
// { value: [6, 600], name: "C" },
|
|
|
// { value: [7, 1400], name: "D" },
|
|
|
// { value: [10, 1400], },
|
|
|
// [4, 1200],
|
|
|
// [6, 600],
|
|
|
// [7, 1400],
|
|
|
],
|
|
|
type: "scatter",
|
|
|
},
|
|
|
],
|
|
|
};
|
|
|
|
|
|
option2.value && myChart.setOption(option2.value);
|
|
|
myChart.getZr().on("click", function (param) {
|
|
|
if (drawPointNameStep4.value == "") {
|
|
|
proxy.$modal.msgError("请选择要绘制的点");
|
|
|
return;
|
|
|
}
|
|
|
const pointInPixel = [param.offsetX, param.offsetY];
|
|
|
console.log("pointInPixel4", pointInPixel);
|
|
|
//将偏移值转化为坐标值
|
|
|
pointInGridStep4.value = myChart.convertFromPixel({ seriesIndex: 0 }, pointInPixel);
|
|
|
console.log("pointInGrid4", pointInGridStep4.value);
|
|
|
option2.value.series[0].data.push({
|
|
|
value: pointInGridStep4.value,
|
|
|
name: drawPointNameStep4.value,
|
|
|
color: drawPointColorStep4.value,
|
|
|
});
|
|
|
option2.value && myChart.setOption(option2.value);
|
|
|
});
|
|
|
};
|
|
|
const step5EchartInit = () => {
|
|
|
// 散点数据
|
|
|
const marksData = [
|
|
|
{
|
|
|
name: "A",
|
|
|
value: [3, 800],
|
|
|
color: "#009FF1",
|
|
|
},
|
|
|
{
|
|
|
name: "B",
|
|
|
value: [4, 1200],
|
|
|
color: "#FB54A1",
|
|
|
},
|
|
|
{
|
|
|
name: "C",
|
|
|
value: [6, 600],
|
|
|
color: "#FE8D2A",
|
|
|
},
|
|
|
{
|
|
|
name: "D",
|
|
|
value: [7, 1400],
|
|
|
color: "#6E70F0",
|
|
|
},
|
|
|
];
|
|
|
// 中心线
|
|
|
const centerLine = [
|
|
|
{
|
|
|
name: "y",
|
|
|
xAxis: 5,
|
|
|
},
|
|
|
{
|
|
|
name: "x",
|
|
|
yAxis: 1000,
|
|
|
},
|
|
|
];
|
|
|
// 中心点
|
|
|
const centerMark = [
|
|
|
{
|
|
|
value: "中心点",
|
|
|
coord: [5, 1000],
|
|
|
},
|
|
|
];
|
|
|
|
|
|
optionStep5.value = {
|
|
|
tooltip: {
|
|
|
axisPointer: {
|
|
|
show: true,
|
|
|
type: "cross",
|
|
|
lineStyle: {
|
|
|
type: "dashed",
|
|
|
width: 1,
|
|
|
},
|
|
|
label: {
|
|
|
backgroundColor: "#555",
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
grid: {
|
|
|
left: 50,
|
|
|
right: 50,
|
|
|
bottom: "4%",
|
|
|
top: "6%",
|
|
|
containLabel: true,
|
|
|
},
|
|
|
xAxis: {
|
|
|
scale: true,
|
|
|
max: 10,
|
|
|
min: 0,
|
|
|
interval: 1,
|
|
|
axisLine: {
|
|
|
lineStyle: {
|
|
|
color: "#ddd",
|
|
|
},
|
|
|
},
|
|
|
axisLabel: {
|
|
|
color: "#666",
|
|
|
},
|
|
|
axisPointer: {
|
|
|
show: true,
|
|
|
label: {
|
|
|
precision: 0,
|
|
|
},
|
|
|
// snap: true,
|
|
|
},
|
|
|
splitLine: {
|
|
|
lineStyle: {
|
|
|
color: "#eee",
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
yAxis: {
|
|
|
max: 2000,
|
|
|
min: 0,
|
|
|
interval: 200,
|
|
|
scale: true,
|
|
|
axisLine: {
|
|
|
lineStyle: {
|
|
|
color: "#ddd",
|
|
|
},
|
|
|
},
|
|
|
axisPointer: {
|
|
|
show: true,
|
|
|
label: {
|
|
|
precision: 0,
|
|
|
},
|
|
|
// snap: true,
|
|
|
},
|
|
|
axisLabel: {
|
|
|
color: "#666",
|
|
|
},
|
|
|
splitLine: {
|
|
|
lineStyle: {
|
|
|
color: "#eee",
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
series: [
|
|
|
{
|
|
|
type: "scatter",
|
|
|
data: marksData,
|
|
|
label: {
|
|
|
show: true,
|
|
|
position: "bottom",
|
|
|
formatter: "{b}",
|
|
|
},
|
|
|
itemStyle: {
|
|
|
shadowBlur: 2,
|
|
|
shadowColor: "rgba(120, 36, 50, 0.5)",
|
|
|
shadowOffsetY: 1,
|
|
|
color: function (params) {
|
|
|
// 自定义显示的文本内容,params是包含数据信息的对象
|
|
|
return params.data.color;
|
|
|
},
|
|
|
// color: function (e) {
|
|
|
// let randomColor =
|
|
|
// "rgba(" +
|
|
|
// Math.floor(Math.random() * 240) +
|
|
|
// "," +
|
|
|
// Math.floor(Math.random() * 240) +
|
|
|
// "," +
|
|
|
// Math.floor(Math.random() * 240) +
|
|
|
// "," +
|
|
|
// ".8" +
|
|
|
// ")";
|
|
|
// return randomColor.substring();
|
|
|
// },
|
|
|
},
|
|
|
// 各象限区域,需要结合中心线的位置来画出四个象限的markArea
|
|
|
markArea: {
|
|
|
silent: true,
|
|
|
data: [
|
|
|
// 第一象限
|
|
|
[
|
|
|
{
|
|
|
// 标域左上角的数据,也就是要设置矩形左边和上边的值
|
|
|
name: "第一象限",
|
|
|
xAxis: 5, // x 轴开始位置(中心线的值)
|
|
|
yAxis: 2000, // y 轴结束位置(y轴最大值)
|
|
|
itemStyle: {
|
|
|
// color: "rgba(52, 134, 207, 0.6)",
|
|
|
},
|
|
|
label: {
|
|
|
position: "inside",
|
|
|
color: "#fff",
|
|
|
fontSize: 22,
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
// 标域右下角的数据,矩形域右边和下边的值
|
|
|
yAxis: 1000, // y 轴开始位置(中心线的值)
|
|
|
},
|
|
|
],
|
|
|
// 第二象限
|
|
|
[
|
|
|
{
|
|
|
name: "第二象限",
|
|
|
yAxis: 2000, // y 轴结束位置(取y轴最大值)
|
|
|
itemStyle: {
|
|
|
// color: "rgba(177, 130, 192, 0.6)",
|
|
|
},
|
|
|
label: {
|
|
|
position: "inside",
|
|
|
color: "#fff",
|
|
|
fontSize: 22,
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
xAxis: 5, // x 轴结束位置(中心线位置)
|
|
|
yAxis: 1000, // y 轴开始位置(中心线位置)
|
|
|
},
|
|
|
],
|
|
|
// 第三象限
|
|
|
[
|
|
|
{
|
|
|
name: "第三象限",
|
|
|
yAxis: 1000, // y 轴结束位置(中心线位置)
|
|
|
itemStyle: {
|
|
|
// color: "rgba(254, 141, 42, 0.6)",
|
|
|
},
|
|
|
label: {
|
|
|
position: "inside",
|
|
|
color: "#fff",
|
|
|
fontSize: 22,
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
xAxis: 5, // x 轴结束位置(中心线位置)
|
|
|
yAxis: 0, // y 轴开始位置(y轴最小值)
|
|
|
},
|
|
|
],
|
|
|
// 第四象限
|
|
|
[
|
|
|
{
|
|
|
name: "第四象限",
|
|
|
xAxis: 5, // x 轴开始位置(中心线位置)
|
|
|
yAxis: 1000, // y 轴结束位置(中心线位置)
|
|
|
itemStyle: {
|
|
|
// color: "rgba(0, 184, 105, 0.6)",
|
|
|
},
|
|
|
label: {
|
|
|
position: "inside",
|
|
|
color: "#FFF",
|
|
|
fontSize: 22,
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
yAxis: 0, // y轴开始位置(y轴最小值)
|
|
|
},
|
|
|
],
|
|
|
],
|
|
|
},
|
|
|
// 中心点交集象限轴
|
|
|
markLine: {
|
|
|
silent: true, // 是否不响应鼠标事件
|
|
|
precision: 2, // 精度
|
|
|
lineStyle: {
|
|
|
type: "solid",
|
|
|
color: "#00aca6",
|
|
|
},
|
|
|
label: {
|
|
|
color: "#00aca6",
|
|
|
position: "end",
|
|
|
formatter: "{b}",
|
|
|
},
|
|
|
data: centerLine,
|
|
|
},
|
|
|
// 中心点
|
|
|
markPoint: {
|
|
|
symbol: "roundRect",
|
|
|
symbolSize: 15,
|
|
|
itemStyle: {
|
|
|
color: "rgba(234, 85, 6, .8)",
|
|
|
},
|
|
|
label: {
|
|
|
position: "top",
|
|
|
},
|
|
|
data: centerMark,
|
|
|
},
|
|
|
},
|
|
|
],
|
|
|
};
|
|
|
var chartDom = document.getElementById("charts3");
|
|
|
var myChart = echarts.init(chartDom, "dark");
|
|
|
optionStep5.value && myChart.setOption(optionStep5.value);
|
|
|
myChart.getZr().on("click", function (param) {
|
|
|
if (drawPointColorStep5.value == "") {
|
|
|
proxy.$modal.msgError("请选择要绘制的点");
|
|
|
return;
|
|
|
}
|
|
|
const pointInPixel = [param.offsetX, param.offsetY];
|
|
|
console.log("pointInPixel5", pointInPixel);
|
|
|
//将偏移值转化为坐标值
|
|
|
pointInGridStep5.value = myChart.convertFromPixel({ seriesIndex: 0 }, pointInPixel);
|
|
|
console.log("pointInGrid5", pointInGridStep5.value);
|
|
|
if (pointInGridStep5.value[0] > 5 && pointInGridStep5.value[1] > 1000) {
|
|
|
optionStep5.value.series[0].markArea.data[0][0].itemStyle.color = drawPointColorStep5.value;
|
|
|
optionStep5.value.series[0].markArea.data[0][0].name = drawPointNameStep5.value;
|
|
|
console.log(optionStep5.value);
|
|
|
}
|
|
|
if (pointInGridStep5.value[0] < 5 && pointInGridStep5.value[1] > 1000) {
|
|
|
optionStep5.value.series[0].markArea.data[1][0].itemStyle.color = drawPointColorStep5.value;
|
|
|
optionStep5.value.series[0].markArea.data[1][0].name = drawPointNameStep5.value;
|
|
|
console.log(optionStep5.value);
|
|
|
}
|
|
|
if (pointInGridStep5.value[0] < 5 && pointInGridStep5.value[1] < 1000) {
|
|
|
optionStep5.value.series[0].markArea.data[2][0].itemStyle.color = drawPointColorStep5.value;
|
|
|
optionStep5.value.series[0].markArea.data[2][0].name = drawPointNameStep5.value;
|
|
|
console.log(optionStep5.value);
|
|
|
}
|
|
|
if (pointInGridStep5.value[0] > 5 && pointInGridStep5.value[1] < 1000) {
|
|
|
optionStep5.value.series[0].markArea.data[3][0].itemStyle.color = drawPointColorStep5.value;
|
|
|
optionStep5.value.series[0].markArea.data[3][0].name = drawPointNameStep5.value;
|
|
|
console.log(optionStep5.value);
|
|
|
}
|
|
|
optionStep5.value && myChart.setOption(optionStep5.value);
|
|
|
});
|
|
|
};
|
|
|
const drawQuadrant = (name, color) => {
|
|
|
drawPointColorStep5.value = color;
|
|
|
drawPointNameStep5.value = name;
|
|
|
console.log(drawPointColorStep5.value);
|
|
|
};
|
|
|
const step1Submit = () => {
|
|
|
step1Error.value = 0;
|
|
|
for (let i in step1Data.value) {
|
|
|
if (!step1Data.value[i].params1 || !step1Data.value[i].params2) {
|
|
|
proxy.$modal.msgError("请先完成所有填空");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
if (step1Data.value[0].params1 && step1Data.value[0].params1 !== "3") {
|
|
|
step1Error.value++;
|
|
|
}
|
|
|
if (step1Data.value[0].params2 && step1Data.value[0].params2 !== "800") {
|
|
|
step1Error.value++;
|
|
|
}
|
|
|
if (step1Data.value[1].params1 && step1Data.value[1].params1 !== "4") {
|
|
|
step1Error.value++;
|
|
|
}
|
|
|
if (step1Data.value[1].params2 && step1Data.value[1].params2 !== "1200") {
|
|
|
step1Error.value++;
|
|
|
}
|
|
|
if (step1Data.value[2].params1 && step1Data.value[2].params1 !== "6") {
|
|
|
step1Error.value++;
|
|
|
}
|
|
|
if (step1Data.value[2].params2 && step1Data.value[2].params2 !== "600") {
|
|
|
step1Error.value++;
|
|
|
}
|
|
|
if (step1Data.value[3].params1 && step1Data.value[3].params1 !== "7") {
|
|
|
step1Error.value++;
|
|
|
}
|
|
|
if (step1Data.value[3].params2 && step1Data.value[3].params2 !== "1400") {
|
|
|
step1Error.value++;
|
|
|
}
|
|
|
console.log(step1Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step1AnswerFlag.value = true;
|
|
|
for (let k in step1Data.value) {
|
|
|
step2Data.value[k].amount = step1Data.value[k].params1;
|
|
|
step2Data.value[k].account = step1Data.value[k].params2;
|
|
|
}
|
|
|
};
|
|
|
const step2Submit = () => {
|
|
|
step2Error.value = 0;
|
|
|
if (!step2Data.value[4].params1 || !step2Data.value[4].params2) {
|
|
|
proxy.$modal.msgError("请先完成所有填空");
|
|
|
return;
|
|
|
}
|
|
|
if (step2Data.value[4].params1 && step2Data.value[4].params1 !== "5") {
|
|
|
step2Error.value++;
|
|
|
}
|
|
|
if (step2Data.value[4].params2 && step2Data.value[4].params2 !== "1000") {
|
|
|
step2Error.value++;
|
|
|
}
|
|
|
console.log(step2Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step2AnswerFlag.value = true;
|
|
|
};
|
|
|
const step3Submit = () => {
|
|
|
step3Error.value = 0;
|
|
|
for (let i in option.value.series[0].data) {
|
|
|
console.log(option.value.series[0].data[i]);
|
|
|
if (option.value.series[0].data[i].name == "A") {
|
|
|
if (Math.round(option.value.series[0].data[i].value[0]) != 3 || Math.round(option.value.series[0].data[i].value[1]) != 800) {
|
|
|
step3Error.value++;
|
|
|
}
|
|
|
}
|
|
|
if (option.value.series[0].data[i].name == "B") {
|
|
|
if (Math.round(option.value.series[0].data[i].value[0]) != 4 || Math.round(option.value.series[0].data[i].value[1]) != 1200) {
|
|
|
step3Error.value++;
|
|
|
}
|
|
|
}
|
|
|
if (option.value.series[0].data[i].name == "C") {
|
|
|
if (Math.round(option.value.series[0].data[i].value[0]) != 6 || Math.round(option.value.series[0].data[i].value[1]) != 600) {
|
|
|
step3Error.value++;
|
|
|
}
|
|
|
}
|
|
|
if (option.value.series[0].data[i].name == "D") {
|
|
|
if (Math.round(option.value.series[0].data[i].value[0]) != 7 || Math.round(option.value.series[0].data[i].value[1]) != 1400) {
|
|
|
step3Error.value++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
console.log(step3Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step3AnswerFlag.value = true;
|
|
|
};
|
|
|
const step4Submit = () => {
|
|
|
step4Error.value = 0;
|
|
|
for (let i in option2.value.series[0].data) {
|
|
|
console.log(option2.value.series[0].data[i]);
|
|
|
if (option2.value.series[0].data[i].name == "A") {
|
|
|
if (Math.round(option2.value.series[0].data[i].value[0]) != 5 || Math.round(option2.value.series[0].data[i].value[1]) != 1000) {
|
|
|
step4Error.value++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
console.log(step4Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step4AnswerFlag.value = true;
|
|
|
};
|
|
|
const step5Submit = () => {
|
|
|
step5Error.value = 0;
|
|
|
if (optionStep5.value.series[0].markArea.data[0][0].name != "明星客户") {
|
|
|
step5Error.value++;
|
|
|
}
|
|
|
if (optionStep5.value.series[0].markArea.data[1][0].name != "问题客户") {
|
|
|
step5Error.value++;
|
|
|
}
|
|
|
if (optionStep5.value.series[0].markArea.data[2][0].name != "瘦狗客户") {
|
|
|
step5Error.value++;
|
|
|
}
|
|
|
if (optionStep5.value.series[0].markArea.data[3][0].name != "现金流客户") {
|
|
|
step5Error.value++;
|
|
|
}
|
|
|
console.log(step5Error.value, "错误数");
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
step5AnswerFlag.value = true;
|
|
|
};
|
|
|
const downloadData = () => {
|
|
|
// console.log(666);
|
|
|
// portraitModel
|
|
|
// .downloadDataByBoston({})
|
|
|
// .then((res) => {
|
|
|
// // console.log(res,'--');
|
|
|
// const blob = new Blob([res], { type: "application/vnd.ms-excel" });
|
|
|
// downBlobFile(`案例数据-波士顿矩阵分析`, blob);
|
|
|
// })
|
|
|
// .catch((error) => {});
|
|
|
window.open(baseUrl + "/api/downDataByUserPortrait/bostonMatrixAnalysisData");
|
|
|
};
|
|
|
const submitData = () => {
|
|
|
if (!step1AnswerFlag.value || !step2AnswerFlag.value || !step3AnswerFlag.value || !step4AnswerFlag.value || !step5AnswerFlag.value) {
|
|
|
proxy.$modal.msgError("请先完成所有步骤!");
|
|
|
return;
|
|
|
}
|
|
|
errorNum.value = step1Error.value + step2Error.value + step3Error.value + step4Error.value + step5Error.value;
|
|
|
console.log(errorNum.value, "总错误次数");
|
|
|
portraitModel
|
|
|
.submit({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
taskName: "波士顿矩阵分析",
|
|
|
numberOfErrors: errorNum.value,
|
|
|
})
|
|
|
.then((res) => {
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
})
|
|
|
.catch((error) => {});
|
|
|
};
|
|
|
const saveData = () => {
|
|
|
const params = {
|
|
|
stepFiveA: step1Data.value[0].params1,
|
|
|
stepFiveB: step1Data.value[0].params2,
|
|
|
stepFiveC: step1Data.value[1].params1,
|
|
|
stepFiveD: step1Data.value[1].params2,
|
|
|
stepSixA: step1Data.value[2].params1,
|
|
|
stepSixB: step1Data.value[2].params2,
|
|
|
stepSixC: step1Data.value[3].params1,
|
|
|
stepSixD: step1Data.value[3].params2,
|
|
|
stepSevenA: step2Data.value[4].params1,
|
|
|
stepSevenB: step2Data.value[4].params2,
|
|
|
// stepSevenC: JSON.stringify(option.value.series[0].data),
|
|
|
// stepSevenD: step2Data.value[5].params,
|
|
|
// stepEightA: step2Data.value[6].params,
|
|
|
// stepEightB: step2Data.value[7].params,
|
|
|
// stepEightC: step2Data.value[8].params,
|
|
|
// stepEightD: step2Data.value[9].params,
|
|
|
// stepNineA: step2Data.value[10].params,
|
|
|
// stepNineB: step2Data.value[11].params,
|
|
|
// stepNineC: step2Data.value[12].params,
|
|
|
// stepNineD: step2Data.value[13].params,
|
|
|
// stepTenA: step2Data.value[14].params,
|
|
|
// stepTenB: step2Data.value[15].params,
|
|
|
// stepTenC: step2Data.value[16].params,
|
|
|
// stepTenD: step2Data.value[17].params,
|
|
|
// stepElevenA: step2Data.value[18].params,
|
|
|
// stepOneA: step2Data.value[19].params,
|
|
|
// stepOneB: step2Data.value[20].params,
|
|
|
// stepOneC: step2Data.value[21].params,
|
|
|
// stepOneD: step2Data.value[22].params,
|
|
|
// stepTwoA: step2Data.value[23].params,
|
|
|
// stepTwoB: step2Data.value[24].params,
|
|
|
// stepTwoC: step2Data.value[25].params,
|
|
|
// stepThreeA: step2Data.value[26].params,
|
|
|
// stepThreeB: step2Data.value[27].params,
|
|
|
// stepThreeC: step2Data.value[28].params,
|
|
|
// stepThreeD: step2Data.value[29].params,
|
|
|
// stepFourA: step2Data.value[30].params,
|
|
|
// stepFourB: step2Data.value[31].params,
|
|
|
// stepFourC: step2Data.value[32].params,
|
|
|
// stepFourD: step2Data.value[33].params,
|
|
|
// stepNewOne: step2Data.value[34].params,
|
|
|
// stepNewTwo: step2Data.value[35].params,
|
|
|
// stepNewThree: step2Data.value[36].params,
|
|
|
// stepNewFive: step5DataTable3.value[3].params2,
|
|
|
// stepNewSix: step5DataTable3.value[4].params1,
|
|
|
// stepNewEight: step5DataTable3.value[4].params2,
|
|
|
};
|
|
|
portraitModel
|
|
|
.saveData({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
module: "波士顿矩阵分析",
|
|
|
...params,
|
|
|
})
|
|
|
.then((res) => {})
|
|
|
.catch((error) => {});
|
|
|
};
|
|
|
const getData = () => {
|
|
|
portraitModel
|
|
|
.getData({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
module: "波士顿矩阵分析",
|
|
|
})
|
|
|
.then((res) => {
|
|
|
step1Data.value[0].params1 = res.data.stepFiveA;
|
|
|
step1Data.value[0].params2 = res.data.stepFiveB;
|
|
|
step1Data.value[1].params1 = res.data.stepFiveC;
|
|
|
step1Data.value[1].params2 = res.data.stepFiveD;
|
|
|
step1Data.value[2].params1 = res.data.stepSixA;
|
|
|
step1Data.value[2].params2 = res.data.stepSixB;
|
|
|
step1Data.value[3].params1 = res.data.stepSixC;
|
|
|
step1Data.value[3].params2 = res.data.stepSixD;
|
|
|
step2Data.value[4].params1 = res.data.stepSevenA;
|
|
|
step2Data.value[4].params2 = res.data.stepSevenB;
|
|
|
// option.value.series[0].data = JSON.parse(res.data.stepSevenC);
|
|
|
// step2Data.value[5].params = res.data.stepSevenD;
|
|
|
// step2Data.value[6].params = res.data.stepEightA;
|
|
|
// step2Data.value[7].params = res.data.stepEightB;
|
|
|
// step2Data.value[8].params = res.data.stepEightC;
|
|
|
// step2Data.value[9].params = res.data.stepEightD;
|
|
|
// step2Data.value[10].params = res.data.stepNineA;
|
|
|
// step2Data.value[11].params = res.data.stepNineB;
|
|
|
// step2Data.value[12].params = res.data.stepNineC;
|
|
|
// step2Data.value[13].params = res.data.stepNineD;
|
|
|
// step2Data.value[14].params = res.data.stepTenA;
|
|
|
// step2Data.value[15].params = res.data.stepTenB;
|
|
|
// step2Data.value[16].params = res.data.stepTenC;
|
|
|
// step2Data.value[17].params = res.data.stepTenD;
|
|
|
// step2Data.value[18].params = res.data.stepElevenA;
|
|
|
// step2Data.value[19].params = res.data.stepOneA;
|
|
|
// step2Data.value[20].params = res.data.stepOneB;
|
|
|
// step2Data.value[21].params = res.data.stepOneC;
|
|
|
// step2Data.value[22].params = res.data.stepOneD;
|
|
|
// step2Data.value[23].params = res.data.stepTwoA;
|
|
|
// step2Data.value[24].params = res.data.stepTwoB;
|
|
|
// step2Data.value[25].params = res.data.stepTwoC;
|
|
|
// step2Data.value[26].params = res.data.stepThreeA;
|
|
|
// step2Data.value[27].params = res.data.stepThreeB;
|
|
|
// step2Data.value[28].params = res.data.stepThreeC;
|
|
|
// step2Data.value[29].params = res.data.stepThreeD;
|
|
|
// step2Data.value[30].params = res.data.stepFourA;
|
|
|
// step2Data.value[31].params = res.data.stepFourB;
|
|
|
// step2Data.value[32].params = res.data.stepFourC;
|
|
|
// step2Data.value[33].params = res.data.stepFourD;
|
|
|
// step2Data.value[34].params = res.data.stepNewOne;
|
|
|
// step2Data.value[35].params = res.data.stepNewTwo;
|
|
|
// step2Data.value[36].params = res.data.stepNewThree;
|
|
|
// step5DataTable3.value[3].params2 = res.data.stepNewFive;
|
|
|
// step5DataTable3.value[4].params1 = res.data.stepNewSix;
|
|
|
// step5DataTable3.value[4].params2 = res.data.stepNewEight;
|
|
|
// console.log(JSON.parse(res.data.stepSevenC));
|
|
|
})
|
|
|
.catch((error) => {});
|
|
|
};
|
|
|
const retrain = () => {
|
|
|
// console.log(666);
|
|
|
portraitModel
|
|
|
.retrain({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
module: "波士顿矩阵分析",
|
|
|
})
|
|
|
.then((res) => {
|
|
|
proxy.$modal.msgSuccess("重新实训成功");
|
|
|
for (let i in step1Data.value) {
|
|
|
step1Data.value[i].params1 = "";
|
|
|
step1Data.value[i].params2 = "";
|
|
|
}
|
|
|
step2Data.value[4].params1 = "";
|
|
|
step2Data.value[4].params2 = "";
|
|
|
})
|
|
|
.catch((error) => {});
|
|
|
};
|
|
|
defineExpose({
|
|
|
submitData,
|
|
|
retrain,
|
|
|
// practicalTraining,
|
|
|
});
|
|
|
</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/taskImport.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");
|
|
|
}
|
|
|
.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;
|
|
|
}
|
|
|
}
|
|
|
.drawPoint {
|
|
|
margin-left: 20px;
|
|
|
.point {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
margin-top: 15px;
|
|
|
.pointItem {
|
|
|
// width: 73px;
|
|
|
height: 19px;
|
|
|
padding-left: 10px;
|
|
|
padding-right: 10px;
|
|
|
background: #002651;
|
|
|
border: 1px solid #67b3d6;
|
|
|
text-align: center;
|
|
|
line-height: 19px;
|
|
|
font-size: 12px;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
span {
|
|
|
font-size: 12px;
|
|
|
color: #6e70f0;
|
|
|
margin-left: 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-table td {
|
|
|
padding-top: 4px;
|
|
|
padding-bottom: 4px;
|
|
|
}
|
|
|
</style>
|