Merge branch 'codex/target-user-profile-step1'

# Conflicts:
#	src/api/studentTrainingAnswer.js
dev-QQq
chenyuan 2 weeks ago
commit 4d9d7f9421

@ -1759,3 +1759,57 @@ export function checkIndustryDemandAnalysisStepOne(payload) { const value = payl
export function checkIndustryDemandAnalysisStepTwo(payload) { const value = payload || {}; if (isStudentDemo()) { try { return Promise.resolve({ code: 200, data: checkIndustryDemandDemo(value, ["political", "economic", "social", "technology"]) }); } catch (error) { return Promise.reject(error); } } return request({ url: "/api/student-training-answers/industry-demand-analysis/step-2/validate", method: "post", data: value, headers: { repeatSubmit: false } }); }
export function checkIndustryDemandAnalysisStepThree(payload) { const rows = Array.isArray(payload?.rows) ? payload.rows : []; if (isStudentDemo()) { const valid = rows.length === 4 && ["political", "economic", "social", "technology"].every((dimension) => rows.some((row) => row?.dimension === dimension && String(row?.opportunities || "").trim() && String(row?.challenges || "").trim() && String(row?.strategies || "").trim())); return Promise.resolve({ code: 200, data: { valid, message: valid ? "校验通过" : "请完成四个维度的机会、挑战和策略" } }); } return request({ url: "/api/student-training-answers/industry-demand-analysis/step-3/validate", method: "post", data: { rows }, headers: { repeatSubmit: false } }); }
export function checkIndustryDemandAnalysisStepFour(payload) { const value = payload || {}; if (isStudentDemo()) { const valid = ["高度友好", "较为友好", "中性", "存在风险", "风险较高"].includes(String(value.overallAssessment || "").trim()) && ["建议进入", "谨慎进入", "建议暂缓"].includes(String(value.marketDecision || "").trim()) && String(value.decisionReason || "").trim(); return Promise.resolve({ code: 200, data: { valid, message: valid ? "校验通过" : "请完整填写总体评估、市场进入结论和理由" } }); } return request({ url: "/api/student-training-answers/industry-demand-analysis/step-4/validate", method: "post", data: value, headers: { repeatSubmit: false } }); }
export function checkTargetUserProfileStepOne(payload) {
const value = payload || {};
if (isStudentDemo()) {
const fileName = String(value.excelName || "").trim();
const fileUrl = String(value.excelUrl || "").trim();
if (!fileUrl || !/\.xlsx?$/i.test(fileName)) return Promise.reject(new Error("请上传 RFM 用户分层分析结果 Excel 数据"));
if (Number(value.previewRowCount || 0) < 1 || Number(value.previewColumnCount || 0) < 1) return Promise.reject(new Error("Excel 文件需要包含可预览的表头和数据"));
return Promise.resolve({ code: 200, data: { valid: true, message: "校验通过" } });
}
return request({ url: "/api/student-training-answers/target-user-profile/step-1/validate", method: "post", data: value, headers: { repeatSubmit: false } });
}
export function checkTargetUserProfileStepTwo(payload) {
const charts = Array.isArray(payload?.charts) ? payload.charts : [];
if (isStudentDemo()) {
const expectedTypes = ["segment-share", "average-spend", "score-heatmap"];
const types = new Set(charts.map((chart) => chart?.type));
const invalid = charts.find((chart) => !String(chart?.url || "").trim() || !/\.(png|jpe?g|webp)$/i.test(String(chart?.name || "")));
if (charts.length !== expectedTypes.length || expectedTypes.some((type) => !types.has(type)) || invalid) return Promise.reject(new Error("请上传三类 RFM 分析图"));
return Promise.resolve({ code: 200, data: { valid: true, message: "校验通过" } });
}
return request({ url: "/api/student-training-answers/target-user-profile/step-2/validate", method: "post", data: { charts }, headers: { repeatSubmit: false } });
}
export function checkTargetUserProfileStepThree(payload) {
const insights = Array.isArray(payload?.insights) ? payload.insights : [];
if (isStudentDemo()) {
const expected = ["高价值用户占比", "用户活跃度", "消费能力", "用户忠诚度", "重点客户群特征"];
const dimensions = new Set(insights.map((item) => item?.dimension));
if (insights.length !== expected.length || expected.some((item) => !dimensions.has(item)) || insights.some((item) => !String(item?.analysis || "").trim())) return Promise.reject(new Error("请完成五个 RFM 用户群体特点分析维度"));
return Promise.resolve({ code: 200, data: { valid: true, message: "校验通过" } });
}
return request({ url: "/api/student-training-answers/target-user-profile/step-3/validate", method: "post", data: { insights }, headers: { repeatSubmit: false } });
}
export function checkTargetUserProfileStepFour(payload) {
const records = Array.isArray(payload?.records) ? payload.records : [];
if (isStudentDemo()) {
const expected = ["U01", "U02", "U03"];
const codes = new Set(records.map((item) => item?.code));
const fields = ["user", "basicAttributes", "tags", "behavior", "painPoints", "psychology"];
if (records.length !== expected.length || expected.some((code) => !codes.has(code)) || records.some((item) => fields.some((field) => !String(item?.[field] || "").trim()))) return Promise.reject(new Error("请完成三位重点用户的完整画像"));
return Promise.resolve({ code: 200, data: { valid: true, message: "校验通过" } });
}
return request({ url: "/api/student-training-answers/target-user-profile/step-4/validate", method: "post", data: { records }, headers: { repeatSubmit: false } });
}
export function checkTargetUserProfileStepFive(payload) {
const value = payload || {};
const segments = Array.isArray(value.segments) ? value.segments : [];
if (isStudentDemo()) {
const fields = ["market", "attractiveness", "painPoints", "behaviorCharacteristics", "productOpportunity"];
if (!segments.length || segments.length > 6 || !String(value.marketSelection || "").trim() || segments.some((item) => fields.some((field) => !String(item?.[field] || "").trim()))) return Promise.reject(new Error("请完成细分市场分析表和市场选择结论"));
return Promise.resolve({ code: 200, data: { valid: true, message: "校验通过" } });
}
return request({ url: "/api/student-training-answers/target-user-profile/step-5/validate", method: "post", data: { segments, marketSelection: String(value.marketSelection || "") }, headers: { repeatSubmit: false } });
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save