You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dianshang-qianduan/src/views/demand/index.vue

560 lines
18 KiB
Vue

2 months ago
<template>
<div class="content app-container">
<div class="handren">
<div class="left">
<el-button>蛋糕指数分析</el-button>
</div>
<div class="right">
<el-button @click="dialogVisible = true" type="primary" id="brtn">任务背景与目标</el-button>
<popModel :showModel="dialogVisible" title="任务背景:" @closePop="dialogVisible = false">
<template v-slot:content>
<p style="font-size: 1rem">
市场竞争加剧随着电商平台的不断增多市场竞争日益激烈为了保持竞争优势电商平台需要深入了解市场需求以便制定有效的市场策略
<br />
<br />
消费者需求多样化随着生活水平的提高和消费观念的转变消费者对线上购物的需求日益多样化这要求电商平台必须准确把握消费者需求提供个性化差异化的产品和服务
<br />
<br />
技术进步推动行业变革大数据人工智能云计算等新技术的广泛应用为电商市场带来了前所未有的变革这些技术不仅提高了电商平台的运营效率还为消费者提供了更加便捷智能的购物体验因此电商平台需要紧跟技术发展趋势不断创新和优化产品和服务
<br />
<br />
任务目标
<br />
<br />
了解行业需求分析用到的数据源及分析方法
<br />
<br />
①用户画像数据用户年龄性别分布用户地域分布用户消费偏好与习惯对客户数据进行描述性统计和聚类分析
<br />
<br />
②市场销售数据某个行业商品类目支付额及商家数量电商市场或者该类目父市场支付额总商家数量等通过计算蛋糕指数判断市场需求状况
<br />
<br />
</p>
</template>
</popModel>
</div>
</div>
<p>
蛋糕指数的含义
<br />
蛋糕指数用于衡量一个商品或类目在电商市场中的相对潜力和竞争状况它反映了在特定父行业或市场某商品或类目的支付金额占比相对于该行业商家数占比的情况其公式为蛋糕指数=支付金额较父行业占比/父行业商家数占比
<br />
支付金额较父行业占比指的是某一类目例如淘宝母婴童装童鞋类目的支付金额占其父行业例如母婴行业总支付金额的比例这个比例反映了该类目在父行业中的市场规模或市场容量
<br />
父行业商家数占比指的是该类目中的商家数占其父行业中总商家数的比例这个比例反映了该类目的竞争程度
<br />
<br />
蛋糕指数的应用
<br />
判断市场潜力蛋糕指数越高通常意味着该商品或类目的市场潜力越大但需要结合市场容量和竞争状况进行具体分析
<br />
分析竞争态势通过蛋糕指数可以了解某商品或类目在特定市场中的竞争程度例如蛋糕指数大且市场容量小可能意味着市场竞争度较低但需要进一步分析增长趋势以确定是否值得进入
<br />
指导市场策略电商企业可以根据蛋糕指数来制定和调整市场策略例如对于蛋糕指数高且市场容量大的商品或类目可以加大投入和推广力度而对于蛋糕指数低且市场容量小的商品或类目则可能需要考虑退出或调整经营策略
<br />
<br />
实训操作
<br />
任务要求请分析淘宝母婴行业童装童鞋的蛋糕指数分析童装童鞋相关需求为店铺产品规划及运营提供决策支持
<br />
</p>
<el-tabs type="border-card" style="width: 100%" v-model="activeNames">
<el-tab-pane label="年度数据" name="0">
<el-table
:data="tableData"
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="父行业" align="center" prop="data2"></el-table-column>
<el-table-column label="父行业销售额(亿元)" align="center" prop="data3"></el-table-column>
<el-table-column label="父行业商家数(万)" align="center" prop="data4"></el-table-column>
<el-table-column label="子类目" align="center" prop="data5"></el-table-column>
<el-table-column label="子类目销售额(亿元)" align="center" prop="data6"></el-table-column>
<el-table-column label="子类目商家数(万)" align="center" prop="data7"></el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="月度数据" name="1">
<el-table
:data="ecommerceData"
border
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column label="月份‌" align="center" prop="month"></el-table-column>
<el-table-column label="父行业" align="center" prop="parentIndustry"></el-table-column>
<el-table-column label="父行业商家数量(万)" align="center" prop="parentMerchantCount"></el-table-column>
<el-table-column label="父行业销售额(亿元)" align="center" prop="parentSales"></el-table-column>
<el-table-column label="子类目" align="center" prop="subCategory"></el-table-column>
<el-table-column label="子类目商家数量(万)" align="center" prop="subMerchantCount"></el-table-column>
<el-table-column label="子类目销售额(亿元)" align="center" prop="subSales"></el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<p>请根据上述数据及蛋糕指数公式分别计算年度数据和月度数据下母婴行业童装童鞋的蛋糕指数计算结果保留两位小数计算完成后生成蛋糕指数走势图</p>
<div style="display: flex; gap: 20px">
<el-tabs type="border-card" style="width: 50%" v-model="activeName">
<el-tab-pane label="年度蛋糕指数" name="0">
<el-table
:data="annualIndex"
border
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column label="月份‌" align="center" prop="year"></el-table-column>
<el-table-column label="童装童鞋类目年度蛋糕指数" align="center" prop="yearAnswer">
<template #default="{ row }">
<el-input v-model="row.yearAnswer" placeholder="" />
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="月度蛋糕指数" name="1">
<el-table
:data="monthlyIndex"
border
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column label="月份‌" align="center" prop="year"></el-table-column>
<el-table-column label="月度蛋糕指数" align="center" prop="monthAnswer">
<template #default="{ row }">
<el-input v-model="row.monthAnswer" placeholder="" />
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<div style="display: flex; flex-direction: column; flex: 1; gap: 20px">
<div>
<el-button type="primary" style="width: 10vw" @click="getIndex('monthlyIndex')"></el-button>
<el-button type="primary" style="width: 7vw" @click="onClick"></el-button>
</div>
<br />
<div id="main" ref="main" style="width: 100%; height: 50vh"></div>
</div>
</div>
<p>请根据上述数据计算分析童装童鞋行业年度蛋糕指数走势和月度蛋糕指数走势的区别假如您所在的公司是大型成熟企业想要提高市场竞争力对公司原有童装童鞋款式进行更新 那么这种情况下更适合使用年度数据还是月度数据请说明理由</p>
<el-input v-model="textarea2" :autosize="{ minRows: 6, maxRows: 8 }" type="textarea" placeholder="" />
<div class="taskfooter">
<el-button @click="submitTask"></el-button>
<el-button @click="reTraining"></el-button>
</div>
</div>
</template>
<script setup>
import * as echarts from "echarts";
import popModel from "@/views/components/popModal.vue";
import useUserStore from "@/store/modules/user";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
import * as analysisAPI from "@/api/market-demand-mining.js";
const activeName = ref("0");
const activeNames = ref("0");
const textarea2 = ref("");
const dialogVisible = ref(false);
const main = ref(null);
const tableData = [
{
data1: "2018年",
data2: "母婴行业",
data3: "2800",
data4: "6.5",
data5: "童装童鞋",
data6: "550",
data7: "4.5",
},
{
data1: "2019年",
data2: "母婴行业",
data3: "3600",
data4: "7.8",
data5: "童装童鞋",
data6: "680",
data7: "5.8",
},
{
data1: "2020年",
data2: "母婴行业",
data3: "4500",
data4: "9.5",
data5: "童装童鞋",
data6: "820",
data7: "7.2",
},
{
data1: "2021年",
data2: "母婴行业",
data3: "5800",
data4: "11.2",
data5: "童装童鞋",
data6: "950",
data7: "8.5",
},
{
data1: "2022年",
data2: "母婴行业",
data3: "7200",
data4: "13.8",
data5: "童装童鞋",
data6: "1050",
data7: "9.7",
},
{
data1: "2023年",
data2: "母婴行业",
data3: "8500",
data4: "16.5",
data5: "童装童鞋",
data6: "1250",
data7: "11.2",
},
{
data1: "2024年",
data2: "母婴行业",
data3: "11000",
data4: "20",
data5: "童装童鞋",
data6: "1450",
data7: "13.5",
},
];
const ecommerceData = [
{
month: "2024年4月",
parentIndustry: "母婴行业",
parentMerchantCount: 20.0,
parentSales: 675,
subCategory: "童装童鞋",
subMerchantCount: 13.5,
subSales: 95,
},
{
month: "2024年5月",
parentIndustry: "母婴行业",
parentMerchantCount: 20.3,
parentSales: 810,
subCategory: "童装童鞋",
subMerchantCount: 13.7,
subSales: 110,
},
{
month: "2024年6月",
parentIndustry: "母婴行业",
parentMerchantCount: 20.7,
parentSales: 2025,
subCategory: "童装童鞋",
subMerchantCount: 14.0,
subSales: 280,
},
{
month: "2024年7月",
parentIndustry: "母婴行业",
parentMerchantCount: 21.0,
parentSales: 540,
subCategory: "童装童鞋",
subMerchantCount: 14.2,
subSales: 80,
},
{
month: "2024年8月",
parentIndustry: "母婴行业",
parentMerchantCount: 21.3,
parentSales: 540,
subCategory: "童装童鞋",
subMerchantCount: 14.5,
subSales: 120,
},
{
month: "2024年9月",
parentIndustry: "母婴行业",
parentMerchantCount: 21.7,
parentSales: 675,
subCategory: "童装童鞋",
subMerchantCount: 14.8,
subSales: 140,
},
{
month: "2024年10月",
parentIndustry: "母婴行业",
parentMerchantCount: 22.0,
parentSales: 810,
subCategory: "童装童鞋",
subMerchantCount: 15.0,
subSales: 180,
},
{
month: "2024年11月",
parentIndustry: "母婴行业",
parentMerchantCount: 22.3,
parentSales: 2700,
subCategory: "童装童鞋",
subMerchantCount: 15.3,
subSales: 420,
},
{
month: "2024年12月",
parentIndustry: "母婴行业",
parentMerchantCount: 22.7,
parentSales: 1350,
subCategory: "童装童鞋",
subMerchantCount: 15.6,
subSales: 200,
},
{
month: "2025年1月",
parentIndustry: "母婴行业",
parentMerchantCount: 23.0,
parentSales: 1080,
subCategory: "童装童鞋",
subMerchantCount: 15.8,
subSales: 160,
},
{
month: "2025年2月",
parentIndustry: "母婴行业",
parentMerchantCount: 23.3,
parentSales: 675,
subCategory: "童装童鞋",
subMerchantCount: 16.0,
subSales: 70,
},
{
month: "2025年3月",
parentIndustry: "母婴行业",
parentMerchantCount: 23.7,
parentSales: 810,
subCategory: "童装童鞋",
subMerchantCount: 16.3,
subSales: 150,
},
];
const annualIndex = ref([
{
year: "2018年",
yearAnswer: null,
},
{
year: "2019年",
yearAnswer: null,
},
{
year: "2020年",
yearAnswer: null,
},
{
year: "2021年",
yearAnswer: null,
},
{
year: "2022年",
yearAnswer: null,
},
{
year: "2023年",
yearAnswer: null,
},
{
year: "2024年",
yearAnswer: null,
},
]);
const monthlyIndex = ref([
{
year: "2024年4月",
monthAnswer: null,
},
{
year: "2024年5月",
monthAnswer: null,
},
{
year: "2024年6月",
monthAnswer: null,
},
{
year: "2024年7月",
monthAnswer: null,
},
{
year: "2024年8月",
monthAnswer: null,
},
{
year: "2024年9月",
monthAnswer: null,
},
{
year: "2024年10月",
monthAnswer: null,
},
{
year: "2024年11月",
monthAnswer: null,
},
{
year: "2024年12月",
monthAnswer: null,
},
{
year: "2025年1月",
monthAnswer: null,
},
{
year: "2025年2月",
monthAnswer: null,
},
{
year: "2025年3月",
monthAnswer: null,
},
]);
const getIndex = (str) => {
let arr = activeName.value == "0" ? annualIndex.value.map((item) => item.year) : monthlyIndex.value.map((item) => item.year);
let index = activeName.value == "0" ? annualIndex.value.map((item) => item.yearAnswer) : monthlyIndex.value.map((item) => item.monthAnswer);
if (str == "monthlyIndex") {
if (index.every((item) => item == null)) {
proxy.$modal.msgWarning(`请先填写${activeName.value == "0" ? "年度" : "月度"}数据!`);
}
}
if (index.every((item) => item == null)) return;
index = index.map((item) => Number(item));
var myChart = echarts.init(main.value);
myChart.setOption({
xAxis: {
type: "category",
data: arr,
},
yAxis: {
type: "value",
},
series: [
{
data: index,
type: "line",
},
],
});
const resizeHandler = debounce(() => {
myChart?.resize(); // 仅调整尺寸,不重新初始化
}, 100);
window.addEventListener("resize", resizeHandler);
// 组件卸载时清理
onUnmounted(() => {
window.removeEventListener("resize", resizeHandler);
myChart?.dispose();
});
// 防抖函数(减少高频触发)
function debounce(fn, delay) {
let timer;
return () => {
clearTimeout(timer);
timer = setTimeout(fn, delay);
};
}
};
// 下载数据
const onClick = () => {
analysisAPI
.competitionEnvironmentDownload({
userId: userStore.userInfo.userId,
module: "行业需求分析",
fileName: activeNames.value == "0" ? "年度数据" : "月度数据",
})
.then((res) => {
// 数据下载
const blob = new Blob([res], {
type: "application/vnd.ms-excel",
});
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", `${activeNames.value == "0" ? "年度数据" : "月度数据"}.xlsx`);
document.body.appendChild(link);
link.click();
proxy.$modal.msgSuccess("数据下载成功");
});
};
// 提交任务
const submitTask = () => {
if (annualIndex.value.every((item) => item.yearAnswer == null) && monthlyIndex.value.every((item) => item.monthAnswer == null)) {
proxy.$modal.msgWarning(`请先填写${activeNames.value == "0" ? "年度" : "月度"}数据!`);
return;
}
analysisAPI
.industryDemandAnalysisSubmit({
userId: userStore.userInfo.userId,
schoolId: userStore.userInfo.schoolId,
monthlyCakeIndexList: monthlyIndex.value,
yearCakeIndexDtoList: annualIndex.value,
context: textarea2.value,
})
.then((res) => {
proxy.$modal.msgSuccess("提交成功");
});
};
const reTraining = () => {
analysisAPI
.industryDemandAnalysisReTrain({
userId: userStore.userInfo.userId,
module: "行业需求分析",
})
.then((res) => {
// 清空数据
annualIndex.value.forEach((item) => {
item.yearAnswer = null;
});
monthlyIndex.value.forEach((item) => {
item.monthAnswer = null;
});
textarea2.value = "";
proxy.$modal.msgSuccess("重新实训成功");
});
};
// 回显行业需求分析
const getZJData = () => {
analysisAPI
.industryDemandAnalysisEcho({
userId: userStore.userInfo.userId,
})
.then((res) => {
if (res.data) {
annualIndex.value.forEach((item, index) => {
item.yearAnswer = res.data.yearCakeIndexDtoList[index].yearAnswer;
});
monthlyIndex.value.forEach((item, index) => {
item.monthAnswer = res.data.monthlyCakeIndexList[index].monthAnswer;
});
textarea2.value = res.data.context;
getIndex();
}
});
};
onMounted(() => {
getIndex();
getZJData();
});
</script>
<style lang='scss' scoped>
.app-container {
background: #ffffff;
}
.content {
}
</style>