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/assessment/index.vue

440 lines
16 KiB
Vue

<template>
<div class="index app-container student-training-shell legacy-training-page">
<TrainingIntro title="功效系数法">
<template #background>
<p>
电商产品表现分析的主要目的是了解产品在市场中的实际表现,以便企业能够及时调整产品策略、优化运营、提高市场竞争力。通过分析,企业可以识别出产品的优势与不足,进而制定更有效的营销策略和产品开发计划。
4 months ago
<br />
<br />
分析维度
<br />
‌销售数据‌:
<br />
‌销售额与销量‌:分析产品的总销售额和销量,以了解产品的整体销售情况。高销售额和销量通常意味着产品受欢迎程度高,市场需求大。
<br />
‌销售趋势‌:通过分析产品在不同时间段(如日、周、月)的销售数据,识别销售高峰和低谷,以便企业能够提前布局促销活动,平衡销售周期。
<br />
‌单品贡献率‌:衡量某个产品对整体销售额的贡献度。根据贡献度,企业可以调整推广策略,集中资源对高贡献产品进行进一步的营销。
<br />
‌库存情况‌:
<br />
‌库存周转率‌:反映产品的周转速度。高库存周转率通常意味着产品畅销,而低周转率则可能是滞销的标志。通过分析库存周转率,企业可以实时调整库存量,避免过多的滞销产品和缺货问题。
<br />
‌缺货率‌:指产品因库存不足导致无法满足客户需求的比例。高缺货率会直接影响销售收入和顾客满意度。企业需要建立库存预警系统,及时补货以降低缺货率。
<br />
‌退货情况‌:
<br />
‌退货率‌:衡量产品在销售过程中退货的比例。高退货率可能意味着产品质量问题、商品描述不准确或客户期望值过高等问题。企业需要通过退货分析找出问题产品,并及时采取改进措施。
<br />
‌退货原因分析‌:通过分析退货的原因(如商品质量、物流问题等),企业可以发现产品描述不准确、运输损坏或客户对产品不满意等问题,从而优化商品展示、包装和物流管理。
<br />
‌消费者反馈‌:
<br />
‌用户评价‌:收集和分析消费者对产品的评价,了解产品的优点和不足。正面评价有助于提升产品口碑和品牌形象,而负面评价则需要企业及时关注和解决。
<br />
‌用户满意度‌:通过调查或问卷等方式了解用户对产品的满意度。高满意度意味着产品能够满足消费者需求,而低满意度则需要企业进行深入分析并采取改进措施。
</p>
</template>
<template #goal>
<p>
根据商品合格率、订单响应时长、用户评分、退货率数据,采用功效系数法,对产品表现进行量化评分,根据评分结果制定对应策略。
</p>
</template>
</TrainingIntro>
<div class="legacy-training-toolbar">
<TrainingTaskToolbar task-key="product-diagnosis-iteration" />
</div>
<div class="training-step-area">
4 months ago
<p>功效系数法:绩效评估的标准化工具‌,将各指标数据通过标准化处理消除量纲差异,转化为“功效值”后加权计算综合得分,适用于多维度绩效评估‌,可用于分析电商产品表现。</p>
<div class="caseBacktitle">
<span>实验实训:</span>
</div>
<p>某电商对商品质量、交付时效、用户评分、退货率等指标进行标准化处理,权重分配后计算商品综合得分。综合得分90分以上为A级,80-90分为B级,80分以下为C级。</p>
<p>对标头部电商标准,我们的指标评价标准如下所示:</p>
<el-table
:data="metrics"
border
style="width: 60%; margin-top: 10px"
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column prop="name" label="指标" align="center"></el-table-column>
<el-table-column label="满意值(上限)" align="center" prop="satisfactoryValue"></el-table-column>
<el-table-column prop="unacceptableValue" label="不允许值(下限)" align="center"></el-table-column>
<el-table-column prop="dataSource" label="数据来源" align="center"></el-table-column>
</el-table>
<p>从店铺后台可看到某款商品采购销售数据如下所示:</p>
<el-table
:data="performanceData"
border
style="width: 40%; margin-top: 10px"
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column prop="indicator" label="指标" align="center"></el-table-column>
<el-table-column label="指标值" align="center" prop="value"></el-table-column>
</el-table>
<p>标准化处理与功效值计算</p>
<p>计算公式‌(基于多目标规划模型)‌:</p>
<img src="../../assets/images/image.png" alt="" />
<p>请根据公式计算该款商品各指标功效值:</p>
<el-table
:data="efficacyResults"
border
style="width: 40%; margin-top: 10px"
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column prop="indicator" label="指标" align="center"></el-table-column>
<el-table-column label="功效值" align="center" prop="efficacyValue">
<template #default="scope">
<el-input v-model="scope.row.efficacyValue" placeholder=""></el-input>
</template>
</el-table-column>
</el-table>
<p>权重分配与综合得分计算:</p>
<el-table
:data="data"
border
style="width: 40%; margin-top: 10px"
:header-cell-style="{
color: '#fff',
fontSize: '14px',
backgroundColor: '#6A7DE9!important',
}"
>
<el-table-column prop="indicator" label="指标" align="center"></el-table-column>
<el-table-column prop="currentWeight" label="权重设置" align="center">
<template #default="scope">
<el-input v-model="scope.row.currentWeight" placeholder=""></el-input>
</template>
</el-table-column>
<el-table-column prop="recommendedRange" label="建议权重" align="center"></el-table-column>
<el-table-column label="功效得分" align="center" prop="efficacyScore">
<template #default="scope">
<el-input v-model="scope.row.efficacyScore" placeholder=""></el-input>
</template>
</el-table-column>
</el-table>
<div style="display: flex; gap: 30px; margin-top: 10px">
<div class="online">
<span style="width: 15vw">该商品综合表现评分为:</span>
<el-input v-model="form.totalScore" placeholder=""></el-input>
</div>
<div class="online">
<span>商品评级为:</span>
<el-select placeholder="请选择" class="ml10" v-model="form.rating">
<el-option value="A" label="A级"></el-option>
<el-option value="B" label="B级"></el-option>
<el-option value="C" label="C级"></el-option>
</el-select>
</div>
</div>
<p>
4. 应用策略升级‌
<br />
流量分配规则‌:‌
<br />
A级商品需同时满足:用户评分≥4.5分 ‌且‌ 退货率≤5%(避免高评分但高退货商品)‌‌
<br />
C级商品触发整改条件:退货率连续3个月≥8% ‌或‌ 用户评分≤4.0分(参考司法判例阈值)‌‌
<br />
动态调整机制‌:‌
<br />
用户评分阈值‌:每半年根据平台TOP 10%商品均值校准(如从4.8分提升至4.9分)‌‌
<br />
退货率干预‌:对B级商品(退货率4-5%)启动AI退货原因分析,针对性优化‌‌
<br />
‌
<br />
5. 配套工具与风控措施‌‌
<br />
数据治理‌:‌
<br />
用户评分数据清洗:剔除刷单评价(通过行为模型识别异常账号)‌‌
<br />
退货率分层统计:区分质量问题退货(计入商品指标)与物流破损退货(计入服务指标)‌‌
<br />
风险预警‌:‌
<br />
用户评分波动>0.3分/周时触发人工复核‌‌
<br />
退货率同比上升50%自动冻结商品上架‌‌
<br />
</p>
<div class="taskfooter">
<el-button @click="submitTask">提交任务</el-button>
<el-button @click="resetTask">重新实训</el-button>
</div>
</div>
<TrainingLegacyActions />
<TrainingAiSidebar />
4 months ago
</div>
</template>
<script setup>
import TrainingLegacyActions from "@/views/components/TrainingLegacyActions.vue";
import TrainingAiSidebar from "@/views/components/TrainingAiSidebar.vue";
import TrainingTaskToolbar from "@/views/components/TrainingTaskToolbar.vue";
import TrainingIntro from '@/views/components/TrainingIntro.vue';
4 months ago
import useUserStore from "@/store/modules/user";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
import popModel from "@/views/components/popModal.vue";
import * as analysisAPI from "@/api/market-demand-mining.js";
const dialogVisible = ref(false);
const form = ref({
rating: "",
totalScore: "84.3",
});
const metrics = [
{
name: "商品合格率",
satisfactoryValue: "98%",
unacceptableValue: "95%",
dataSource: "行业质检标准",
},
{
name: "订单响应时长",
satisfactoryValue: "2小时",
unacceptableValue: "4小时",
dataSource: "历史运营数据",
},
{
name: "用户评分",
satisfactoryValue: "4.8分",
unacceptableValue: "4.0分",
dataSource: "平台口碑数据",
},
{
name: "退货率",
satisfactoryValue: "≤3%",
unacceptableValue: "≥8%",
dataSource: "售后运营报告",
},
];
const performanceData = [
{ indicator: "商品采购合格率", value: "96.5%" },
{ indicator: "订单响应平均时长", value: "2.5 小时" },
{ indicator: "用户评分", value: "4.6 分" },
{ indicator: "退货率", value: "5%" },
];
const efficacyResults = ref([
{
indicator: "商品采购合格率",
efficacyValue: null,
calculation: "(96.5-95)/(98-95)×40+60 = 80",
},
{
indicator: "订单响应平均时长",
efficacyValue: null,
calculation: "(4-2.5)/(4-2)×40+60 = 90",
},
{
indicator: "用户评分",
efficacyValue: null,
calculation: "(4.6-4.0)/(4.8-4.0)×40+60 = 90",
},
{
indicator: "退货率",
efficacyValue: null,
calculation: "(8-5)/(8-3)×40+60 = 84",
},
]);
const data = ref([
{
id: "quality",
indicator: "商品采购合格率",
currentWeight: null,
recommendedRange: "30%—60%", // 建议权重范围
efficacyScore: null, // 功效得分
},
{
id: "response",
indicator: "订单响应平均时长",
currentWeight: null,
recommendedRange: "5%-15%",
efficacyScore: null,
},
{
id: "rating",
indicator: "用户评分",
currentWeight: null,
recommendedRange: "20%-30%",
efficacyScore: null,
},
{
id: "return",
indicator: "退货率",
currentWeight: null,
recommendedRange: "15%-25%",
efficacyScore: null,
},
]);
const mpkey = {
qualifiedRate: "商品采购合格率",
responseTime: "订单响应平均时长",
userRating: "用户评分",
returnRate: "退货率",
};
const mpvalue = {
qrScore: "商品采购合格率得分",
rtScore: "订单响应平均时长得分",
urScore: "用户评分得分",
rrScore: "退货率得分",
qrWeight: "商品采购合格率权重",
rtWeight: "订单响应平均时长权重",
urWeight: "用户评分权重",
rrWeight: "退货率权重",
};
// 工具函数:把百分号字符串转为小数
function parsePercentage(str) {
if (typeof str === "string" && str.includes("%")) {
return parseFloat(str.replace("%", "")) / 100;
}
return parseFloat(str);
}
const submitTask = () => {
if (efficacyResults.value.some((item) => !item.efficacyValue)) {
proxy.$modal.msgWarning("请填写所有指标的功效得分");
return;
}
if (data.value.some((item) => !item.efficacyScore || !item.currentWeight)) {
proxy.$modal.msgWarning("请填写所有权重分配与综合得分");
return;
}
// 判断form是否为空
if (!form.value.rating || !form.value.totalScore) {
proxy.$modal.msgWarning("请填写所有评级与综合得分");
return;
}
const efficacyValueMap = {};
Object.entries(mpkey).forEach(([backendKey, indicatorLabel]) => {
const match = efficacyResults.value.find((item) => item.indicator === indicatorLabel);
if (match) {
efficacyValueMap[backendKey] = match.efficacyValue;
}
});
// 反转 mpkey,得到从 indicator 到前缀 key 的映射
const indicatorPrefixMap = Object.entries(mpkey).reduce((acc, [prefix, name]) => {
acc[name + "率"] = prefix; // 补上 “率”
acc[name] = prefix;
return acc;
}, {});
// 对应 prefix 映射到 mpvalue 的实际字段前缀
const prefixToMpvalueKey = {
qualifiedRate: "qr",
responseTime: "rt",
userRating: "ur",
returnRate: "rr",
};
// 最终结果
const mappedData = {};
data.value.forEach((item) => {
const prefixKey = indicatorPrefixMap[item.indicator]; // 例如 "qualifiedRate"
const mpPrefix = prefixToMpvalueKey[prefixKey]; // 例如 "qr"
if (mpPrefix) {
mappedData[`${mpPrefix}Weight`] = parsePercentage(item.currentWeight);
mappedData[`${mpPrefix}Score`] = item.efficacyScore;
}
});
let params = {
...mappedData,
...efficacyValueMap,
...form.value,
userId: userStore.userInfo.userId,
};
analysisAPI.productPerformanceAnalysisSubmit(params).then((res) => {
proxy.$modal.msgSuccess("提交成功");
});
};
// 重新实训
const resetTask = () => {
analysisAPI.productPerformanceAnalysisReTrain({ userId: userStore.userInfo.userId }).then((res) => {
proxy.$modal.msgSuccess("重新实训成功");
efficacyResults.value = efficacyResults.value.map((item) => ({
...item,
efficacyValue: null,
}));
data.value = data.value.map((item) => ({
...item,
currentWeight: null,
efficacyScore: null,
}));
form.value = {
rating: null,
totalScore: null,
};
});
};
//回显
const indicatorMap = {
商品采购合格率: { scoreKey: "qrScore", weightKey: "qrWeight" },
订单响应平均时长: { scoreKey: "rtScore", weightKey: "rtWeight" },
用户评分: { scoreKey: "urScore", weightKey: "urWeight" },
退货率: { scoreKey: "rrScore", weightKey: "rrWeight" },
};
const getTask = () => {
analysisAPI.productPerformanceAnalysisEcho({ userId: userStore.userInfo.userId }).then((res) => {
Object.entries(mpkey).forEach(([indicator, keys]) => {
let item = efficacyResults.value.find((i) => i.indicator === keys);
if (item) {
item.efficacyValue = res.data[indicator];
}
});
data.value.forEach((item) => {
const keys = indicatorMap[item.indicator];
if (!keys) return;
if (res.data[keys.scoreKey] !== undefined) {
item.efficacyScore = res.data[keys.scoreKey];
}
if (res.data[keys.weightKey] !== undefined) {
item.currentWeight = (res.data[keys.weightKey] * 100).toFixed(0) + "%";
}
});
form.value = {
rating: res.data.rating,
totalScore: res.data.totalScore,
};
});
};
onMounted(() => {
getTask();
});
</script>
<style lang='scss' scoped>
.index {
background: #ffffffff;
}
</style>