|
|
|
|
@ -154,10 +154,10 @@
|
|
|
|
|
<p class="section-eyebrow">Step 03</p>
|
|
|
|
|
<h3>{{ getStepName(3) }}</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<span class="step-chip">产品1 / 产品2 / 产品3</span>
|
|
|
|
|
<span class="step-chip">三层次对照分析</span>
|
|
|
|
|
</div>
|
|
|
|
|
<p class="step-desc">
|
|
|
|
|
根据查找的产品,从核心层、有形层、延伸层开展三层次分析,对比不同产品如何创造用户价值。
|
|
|
|
|
基于上一步采集的真实数据,运用“三层次理论”进行深度分析,参考示例填写下表;每层至少填写 2 条要点并按换行分条。
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<div class="training-table-wrap">
|
|
|
|
|
@ -165,21 +165,22 @@
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>分析维度</th>
|
|
|
|
|
<th>内容要求</th>
|
|
|
|
|
<th>实例:AI学习机</th>
|
|
|
|
|
<th>产品1</th>
|
|
|
|
|
<th>产品2</th>
|
|
|
|
|
<th>产品3</th>
|
|
|
|
|
<th>{{ step2Form.productName || '所选产品' }}分析</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr v-for="row in step3Rows" :key="row.dimension">
|
|
|
|
|
<td class="dimension-cell">{{ row.dimension }}</td>
|
|
|
|
|
<td class="requirement-cell">{{ row.requirement }}</td>
|
|
|
|
|
<td class="example-cell">{{ row.example }}</td>
|
|
|
|
|
<td><textarea v-model="row.product1" class="cell-textarea" /></td>
|
|
|
|
|
<td><textarea v-model="row.product2" class="cell-textarea" /></td>
|
|
|
|
|
<td><textarea v-model="row.product3" class="cell-textarea" /></td>
|
|
|
|
|
<td class="dimension-cell"><strong>{{ row.dimension }}</strong><span>{{ row.definition }}</span></td>
|
|
|
|
|
<td class="example-cell">
|
|
|
|
|
<ol class="reference-points">
|
|
|
|
|
<li v-for="point in row.referencePoints" :key="point">{{ point }}</li>
|
|
|
|
|
</ol>
|
|
|
|
|
</td>
|
|
|
|
|
<td class="analysis-input-cell">
|
|
|
|
|
<textarea v-model="row.analysis" class="cell-textarea" rows="7" placeholder="每行填写一条分析要点" />
|
|
|
|
|
<p class="analysis-count" :class="{ 'is-ready': countStepThreePoints(row.analysis) >= 2 }">已填写 {{ countStepThreePoints(row.analysis) }} / 至少 2 条</p>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
@ -269,7 +270,7 @@ import {
|
|
|
|
|
TrendCharts,
|
|
|
|
|
} from "@element-plus/icons-vue";
|
|
|
|
|
import { getTrainingTaskByKey } from "@/api/trainingTask";
|
|
|
|
|
import { checkNewProductSurveyStepOne, checkNewProductSurveyStepTwo, getStudentTrainingAnswer, saveStudentTrainingAnswer, uploadStudentTrainingFile } from "@/api/studentTrainingAnswer";
|
|
|
|
|
import { checkNewProductSurveyStepOne, checkNewProductSurveyStepThree, checkNewProductSurveyStepTwo, getStudentTrainingAnswer, saveStudentTrainingAnswer, uploadStudentTrainingFile } from "@/api/studentTrainingAnswer";
|
|
|
|
|
import useUserStore from "@/store/modules/user";
|
|
|
|
|
import { extractTrainingStepNames } from "@/views/training/taskKeyMap";
|
|
|
|
|
import TrainingAiSidebar from "@/views/components/TrainingAiSidebar.vue";
|
|
|
|
|
@ -357,33 +358,14 @@ const STEP_ONE_SELLING_POINTS = [
|
|
|
|
|
|
|
|
|
|
const createStep2Form = () => ({ platform: "", scene: "", customScene: "", keyword: "", productName: "", images: [] });
|
|
|
|
|
|
|
|
|
|
const createStep3Rows = () => [
|
|
|
|
|
{
|
|
|
|
|
dimension: "核心层",
|
|
|
|
|
requirement: "说明产品解决的核心痛点、用户需求和核心利益。",
|
|
|
|
|
example: "解决学生学习效率低、家长辅导时间不足等痛点,提供个性化学习支持。",
|
|
|
|
|
product1: "",
|
|
|
|
|
product2: "",
|
|
|
|
|
product3: "",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
dimension: "有形层",
|
|
|
|
|
requirement: "记录功能、设计、品牌、参数、包装、价格等可见要素。",
|
|
|
|
|
example: "护眼屏、AI语音互动、拍照搜题、错题本、课程资源、学习报告。",
|
|
|
|
|
product1: "",
|
|
|
|
|
product2: "",
|
|
|
|
|
product3: "",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
dimension: "延伸层",
|
|
|
|
|
requirement: "分析售后、会员、内容更新、物流、生态兼容和数据安全等附加服务。",
|
|
|
|
|
example: "课程持续更新、家长端管理、云端错题同步、售后保修、会员内容权益。",
|
|
|
|
|
product1: "",
|
|
|
|
|
product2: "",
|
|
|
|
|
product3: "",
|
|
|
|
|
},
|
|
|
|
|
const STEP_THREE_REFERENCE_ROWS = [
|
|
|
|
|
{ dimension: "核心层", definition: "AI技术解决的核心需求/功能", referencePoints: ["大模型作业批改", "自适应学习路径规划"] },
|
|
|
|
|
{ dimension: "有形层", definition: "外观/材质/参数/价格策略", referencePoints: ["护眼屏+铝合金机身", "搭载NPU芯片", "全平台统一定价2999元,某网红直播间专属价2699元"] },
|
|
|
|
|
{ dimension: "延伸层", definition: "软件升级/专属服务/社群运营", referencePoints: ["终身免费题库更新", "VIP学科规划师1对1", "家长互助社群及资料共享微信群"] },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const createStep3Rows = () => STEP_THREE_REFERENCE_ROWS.map((row) => ({ ...row, analysis: "" }));
|
|
|
|
|
|
|
|
|
|
const createStep4Form = () => ({
|
|
|
|
|
coreValue: "",
|
|
|
|
|
tangibleValue: "",
|
|
|
|
|
@ -406,7 +388,7 @@ const currentStudyTip = computed(() => {
|
|
|
|
|
const tips = {
|
|
|
|
|
1: "当前步骤建议:先从案例或电商详情页中拆出核心层、有形层、延伸层,不要把功能和用户利益混在一起。",
|
|
|
|
|
2: "当前步骤建议:选择一个主流电商平台与真实 AI 产品,用“核心词 + 属性词 + 场景词”搜索并保留主图、详情页截图。",
|
|
|
|
|
3: "当前步骤建议:同一维度横向比较 3 个产品,重点找出 AI 技术在哪一层创造了差异化。",
|
|
|
|
|
3: "当前步骤建议:将上一步选定产品的卖点按核心层、有形层、延伸层拆分,每层至少记录两条可核对的分析要点。",
|
|
|
|
|
4: "当前步骤建议:把前面三步的发现收束为产品开发启发,说明哪些价值值得继续强化。",
|
|
|
|
|
};
|
|
|
|
|
return tips[currentStep.value];
|
|
|
|
|
@ -623,7 +605,19 @@ function applyStep3Answer(value) {
|
|
|
|
|
const parsed = safeParse(value);
|
|
|
|
|
const rows = Array.isArray(parsed) ? parsed : parsed?.step3Rows || parsed?.rows || parsed?.layerRows;
|
|
|
|
|
if (!Array.isArray(rows) || !rows.length) return false;
|
|
|
|
|
step3Rows.value = normalizeRows(rows, createStep3Rows(), "dimension");
|
|
|
|
|
const savedByDimension = rows.reduce((result, row) => {
|
|
|
|
|
if (row?.dimension) result[row.dimension] = row;
|
|
|
|
|
return result;
|
|
|
|
|
}, {});
|
|
|
|
|
step3Rows.value = createStep3Rows().map((row, index) => {
|
|
|
|
|
const saved = savedByDimension[row.dimension] || rows[index] || {};
|
|
|
|
|
const points = Array.isArray(saved.points) ? saved.points : [];
|
|
|
|
|
const legacyValue = [saved.analysis, saved.product1, saved.product2, saved.product3].find((item) => String(item || "").trim());
|
|
|
|
|
return {
|
|
|
|
|
...row,
|
|
|
|
|
analysis: points.length ? points.map((item) => String(item || "").trim()).filter(Boolean).join("\n") : String(legacyValue || ""),
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -667,6 +661,26 @@ function normalizeRows(rows, fallback, matchKey = "") {
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function splitStepThreePoints(value) {
|
|
|
|
|
return String(value || "")
|
|
|
|
|
.split(/\r?\n/)
|
|
|
|
|
.map((item) => item.trim())
|
|
|
|
|
.filter(Boolean);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function countStepThreePoints(value) {
|
|
|
|
|
return splitStepThreePoints(value).length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildStepThreeValidationPayload() {
|
|
|
|
|
return {
|
|
|
|
|
rows: step3Rows.value.map((row) => ({
|
|
|
|
|
dimension: row.dimension,
|
|
|
|
|
points: splitStepThreePoints(row.analysis),
|
|
|
|
|
})),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildAnswerPayload(status) {
|
|
|
|
|
const saveAction = status === "SUBMITTED" ? "SUBMIT" : status === "RESET" ? "RESET" : "SAVE";
|
|
|
|
|
return {
|
|
|
|
|
@ -674,7 +688,7 @@ function buildAnswerPayload(status) {
|
|
|
|
|
currentStep: currentStep.value,
|
|
|
|
|
step1Answer: JSON.stringify({ classifications: classifications.value, checkResult: checkResult.value }),
|
|
|
|
|
step2Answer: JSON.stringify(step2Form.value),
|
|
|
|
|
step3Answer: JSON.stringify(step3Rows.value),
|
|
|
|
|
step3Answer: JSON.stringify(buildStepThreeValidationPayload()),
|
|
|
|
|
step4Answer: JSON.stringify(step4Form.value),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
@ -714,6 +728,20 @@ async function nextStep() {
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (currentStep.value === 3) {
|
|
|
|
|
checking.value = true;
|
|
|
|
|
try {
|
|
|
|
|
await checkNewProductSurveyStepThree(buildStepThreeValidationPayload());
|
|
|
|
|
await saveAnswer("IN_PROGRESS", true);
|
|
|
|
|
proxy?.$modal?.msgSuccess("第三步分析已校验并保存");
|
|
|
|
|
advanceStep();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
proxy?.$modal?.msgWarning(error?.message || "请确保每个层次至少填写 2 条分析要点");
|
|
|
|
|
} finally {
|
|
|
|
|
checking.value = false;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (currentStep.value !== 1) {
|
|
|
|
|
advanceStep();
|
|
|
|
|
return;
|
|
|
|
|
@ -1513,9 +1541,26 @@ function exportOutcome() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dimension-cell {
|
|
|
|
|
min-width: 170px;
|
|
|
|
|
color: #eafaff;
|
|
|
|
|
font-weight: 900;
|
|
|
|
|
text-align: center;
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
|
|
|
|
strong,
|
|
|
|
|
span {
|
|
|
|
|
display: block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strong {
|
|
|
|
|
margin-bottom: 7px;
|
|
|
|
|
font-weight: 900;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
color: #9fc6da;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
line-height: 1.55;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.requirement-cell,
|
|
|
|
|
@ -1529,6 +1574,28 @@ function exportOutcome() {
|
|
|
|
|
color: #f5d99d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.reference-points {
|
|
|
|
|
display: grid;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding-left: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.analysis-input-cell {
|
|
|
|
|
min-width: 280px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.analysis-count {
|
|
|
|
|
margin: 8px 2px 0;
|
|
|
|
|
color: #ffb1b1;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
|
|
|
|
&.is-ready {
|
|
|
|
|
color: #86e7bd;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.example-hint {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|