diff --git a/src/api/studentTrainingAnswer.js b/src/api/studentTrainingAnswer.js index 161310f..4be51d4 100644 --- a/src/api/studentTrainingAnswer.js +++ b/src/api/studentTrainingAnswer.js @@ -95,6 +95,56 @@ export function checkNewProductSurveyStepOne(items) { }); } +export function checkMarketOpportunitySelectionStepOne(items) { + const expected = { + "search-count": "市场规模", "demand-supply-ratio": "竞争强度", "transaction-amount": "市场规模", "transaction-growth": "市场潜力", + "category-transaction-growth": "市场潜力", "online-products": "竞争强度", "online-merchants": "竞争强度", "organic-traffic-ratio": "运营难度", + }; + if (isStudentDemo()) { + const list = Array.isArray(items) ? items : []; + const incorrect = list.find((item) => expected[item?.id] !== item?.category); + if (list.length !== Object.keys(expected).length || incorrect) return Promise.reject(new Error("指标分类有误,请根据提示重新选择")); + return Promise.resolve({ code: 200, data: { correctCount: Object.keys(expected).length, totalCount: Object.keys(expected).length, allCorrect: true, message: "校验通过" } }); + } + return request({ url: "/api/student-training-answers/market-opportunity-selection/step-1/check", method: "post", data: { items }, headers: { repeatSubmit: false } }); +} + +export function checkMarketOpportunitySelectionStepTwo(payload) { + const weights = Array.isArray(payload?.weights) ? payload.weights : []; + const expectedIds = ["search-count", "transaction-amount", "transaction-growth", "category-transaction-growth", "demand-supply-ratio", "online-products", "online-merchants", "organic-traffic-ratio"]; + if (isStudentDemo()) { + const ids = new Set(weights.map((item) => item?.id)); + const total = weights.reduce((sum, item) => sum + Number(item?.weight || 0), 0); + if (weights.length !== expectedIds.length || expectedIds.some((id) => !ids.has(id)) || weights.some((item) => !Number.isInteger(Number(item?.weight)) || Number(item.weight) < 1 || Number(item.weight) > 100) || total !== 100) { + return Promise.reject(new Error("二级指标权重需为 1 至 100 的整数,且合计必须为 100%")); + } + return Promise.resolve({ code: 200, data: { valid: true, message: "校验通过" } }); + } + return request({ url: "/api/student-training-answers/market-opportunity-selection/step-2/validate", method: "post", data: { weights }, headers: { repeatSubmit: false } }); +} + +export function checkMarketOpportunitySelectionStepThree(payload) { + const scores = Array.isArray(payload?.scores) ? payload.scores : []; + const expectedIds = ["smart-fitness-mirror", "smart-bathroom-mirror", "smart-beauty-mirror"]; + if (isStudentDemo()) { + const ids = new Set(scores.map((item) => item?.id)); + if (scores.length !== expectedIds.length || expectedIds.some((id) => !ids.has(id)) || scores.some((item) => !Number.isFinite(Number(item?.score)) || Number(item.score) < 0 || Number(item.score) > 100)) { + return Promise.reject(new Error("请为三类产品填写 0 至 100 分的综合得分")); + } + return Promise.resolve({ code: 200, data: { valid: true, message: "校验通过" } }); + } + return request({ url: "/api/student-training-answers/market-opportunity-selection/step-3/validate", method: "post", data: { scores }, headers: { repeatSubmit: false } }); +} + +export function checkMarketOpportunitySelectionStepFour(payload) { + const visualizationUrl = String(payload?.visualizationUrl || "").trim(); + if (isStudentDemo()) { + if (!visualizationUrl) return Promise.reject(new Error("请上传数据可视化结果图")); + return Promise.resolve({ code: 200, data: { valid: true, message: "校验通过" } }); + } + return request({ url: "/api/student-training-answers/market-opportunity-selection/step-4/validate", method: "post", data: { visualizationUrl }, headers: { repeatSubmit: false } }); +} + function validateNewProductSurveyStepTwoDemo(form) { const value = form || {}; const images = Array.isArray(value.images) ? value.images : []; diff --git a/src/router/index.js b/src/router/index.js index e0d49b8..1a2dbf7 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -286,7 +286,7 @@ export const dynamicRoutes = [ // 产品定位 { path: "index", - component: () => import("@/views/product/index.vue"), + component: () => import("@/views/product/market-opportunity-selection.vue"), name: "product", meta: { title: "市场机会识别与选品", icon: "产品规划", affix: true, pageKey: "market-opportunity-selection" }, }, diff --git a/src/views/product/market-opportunity-selection.vue b/src/views/product/market-opportunity-selection.vue new file mode 100644 index 0000000..fb80dcb --- /dev/null +++ b/src/views/product/market-opportunity-selection.vue @@ -0,0 +1,108 @@ + + + + +