diff --git a/client/src/pages/StoreDetailPage.tsx b/client/src/pages/StoreDetailPage.tsx index 6839366..0b8610a 100644 --- a/client/src/pages/StoreDetailPage.tsx +++ b/client/src/pages/StoreDetailPage.tsx @@ -87,6 +87,25 @@ export function StoreDetailPage() { if (!sd) return
加载中...
const sc = sd.scorecard + const action = sd.action + const risk = sd.risk + + const riskDesc: Record = { + '绿色': { color: 'text-green-600 bg-green-50 border-green-200', desc: '各项指标健康,经营状态良好,维持现有运营策略即可。' }, + '黄色': { color: 'text-yellow-600 bg-yellow-50 border-yellow-200', desc: '存在单项指标偏差,需关注并针对性改善,避免风险升级。' }, + '红色': { color: 'text-red-600 bg-red-50 border-red-200', desc: '多项指标异常,经营风险较高,需立即介入并制定整改计划。' }, + } + + const quadrantDesc: Record = { + '明星门店': '高营收高毛利,是公司的核心利润来源。应总结其成功经验并推广至其他门店。', + '现金牛门店': '高营收但毛利偏低,通过成本优化有较大利润提升空间。', + '潜力门店': '营收偏低但毛利较好,具备增长潜力,需提升客流和营收规模。', + '问题门店': '营收和毛利均偏低,需全面诊断并考虑调整经营策略或选址。', + } + + const riskInfo = risk?.risk_level ? riskDesc[risk.risk_level] : null + const quadrant = action?.management_quadrant || '' + const quadrantInfo = quadrantDesc[quadrant] return (
@@ -96,8 +115,8 @@ export function StoreDetailPage() {

{sc.store_name}

- {sd.risk && } - {sd.benchmark && {sd.benchmark.management_quadrant}} + {risk?.risk_level && } + {quadrant && {quadrant}}
{/* 核心指标 */} @@ -110,6 +129,39 @@ export function StoreDetailPage() {
+ {/* 风险与经营状态说明 */} +
+ {riskInfo && ( +
+
+ 风险等级:{risk.risk_level} + {risk.primary_issue && — {risk.primary_issue}} +
+

{riskInfo.desc}

+
+ )} + {quadrantInfo && ( +
+
+ 经营象限:{quadrant} + {action?.scale_tier && — {action.scale_tier}} +
+

{quadrantInfo}

+
+ )} +
+ + {/* 行动建议 */} + {action?.action_priority && ( +
+
+ 行动优先级:{action.action_priority} + {action.problem_combination && 问题:{action.problem_combination}} + {action.business_type && {action.business_type}} +
+
+ )} + {/* Tab bar */}
{TABS.map(t => ( diff --git a/server/src/routes/data.ts b/server/src/routes/data.ts index 975698a..b5affe2 100644 --- a/server/src/routes/data.ts +++ b/server/src/routes/data.ts @@ -108,13 +108,12 @@ router.get('/stores/quadrant', async (req: AuthRequest, res) => { router.get('/stores/:code', async (req: AuthRequest, res) => { try { const code = req.params.code - const [scorecard, risk, platform, benchmark, action, execution] = await Promise.all([ + const [scorecard, risk, platform, benchmark, action] = await Promise.all([ query(`SELECT * FROM analytics.v_store_scorecard WHERE store_code = $1`, [code]), query(`SELECT * FROM analytics.mv_store_risk_rating WHERE store_code = $1`, [code]), query(`SELECT * FROM analytics.v_store_platform_economics WHERE store_code = $1`, [code]), - query(`SELECT * FROM analytics.v_store_benchmark WHERE store_code = $1`, [code]), - query(`SELECT * FROM analytics.v_store_action_list WHERE store_code = $1`, [code]), - query(`SELECT * FROM analytics.v_store_execution_priority WHERE store_code = $1`, [code]), + query(`SELECT * FROM analytics.v_store_benchmark_composite WHERE store_code = $1`, [code]), + query(`SELECT * FROM analytics.v_store_action_priority_deep_april WHERE store_code = $1`, [code]), ]) if (scorecard.rows.length === 0) { @@ -127,7 +126,6 @@ router.get('/stores/:code', async (req: AuthRequest, res) => { platform: platform.rows[0], benchmark: benchmark.rows[0], action: action.rows[0], - execution: execution.rows[0], }) } catch (err: any) { sendError(res, err.message)