fix: 门店成本分析Tab - 用v_inventory_cost_classified_april替代不存在的v_store_category_cost_benchmark_april
This commit is contained in:
@@ -261,10 +261,10 @@ export function StoreDetailPage() {
|
||||
<DataTable
|
||||
columns={[
|
||||
{ key: 'category_name', label: '原料分类' },
|
||||
{ key: 'theoretical_cost_rate_pct', label: '理论成本率', align: 'right', render: (r) => formatPercent(r.theoretical_cost_rate_pct) },
|
||||
{ key: 'actual_cost_rate_pct', label: '实际成本率', align: 'right', render: (r) => formatPercent(r.actual_cost_rate_pct) },
|
||||
{ key: 'variance_pct', label: '差异', align: 'right', render: (r) => <span className={Number(r.variance_pct) > 20 ? 'text-red-600' : 'text-green-600'}>{Number(r.variance_pct).toFixed(1)}%</span> },
|
||||
{ key: 'benchmark_rate_pct', label: '同类基准', align: 'right', render: (r) => formatPercent(r.benchmark_rate_pct) },
|
||||
{ key: 'consumption_amount', label: '消耗金额', align: 'right', render: (r) => formatCurrency(r.consumption_amount) },
|
||||
{ key: 'actual_cost_rate_pct', label: '占比', align: 'right', render: (r) => formatPercent(r.actual_cost_rate_pct) },
|
||||
{ key: 'benchmark_rate_pct', label: '公司基准', align: 'right', render: (r) => formatPercent(r.benchmark_rate_pct) },
|
||||
{ key: 'variance_pct', label: '差异', align: 'right', render: (r) => <span className={Number(r.variance_pct) > 2 ? 'text-red-600' : 'text-green-600'}>{Number(r.variance_pct).toFixed(1)}%</span> },
|
||||
]}
|
||||
data={cost.categories}
|
||||
/>
|
||||
|
||||
@@ -383,7 +383,30 @@ router.get('/stores/:code/cost', async (req: AuthRequest, res) => {
|
||||
try {
|
||||
const [costResult, catResult] = await Promise.all([
|
||||
query(`SELECT * FROM analytics.v_store_theoretical_actual_cost_april WHERE store_code = $1`, [req.params.code]),
|
||||
query(`SELECT * FROM analytics.v_store_category_cost_benchmark_april WHERE store_code = $1`, [req.params.code]),
|
||||
query(`
|
||||
WITH store_cat AS (
|
||||
SELECT finance_category AS category_name,
|
||||
round(sum(consumption_amount)::numeric, 2) AS consumption_amount,
|
||||
round(sum(consumption_amount)::numeric / nullif(sum(sum(consumption_amount)) OVER (), 0) * 100, 1) AS actual_cost_rate_pct
|
||||
FROM analytics.v_inventory_cost_classified_april
|
||||
WHERE sales_store_code = $1 AND finance_category IS NOT NULL
|
||||
GROUP BY finance_category
|
||||
ORDER BY sum(consumption_amount) DESC
|
||||
),
|
||||
company_cat AS (
|
||||
SELECT finance_category,
|
||||
round(sum(consumption_amount)::numeric / nullif(sum(sum(consumption_amount)) OVER (), 0) * 100, 1) AS benchmark_rate_pct
|
||||
FROM analytics.v_inventory_cost_classified_april
|
||||
WHERE finance_category IS NOT NULL
|
||||
GROUP BY finance_category
|
||||
)
|
||||
SELECT s.category_name, s.consumption_amount, s.actual_cost_rate_pct,
|
||||
COALESCE(c.benchmark_rate_pct, 0) AS benchmark_rate_pct,
|
||||
round(s.actual_cost_rate_pct - COALESCE(c.benchmark_rate_pct, 0), 1) AS variance_pct
|
||||
FROM store_cat s
|
||||
LEFT JOIN company_cat c ON s.category_name = c.finance_category
|
||||
ORDER BY s.consumption_amount DESC
|
||||
`, [req.params.code]),
|
||||
])
|
||||
sendSuccess(res, { cost: costResult.rows[0], categories: catResult.rows })
|
||||
} catch (err: any) { sendError(res, err.message) }
|
||||
|
||||
Reference in New Issue
Block a user