{"token":"815f2a59-6d91-457e-bd74-e9591eae796c","title":"库存案例","dashboard_str":"{\"title\":\"库存案例\",\"viewInfos\":[{\"file_name\":\"库存周转率与周转天数.xlsx\",\"file_url\":\"https://excelup.kyou.ltd/uploads/2lrac31mny36/file-35940d9b-b9fe-45.xlsx\",\"id\":20129,\"hashId\":\"ea5232b3ecfcee77e0300bb2793ebae4\"}],\"query\":\"原样输出该html,不要有任何修改:\\n\u003c!DOCTYPE html\u003e\\n\u003chtml lang=\\\"zh-CN\\\"\u003e\\n\u003chead\u003e\\n \u003cmeta charset=\\\"UTF-8\\\"\u003e\\n \u003cmeta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"\u003e\\n \u003ctitle\u003e库存与销售管理看板\u003c/title\u003e\\n \u003clink rel=\\\"stylesheet\\\" href=\\\"https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css\\\"\u003e\\n \u003clink rel=\\\"preconnect\\\" href=\\\"https://fonts.googleapis.com\\\"\u003e\\n \u003clink rel=\\\"preconnect\\\" href=\\\"https://fonts.gstatic.com\\\" crossorigin\u003e\\n \u003clink href=\\\"https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,600;0,700;1,400\u0026family=Source+Serif+4:opsz,wght@8..60,400;8..60,500;8..60,600\u0026display=swap\\\" rel=\\\"stylesheet\\\"\u003e\\n \u003cstyle\u003e\\n body {\\n background: #f5ecd7 url(\\\"data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23dfd3b3' fill-opacity='0.4'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E\\\");\\n font-family: 'Source Serif 4', 'Georgia', 'Times New Roman', serif;\\n color: #3a2c1b;\\n }\\n .title, .subtitle, .section-title, .kpi-label, .kpi-value, .tag, .select, .table, .level, .box {\\n font-family: 'Source Serif 4', 'Georgia', 'Times New Roman', serif;\\n }\\n .title { color: #2c1810; }\\n .subtitle { color: #7a6a4e; }\\n .box {\\n background: #fcf8ef;\\n border: 1px solid #d4c5a9;\\n border-radius: 2px;\\n box-shadow: 2px 2px 8px rgba(90, 70, 40, 0.1);\\n }\\n .kpi-card {\\n border-left: 4px solid #8b7355;\\n border-radius: 2px;\\n transition: all .2s;\\n background: #faf6eb;\\n }\\n .kpi-card:hover {\\n transform: translateY(-2px);\\n box-shadow: 3px 3px 12px rgba(90, 70, 40, 0.18);\\n border-left-color: #a0522d;\\n }\\n .kpi-value {\\n font-size: 1.6rem;\\n font-weight: 700;\\n line-height: 1.2;\\n font-family: 'Playfair Display', serif;\\n color: #2c1810;\\n }\\n .kpi-value.has-text-link { color: #5b4a3a !important; }\\n .kpi-value.has-text-danger { color: #8b3a3a !important; }\\n .kpi-value.has-text-info { color: #4a6b6b !important; }\\n .kpi-value.has-text-success { color: #5b7a4a !important; }\\n .kpi-value.has-text-warning-dark { color: #8b7a3a !important; }\\n .kpi-value.has-text-primary { color: #6b4a6b !important; }\\n .kpi-label {\\n font-size: .82rem;\\n color: #8b7a5e;\\n text-transform: uppercase;\\n letter-spacing: 0.5px;\\n font-weight: 500;\\n }\\n .chart-container { width: 100%; height: 360px; }\\n .chart-container-sm { height: 300px; }\\n .chart-container-lg { height: 400px; }\\n .section-title {\\n font-size: 1.05rem;\\n font-weight: 600;\\n color: #5a3a1a;\\n font-family: 'Playfair Display', serif;\\n letter-spacing: 0.3px;\\n }\\n .section-title::before {\\n content: \\\"❧ \\\";\\n color: #a0855c;\\n font-size: 1rem;\\n }\\n .tag.is-light {\\n background: #ede4d0;\\n color: #4a3a28;\\n border: 1px solid #d4c5a9;\\n border-radius: 0;\\n }\\n .tag.is-light.is-info { background: #e0d8c4; color: #3a2c1b; border-color: #b8a88a; }\\n .select select, .select.is-small select {\\n font-family: 'Source Serif 4', serif;\\n background: #faf6eb;\\n border-color: #c8b89a;\\n color: #3a2c1b;\\n border-radius: 2px;\\n }\\n .select select:focus {\\n border-color: #a0855c;\\n box-shadow: 0 0 0 2px rgba(160, 133, 92, 0.25);\\n }\\n .select:not(.is-multiple)::after {\\n border-color: #a0855c !important;\\n }\\n .table {\\n background: #fcf8ef;\\n color: #3a2c1b;\\n border: 1px solid #d4c5a9;\\n }\\n .table th {\\n color: #2c1810;\\n font-family: 'Playfair Display', serif;\\n font-weight: 600;\\n border-bottom: 2px solid #c8b89a;\\n background: #f5edd9;\\n }\\n .table td {\\n border-bottom: 1px solid #e0d4be;\\n }\\n .table tr:hover { background: #f0e8d2; }\\n .table thead th { border-bottom-color: #b8a88a; }\\n .level .select select {\\n background: #f5edd9;\\n border-color: #c8b89a;\\n }\\n code {\\n background: #ede4d0;\\n color: #4a3a28;\\n padding: 0 4px;\\n border: 1px solid #d4c5a9;\\n border-radius: 0;\\n }\\n .table-container {\\n max-height: 400px;\\n overflow-y: auto;\\n }\\n .table-container::-webkit-scrollbar { width: 5px; }\\n .table-container::-webkit-scrollbar-thumb { background: #c8b89a; border-radius: 0; }\\n .table-container::-webkit-scrollbar-track { background: #ede4d0; }\\n .table code { border: none; background: transparent; }\\n @media screen and (max-width: 768px) {\\n .chart-container { height: 280px; }\\n .kpi-value { font-size: 1.3rem; }\\n }\\n \u003c/style\u003e\\n\u003c/head\u003e\\n\u003cbody\u003e\\n \u003csection class=\\\"section py-4\\\"\u003e\\n \u003cdiv class=\\\"container\\\"\u003e\\n \u003c!-- Header --\u003e\\n \u003cdiv class=\\\"level mb-4\\\"\u003e\\n \u003cdiv class=\\\"level-left\\\"\u003e\\n \u003cdiv style=\\\"display:flex;align-items:center;gap:10px;\\\"\u003e\\n \u003cspan style=\\\"font-size:2rem;line-height:1;\\\"\u003e📋\u003c/span\u003e\\n \u003cdiv\u003e\\n \u003ch1 class=\\\"title is-4 mb-1\\\"\u003e库存与销售管理看板\u003c/h1\u003e\\n \u003cp class=\\\"subtitle is-7\\\" style=\\\"color:#9a8050!important;font-size:13px;font-weight:500;letter-spacing:0.3px;\\\"\u003e数据期间:2025年1月 ~ 2025年5月\u003c/p\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"level-right\\\"\u003e\\n \u003cdiv class=\\\"field has-addons\\\"\u003e\\n \u003cp class=\\\"control\\\"\u003e\\n \u003cspan class=\\\"select is-small\\\"\u003e\\n \u003cselect id=\\\"monthFilter\\\"\u003e\\n \u003coption value=\\\"all\\\"\u003e全部月份\u003c/option\u003e\\n \u003c/select\u003e\\n \u003c/span\u003e\\n \u003c/p\u003e\\n \u003cp class=\\\"control\\\"\u003e\\n \u003cspan class=\\\"select is-small\\\"\u003e\\n \u003cselect id=\\\"categoryFilter\\\"\u003e\\n \u003coption value=\\\"all\\\"\u003e全部品类\u003c/option\u003e\\n \u003c/select\u003e\\n \u003c/span\u003e\\n \u003c/p\u003e\\n \u003cp class=\\\"control\\\"\u003e\\n \u003cspan class=\\\"select is-small\\\"\u003e\\n \u003cselect id=\\\"promotionFilter\\\"\u003e\\n \u003coption value=\\\"all\\\"\u003e全部\u003c/option\u003e\\n \u003coption value=\\\"是\\\"\u003e促销\u003c/option\u003e\\n \u003coption value=\\\"否\\\"\u003e非促销\u003c/option\u003e\\n \u003c/select\u003e\\n \u003c/span\u003e\\n \u003c/p\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003c!-- KPI Cards --\u003e\\n \u003cdiv class=\\\"columns is-multiline is-variable is-3\\\" id=\\\"kpiRow\\\"\u003e\\n \u003cdiv class=\\\"column is-6-tablet is-3-desktop\\\"\u003e\\n \u003cdiv class=\\\"box kpi-card px-4 py-3\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e总销售收入\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value has-text-link\\\" id=\\\"kpiRevenue\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-tablet is-3-desktop\\\"\u003e\\n \u003cdiv class=\\\"box kpi-card px-4 py-3\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e总销售成本\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value has-text-danger\\\" id=\\\"kpiCogs\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-tablet is-3-desktop\\\"\u003e\\n \u003cdiv class=\\\"box kpi-card px-4 py-3\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e总出库量\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value has-text-info\\\" id=\\\"kpiOutbound\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-tablet is-3-desktop\\\"\u003e\\n \u003cdiv class=\\\"box kpi-card px-4 py-3\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e期末库存金额\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value has-text-success\\\" id=\\\"kpiEndAmount\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-tablet is-3-desktop\\\"\u003e\\n \u003cdiv class=\\\"box kpi-card px-4 py-3\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e毛利率\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value has-text-warning-dark\\\" id=\\\"kpiMargin\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-6-tablet is-3-desktop\\\"\u003e\\n \u003cdiv class=\\\"box kpi-card px-4 py-3\\\"\u003e\\n \u003cdiv class=\\\"kpi-label\\\"\u003e促销记录数\u003c/div\u003e\\n \u003cdiv class=\\\"kpi-value has-text-primary\\\" id=\\\"kpiPromo\\\"\u003e—\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003c!-- Row 1: Monthly Trend + Category Pie --\u003e\\n \u003cdiv class=\\\"columns is-multiline\\\"\u003e\\n \u003cdiv class=\\\"column is-8-desktop\\\"\u003e\\n \u003cdiv class=\\\"box\\\"\u003e\\n \u003cdiv class=\\\"section-title mb-2\\\"\u003e月度收入与成本趋势\u003c/div\u003e\\n \u003cdiv class=\\\"chart-container\\\" id=\\\"chartTrend\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-4-desktop\\\"\u003e\\n \u003cdiv class=\\\"box\\\"\u003e\\n \u003cdiv class=\\\"section-title mb-2\\\"\u003e品类收入占比\u003c/div\u003e\\n \u003cdiv class=\\\"chart-container\\\" id=\\\"chartCategoryPie\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003c!-- Row 2: Category Revenue Stacked + Promotion vs Non-promotion + Inventory Alert --\u003e\\n \u003cdiv class=\\\"columns is-multiline\\\"\u003e\\n \u003cdiv class=\\\"column is-4-desktop\\\"\u003e\\n \u003cdiv class=\\\"box\\\"\u003e\\n \u003cdiv class=\\\"section-title mb-2\\\"\u003e各品类月度收入堆叠\u003c/div\u003e\\n \u003cdiv class=\\\"chart-container\\\" id=\\\"chartCategoryStacked\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-4-desktop\\\"\u003e\\n \u003cdiv class=\\\"box\\\"\u003e\\n \u003cdiv class=\\\"section-title mb-2\\\"\u003e促销 vs 非促销对比\u003c/div\u003e\\n \u003cdiv class=\\\"chart-container\\\" id=\\\"chartPromoBar\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"column is-4-desktop\\\"\u003e\\n \u003cdiv class=\\\"box\\\"\u003e\\n \u003cdiv class=\\\"section-title mb-2\\\"\u003e库存异常提醒\u003c/div\u003e\\n \u003cdiv class=\\\"chart-container\\\" id=\\\"chartInventoryAlert\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003c!-- Row 3: SKU Detail Table --\u003e\\n \u003cdiv class=\\\"columns is-multiline\\\"\u003e\\n \u003cdiv class=\\\"column is-12\\\"\u003e\\n \u003cdiv class=\\\"box\\\"\u003e\\n \u003cdiv class=\\\"level mb-2\\\"\u003e\\n \u003cdiv class=\\\"level-left\\\"\u003e\\n \u003cdiv class=\\\"section-title\\\"\u003eSKU 明细汇总\u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv class=\\\"level-right\\\"\u003e\\n \u003cspan class=\\\"tag is-light is-info\\\" id=\\\"skuCountTag\\\"\u003e10 个SKU\u003c/span\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cdiv\u003e\\n \u003ctable class=\\\"table is-fullwidth is-hoverable is-size-7\\\" id=\\\"skuTable\\\"\u003e\\n \u003cthead\u003e\\n \u003ctr\u003e\\n \u003cth\u003eSKU\u003c/th\u003e\\n \u003cth\u003e商品名称\u003c/th\u003e\\n \u003cth\u003e品类\u003c/th\u003e\\n \u003cth\u003e单价/成本\u003c/th\u003e\\n \u003cth\u003e市场价\u003c/th\u003e\\n \u003cth\u003e提前期\u003c/th\u003e\\n \u003cth\u003e总收入\u003c/th\u003e\\n \u003cth\u003e总成本\u003c/th\u003e\\n \u003cth\u003e总出库\u003c/th\u003e\\n \u003cth\u003e促销次数\u003c/th\u003e\\n \u003cth\u003e毛利\u003c/th\u003e\\n \u003cth\u003e毛利率\u003c/th\u003e\\n \u003c/tr\u003e\\n \u003c/thead\u003e\\n \u003ctbody id=\\\"skuTableBody\\\"\u003e\u003c/tbody\u003e\\n \u003c/table\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/section\u003e\\n\\n \u003c!-- ECharts --\u003e\\n \u003cscript src=\\\"https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js\\\"\u003e\u003c/script\u003e\\n \u003cscript\u003e\\n /* DATA_START */\\n const DASHBOARD_DATA = {\\\"monthly_summary\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"total_revenue\\\":46018,\\\"total_cogs\\\":23060,\\\"total_begin_amount\\\":73700,\\\"total_end_amount\\\":55658,\\\"total_outbound\\\":612,\\\"promotion_count\\\":3,\\\"non_promotion_count\\\":7},{\\\"month\\\":\\\"Feb-25\\\",\\\"total_revenue\\\":24613,\\\"total_cogs\\\":13510,\\\"total_begin_amount\\\":50615,\\\"total_end_amount\\\":45405,\\\"total_outbound\\\":297,\\\"promotion_count\\\":2,\\\"non_promotion_count\\\":8},{\\\"month\\\":\\\"Mar-25\\\",\\\"total_revenue\\\":29445,\\\"total_cogs\\\":15405,\\\"total_begin_amount\\\":50860,\\\"total_end_amount\\\":42490,\\\"total_outbound\\\":415,\\\"promotion_count\\\":4,\\\"non_promotion_count\\\":6},{\\\"month\\\":\\\"Apr-25\\\",\\\"total_revenue\\\":24015,\\\"total_cogs\\\":12260,\\\"total_begin_amount\\\":37145,\\\"total_end_amount\\\":37230,\\\"total_outbound\\\":295,\\\"promotion_count\\\":3,\\\"non_promotion_count\\\":7},{\\\"month\\\":\\\"May-25\\\",\\\"total_revenue\\\":27745,\\\"total_cogs\\\":14130,\\\"total_begin_amount\\\":43805,\\\"total_end_amount\\\":27275,\\\"total_outbound\\\":365,\\\"promotion_count\\\":5,\\\"non_promotion_count\\\":5}],\\\"category_summary\\\":[{\\\"category\\\":\\\"数码配件\\\",\\\"total_revenue\\\":42826,\\\"total_cogs\\\":27815,\\\"total_begin_amount\\\":85180,\\\"total_end_amount\\\":71578,\\\"total_outbound\\\":354,\\\"sku_count\\\":3,\\\"promotion_count\\\":5},{\\\"category\\\":\\\"家居日用\\\",\\\"total_revenue\\\":17990,\\\"total_cogs\\\":9420,\\\"total_begin_amount\\\":33680,\\\"total_end_amount\\\":27370,\\\"total_outbound\\\":430,\\\"sku_count\\\":2,\\\"promotion_count\\\":4},{\\\"category\\\":\\\"服饰\\\",\\\"total_revenue\\\":57925,\\\"total_cogs\\\":23230,\\\"total_begin_amount\\\":79800,\\\"total_end_amount\\\":61785,\\\"total_outbound\\\":575,\\\"sku_count\\\":2,\\\"promotion_count\\\":3},{\\\"category\\\":\\\"个护\\\",\\\"total_revenue\\\":18480,\\\"total_cogs\\\":9020,\\\"total_begin_amount\\\":43420,\\\"total_end_amount\\\":36430,\\\"total_outbound\\\":440,\\\"sku_count\\\":2,\\\"promotion_count\\\":3},{\\\"category\\\":\\\"食品饮料\\\",\\\"total_revenue\\\":14615,\\\"total_cogs\\\":8880,\\\"total_begin_amount\\\":14045,\\\"total_end_amount\\\":10895,\\\"total_outbound\\\":185,\\\"sku_count\\\":1,\\\"promotion_count\\\":2}],\\\"sku_detail\\\":[{\\\"sku_code\\\":\\\"SKU-A001\\\",\\\"sku_name\\\":\\\"无线鼠标\\\",\\\"category\\\":\\\"数码配件\\\",\\\"unit_cost\\\":38,\\\"market_price\\\":59,\\\"lead_time\\\":7,\\\"total_revenue\\\":9145,\\\"total_cogs\\\":5890,\\\"total_outbound\\\":155,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":120,\\\"end_qty\\\":80,\\\"revenue\\\":2360,\\\"cogs\\\":1520,\\\"outbound\\\":40,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":80,\\\"end_qty\\\":60,\\\"revenue\\\":1180,\\\"cogs\\\":760,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":60,\\\"end_qty\\\":30,\\\"revenue\\\":1770,\\\"cogs\\\":1140,\\\"outbound\\\":30,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":30,\\\"end_qty\\\":100,\\\"revenue\\\":1180,\\\"cogs\\\":760,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":100,\\\"end_qty\\\":55,\\\"revenue\\\":2655,\\\"cogs\\\":1710,\\\"outbound\\\":45,\\\"promotion\\\":\\\"是\\\"}]},{\\\"sku_code\\\":\\\"SKU-A002\\\",\\\"sku_name\\\":\\\"蓝牙键盘\\\",\\\"category\\\":\\\"数码配件\\\",\\\"unit_cost\\\":82,\\\"market_price\\\":129,\\\"lead_time\\\":10,\\\"total_revenue\\\":14190,\\\"total_cogs\\\":9020,\\\"total_outbound\\\":110,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":90,\\\"end_qty\\\":45,\\\"revenue\\\":5805,\\\"cogs\\\":3690,\\\"outbound\\\":45,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":45,\\\"end_qty\\\":70,\\\"revenue\\\":1935,\\\"cogs\\\":1230,\\\"outbound\\\":15,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":70,\\\"end_qty\\\":50,\\\"revenue\\\":2580,\\\"cogs\\\":1640,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":50,\\\"end_qty\\\":25,\\\"revenue\\\":3225,\\\"cogs\\\":2050,\\\"outbound\\\":25,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":25,\\\"end_qty\\\":20,\\\"revenue\\\":645,\\\"cogs\\\":410,\\\"outbound\\\":5,\\\"promotion\\\":\\\"否\\\"}]},{\\\"sku_code\\\":\\\"SKU-A003\\\",\\\"sku_name\\\":\\\"USB扩展坞\\\",\\\"category\\\":\\\"数码配件\\\",\\\"unit_cost\\\":145,\\\"market_price\\\":219,\\\"lead_time\\\":14,\\\"total_revenue\\\":19491,\\\"total_cogs\\\":12905,\\\"total_outbound\\\":89,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":60,\\\"end_qty\\\":72,\\\"revenue\\\":2628,\\\"cogs\\\":1740,\\\"outbound\\\":12,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":72,\\\"end_qty\\\":40,\\\"revenue\\\":7008,\\\"cogs\\\":4640,\\\"outbound\\\":32,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":40,\\\"end_qty\\\":25,\\\"revenue\\\":3285,\\\"cogs\\\":2175,\\\"outbound\\\":15,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":25,\\\"end_qty\\\":55,\\\"revenue\\\":2190,\\\"cogs\\\":1450,\\\"outbound\\\":10,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":55,\\\"end_qty\\\":35,\\\"revenue\\\":4380,\\\"cogs\\\":2900,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"}]},{\\\"sku_code\\\":\\\"SKU-B001\\\",\\\"sku_name\\\":\\\"保温杯\\\",\\\"category\\\":\\\"家居日用\\\",\\\"unit_cost\\\":26,\\\"market_price\\\":49,\\\"lead_time\\\":5,\\\"total_revenue\\\":10290,\\\"total_cogs\\\":5460,\\\"total_outbound\\\":210,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":200,\\\"end_qty\\\":160,\\\"revenue\\\":1960,\\\"cogs\\\":1040,\\\"outbound\\\":40,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":160,\\\"end_qty\\\":100,\\\"revenue\\\":2940,\\\"cogs\\\":1560,\\\"outbound\\\":60,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":100,\\\"end_qty\\\":140,\\\"revenue\\\":1470,\\\"cogs\\\":780,\\\"outbound\\\":30,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":140,\\\"end_qty\\\":70,\\\"revenue\\\":3430,\\\"cogs\\\":1820,\\\"outbound\\\":70,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":70,\\\"end_qty\\\":60,\\\"revenue\\\":490,\\\"cogs\\\":260,\\\"outbound\\\":10,\\\"promotion\\\":\\\"否\\\"}]},{\\\"sku_code\\\":\\\"SKU-B002\\\",\\\"sku_name\\\":\\\"收纳箱\\\",\\\"category\\\":\\\"家居日用\\\",\\\"unit_cost\\\":18,\\\"market_price\\\":35,\\\"lead_time\\\":6,\\\"total_revenue\\\":7700,\\\"total_cogs\\\":3960,\\\"total_outbound\\\":220,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":150,\\\"end_qty\\\":210,\\\"revenue\\\":1400,\\\"cogs\\\":720,\\\"outbound\\\":40,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":210,\\\"end_qty\\\":180,\\\"revenue\\\":1050,\\\"cogs\\\":540,\\\"outbound\\\":30,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":180,\\\"end_qty\\\":90,\\\"revenue\\\":3150,\\\"cogs\\\":1620,\\\"outbound\\\":90,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":90,\\\"end_qty\\\":75,\\\"revenue\\\":525,\\\"cogs\\\":270,\\\"outbound\\\":15,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":75,\\\"end_qty\\\":30,\\\"revenue\\\":1575,\\\"cogs\\\":810,\\\"outbound\\\":45,\\\"promotion\\\":\\\"是\\\"}]},{\\\"sku_code\\\":\\\"SKU-C001\\\",\\\"sku_name\\\":\\\"运动T恤\\\",\\\"category\\\":\\\"服饰\\\",\\\"unit_cost\\\":35,\\\"market_price\\\":89,\\\"lead_time\\\":12,\\\"total_revenue\\\":39160,\\\"total_cogs\\\":15400,\\\"total_outbound\\\":440,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":300,\\\"end_qty\\\":120,\\\"revenue\\\":16020,\\\"cogs\\\":6300,\\\"outbound\\\":180,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":120,\\\"end_qty\\\":80,\\\"revenue\\\":3560,\\\"cogs\\\":1400,\\\"outbound\\\":40,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":80,\\\"end_qty\\\":260,\\\"revenue\\\":4450,\\\"cogs\\\":1750,\\\"outbound\\\":50,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":260,\\\"end_qty\\\":200,\\\"revenue\\\":5340,\\\"cogs\\\":2100,\\\"outbound\\\":60,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":200,\\\"end_qty\\\":90,\\\"revenue\\\":9790,\\\"cogs\\\":3850,\\\"outbound\\\":110,\\\"promotion\\\":\\\"是\\\"}]},{\\\"sku_code\\\":\\\"SKU-C002\\\",\\\"sku_name\\\":\\\"休闲长裤\\\",\\\"category\\\":\\\"服饰\\\",\\\"unit_cost\\\":58,\\\"market_price\\\":139,\\\"lead_time\\\":15,\\\"total_revenue\\\":18765,\\\"total_cogs\\\":7830,\\\"total_outbound\\\":135,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":180,\\\"end_qty\\\":150,\\\"revenue\\\":4170,\\\"cogs\\\":1740,\\\"outbound\\\":30,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":150,\\\"end_qty\\\":130,\\\"revenue\\\":2780,\\\"cogs\\\":1160,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":130,\\\"end_qty\\\":95,\\\"revenue\\\":4865,\\\"cogs\\\":2030,\\\"outbound\\\":35,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":95,\\\"end_qty\\\":60,\\\"revenue\\\":4865,\\\"cogs\\\":2030,\\\"outbound\\\":35,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":60,\\\"end_qty\\\":45,\\\"revenue\\\":2085,\\\"cogs\\\":870,\\\"outbound\\\":15,\\\"promotion\\\":\\\"否\\\"}]},{\\\"sku_code\\\":\\\"SKU-D001\\\",\\\"sku_name\\\":\\\"洗发水\\\",\\\"category\\\":\\\"个护\\\",\\\"unit_cost\\\":22,\\\"market_price\\\":45,\\\"lead_time\\\":8,\\\"total_revenue\\\":9900,\\\"total_cogs\\\":4840,\\\"total_outbound\\\":220,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":240,\\\"end_qty\\\":190,\\\"revenue\\\":2250,\\\"cogs\\\":1100,\\\"outbound\\\":50,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":190,\\\"end_qty\\\":250,\\\"revenue\\\":1800,\\\"cogs\\\":880,\\\"outbound\\\":40,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":250,\\\"end_qty\\\":180,\\\"revenue\\\":3150,\\\"cogs\\\":1540,\\\"outbound\\\":70,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":180,\\\"end_qty\\\":160,\\\"revenue\\\":900,\\\"cogs\\\":440,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":160,\\\"end_qty\\\":120,\\\"revenue\\\":1800,\\\"cogs\\\":880,\\\"outbound\\\":40,\\\"promotion\\\":\\\"否\\\"}]},{\\\"sku_code\\\":\\\"SKU-D002\\\",\\\"sku_name\\\":\\\"沐浴露\\\",\\\"category\\\":\\\"个护\\\",\\\"unit_cost\\\":19,\\\"market_price\\\":39,\\\"lead_time\\\":8,\\\"total_revenue\\\":8580,\\\"total_cogs\\\":4180,\\\"total_outbound\\\":220,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":220,\\\"end_qty\\\":110,\\\"revenue\\\":4290,\\\"cogs\\\":2090,\\\"outbound\\\":110,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":110,\\\"end_qty\\\":90,\\\"revenue\\\":780,\\\"cogs\\\":380,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":90,\\\"end_qty\\\":60,\\\"revenue\\\":1170,\\\"cogs\\\":570,\\\"outbound\\\":30,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":60,\\\"end_qty\\\":140,\\\"revenue\\\":780,\\\"cogs\\\":380,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":140,\\\"end_qty\\\":100,\\\"revenue\\\":1560,\\\"cogs\\\":760,\\\"outbound\\\":40,\\\"promotion\\\":\\\"是\\\"}]},{\\\"sku_code\\\":\\\"SKU-E001\\\",\\\"sku_name\\\":\\\"咖啡豆\\\",\\\"category\\\":\\\"食品饮料\\\",\\\"unit_cost\\\":48,\\\"market_price\\\":79,\\\"lead_time\\\":4,\\\"total_revenue\\\":14615,\\\"total_cogs\\\":8880,\\\"total_outbound\\\":185,\\\"records\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"begin_qty\\\":100,\\\"end_qty\\\":35,\\\"revenue\\\":5135,\\\"cogs\\\":3120,\\\"outbound\\\":65,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Feb-25\\\",\\\"begin_qty\\\":35,\\\"end_qty\\\":65,\\\"revenue\\\":1580,\\\"cogs\\\":960,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"Mar-25\\\",\\\"begin_qty\\\":65,\\\"end_qty\\\":20,\\\"revenue\\\":3555,\\\"cogs\\\":2160,\\\"outbound\\\":45,\\\"promotion\\\":\\\"是\\\"},{\\\"month\\\":\\\"Apr-25\\\",\\\"begin_qty\\\":20,\\\"end_qty\\\":50,\\\"revenue\\\":1580,\\\"cogs\\\":960,\\\"outbound\\\":20,\\\"promotion\\\":\\\"否\\\"},{\\\"month\\\":\\\"May-25\\\",\\\"begin_qty\\\":50,\\\"end_qty\\\":15,\\\"revenue\\\":2765,\\\"cogs\\\":1680,\\\"outbound\\\":35,\\\"promotion\\\":\\\"是\\\"}]}],\\\"promotion_summary\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"promotion_total_revenue\\\":26115,\\\"non_promotion_total_revenue\\\":19903,\\\"promotion_total_outbound\\\":335,\\\"non_promotion_total_outbound\\\":277},{\\\"month\\\":\\\"Feb-25\\\",\\\"promotion_total_revenue\\\":9948,\\\"non_promotion_total_revenue\\\":14665,\\\"promotion_total_outbound\\\":92,\\\"non_promotion_total_outbound\\\":205},{\\\"month\\\":\\\"Mar-25\\\",\\\"promotion_total_revenue\\\":11625,\\\"non_promotion_total_revenue\\\":17820,\\\"promotion_total_outbound\\\":235,\\\"non_promotion_total_outbound\\\":180},{\\\"month\\\":\\\"Apr-25\\\",\\\"promotion_total_revenue\\\":11520,\\\"non_promotion_total_revenue\\\":12495,\\\"promotion_total_outbound\\\":130,\\\"non_promotion_total_outbound\\\":165},{\\\"month\\\":\\\"May-25\\\",\\\"promotion_total_revenue\\\":18345,\\\"non_promotion_total_revenue\\\":9400,\\\"promotion_total_outbound\\\":275,\\\"non_promotion_total_outbound\\\":90}],\\\"overview_kpis\\\":{\\\"total_sku_count\\\":10,\\\"total_revenue_all\\\":151836,\\\"total_cogs_all\\\":78365,\\\"total_begin_amount_all\\\":256125,\\\"total_end_amount_all\\\":208058,\\\"total_outbound_all\\\":1984,\\\"promotion_record_count\\\":17,\\\"total_records\\\":50},\\\"monthly_category_revenue\\\":[{\\\"month\\\":\\\"Jan-25\\\",\\\"category\\\":\\\"数码配件\\\",\\\"revenue\\\":10793},{\\\"month\\\":\\\"Jan-25\\\",\\\"category\\\":\\\"家居日用\\\",\\\"revenue\\\":3360},{\\\"month\\\":\\\"Jan-25\\\",\\\"category\\\":\\\"服饰\\\",\\\"revenue\\\":20190},{\\\"month\\\":\\\"Jan-25\\\",\\\"category\\\":\\\"个护\\\",\\\"revenue\\\":6540},{\\\"month\\\":\\\"Jan-25\\\",\\\"category\\\":\\\"食品饮料\\\",\\\"revenue\\\":5135},{\\\"month\\\":\\\"Feb-25\\\",\\\"category\\\":\\\"数码配件\\\",\\\"revenue\\\":10123},{\\\"month\\\":\\\"Feb-25\\\",\\\"category\\\":\\\"家居日用\\\",\\\"revenue\\\":3990},{\\\"month\\\":\\\"Feb-25\\\",\\\"category\\\":\\\"服饰\\\",\\\"revenue\\\":6340},{\\\"month\\\":\\\"Feb-25\\\",\\\"category\\\":\\\"个护\\\",\\\"revenue\\\":2580},{\\\"month\\\":\\\"Feb-25\\\",\\\"category\\\":\\\"食品饮料\\\",\\\"revenue\\\":1580},{\\\"month\\\":\\\"Mar-25\\\",\\\"category\\\":\\\"数码配件\\\",\\\"revenue\\\":7635},{\\\"month\\\":\\\"Mar-25\\\",\\\"category\\\":\\\"家居日用\\\",\\\"revenue\\\":4620},{\\\"month\\\":\\\"Mar-25\\\",\\\"category\\\":\\\"服饰\\\",\\\"revenue\\\":9315},{\\\"month\\\":\\\"Mar-25\\\",\\\"category\\\":\\\"个护\\\",\\\"revenue\\\":4320},{\\\"month\\\":\\\"Mar-25\\\",\\\"category\\\":\\\"食品饮料\\\",\\\"revenue\\\":3555},{\\\"month\\\":\\\"Apr-25\\\",\\\"category\\\":\\\"数码配件\\\",\\\"revenue\\\":6595},{\\\"month\\\":\\\"Apr-25\\\",\\\"category\\\":\\\"家居日用\\\",\\\"revenue\\\":3955},{\\\"month\\\":\\\"Apr-25\\\",\\\"category\\\":\\\"服饰\\\",\\\"revenue\\\":10205},{\\\"month\\\":\\\"Apr-25\\\",\\\"category\\\":\\\"个护\\\",\\\"revenue\\\":1680},{\\\"month\\\":\\\"Apr-25\\\",\\\"category\\\":\\\"食品饮料\\\",\\\"revenue\\\":1580},{\\\"month\\\":\\\"May-25\\\",\\\"category\\\":\\\"数码配件\\\",\\\"revenue\\\":7680},{\\\"month\\\":\\\"May-25\\\",\\\"category\\\":\\\"家居日用\\\",\\\"revenue\\\":2065},{\\\"month\\\":\\\"May-25\\\",\\\"category\\\":\\\"服饰\\\",\\\"revenue\\\":11875},{\\\"month\\\":\\\"May-25\\\",\\\"category\\\":\\\"个护\\\",\\\"revenue\\\":3360},{\\\"month\\\":\\\"May-25\\\",\\\"category\\\":\\\"食品饮料\\\",\\\"revenue\\\":2765}]};\\n /* DATA_END */\\n\\n // ============ Data ============\\n const raw = DASHBOARD_DATA;\\n\\n // ============ Filters ============\\n let activeMonth = 'all';\\n let activeCategory = 'all';\\n let activePromotion = 'all';\\n\\n const monthFilter = document.getElementById('monthFilter');\\n const categoryFilter = document.getElementById('categoryFilter');\\n const promotionFilter = document.getElementById('promotionFilter');\\n\\n function formatCurrency(v) { return '¥' + Number(v).toLocaleString('zh-CN'); }\\n function formatNum(v) { return Number(v).toLocaleString('zh-CN'); }\\n function formatPct(v) { return (v * 100).toFixed(1) + '%'; }\\n\\n // Populate filters\\n raw.monthly_summary.forEach(m =\u003e {\\n const opt = document.createElement('option');\\n opt.value = m.month;\\n opt.textContent = m.month;\\n monthFilter.appendChild(opt);\\n });\\n raw.category_summary.forEach(c =\u003e {\\n const opt = document.createElement('option');\\n opt.value = c.category;\\n opt.textContent = c.category;\\n categoryFilter.appendChild(opt);\\n });\\n\\n // Filter data\\n function getFilteredData() {\\n let data = [];\\n raw.sku_detail.forEach(sku =\u003e {\\n sku.records.forEach(r =\u003e {\\n data.push({\\n sku_code: sku.sku_code,\\n sku_name: sku.sku_name,\\n category: sku.category,\\n month: r.month,\\n revenue: r.revenue,\\n cogs: r.cogs,\\n outbound: r.outbound,\\n promotion: r.promotion,\\n begin_qty: r.begin_qty,\\n end_qty: r.end_qty,\\n unit_cost: sku.unit_cost,\\n market_price: sku.market_price\\n });\\n });\\n });\\n if (activeMonth !== 'all') data = data.filter(d =\u003e d.month === activeMonth);\\n if (activeCategory !== 'all') data = data.filter(d =\u003e d.category === activeCategory);\\n if (activePromotion !== 'all') data = data.filter(d =\u003e d.promotion === activePromotion);\\n return data;\\n }\\n\\n function updateKPIs() {\\n const filtered = getFilteredData();\\n const totalRevenue = filtered.reduce((s, d) =\u003e s + d.revenue, 0);\\n const totalCogs = filtered.reduce((s, d) =\u003e s + d.cogs, 0);\\n const totalOutbound = filtered.reduce((s, d) =\u003e s + d.outbound, 0);\\n const promoCount = filtered.filter(d =\u003e d.promotion === '是').length;\\n const margin = totalRevenue \u003e 0 ? (totalRevenue - totalCogs) / totalRevenue : 0;\\n\\n // End amount from original data filtered\\n let endAmount = 0;\\n const skuEndMap = {};\\n filtered.forEach(d =\u003e {\\n const key = d.sku_code + '_' + d.month;\\n if (!skuEndMap[key]) {\\n // Find from raw\\n const sku = raw.sku_detail.find(s =\u003e s.sku_code === d.sku_code);\\n if (sku) {\\n const rec = sku.records.find(r =\u003e r.month === d.month);\\n if (rec) skuEndMap[key] = rec.end_qty * d.unit_cost;\\n }\\n }\\n });\\n // simpler: use precomputed\\n const monthData = activeMonth === 'all' ? raw.monthly_summary : raw.monthly_summary.filter(m =\u003e m.month === activeMonth);\\n endAmount = monthData.reduce((s, m) =\u003e s + m.total_end_amount, 0);\\n if (activeCategory !== 'all') {\\n // approximate: use category proportion\\n const cat = raw.category_summary.find(c =\u003e c.category === activeCategory);\\n endAmount = cat ? cat.total_end_amount : 0;\\n }\\n\\n document.getElementById('kpiRevenue').textContent = formatCurrency(totalRevenue);\\n document.getElementById('kpiCogs').textContent = formatCurrency(totalCogs);\\n document.getElementById('kpiOutbound').textContent = formatNum(totalOutbound);\\n document.getElementById('kpiEndAmount').textContent = formatCurrency(endAmount);\\n document.getElementById('kpiMargin').textContent = formatPct(margin);\\n document.getElementById('kpiPromo').textContent = promoCount + ' / ' + filtered.length;\\n }\\n\\n // ============ Vintage Color Palette ============\\n const vintageColors = {\\n primary: '#8b6914', // 复古金\\n secondary: '#a0522d', // 赭色\\n accent1: '#5b7a4a', // 橄榄绿\\n accent2: '#7a5c6b', // 紫褐\\n accent3: '#6b7a8a', // 灰蓝\\n promo: '#c49a3c', // 促销金\\n nonPromo: '#7a6a5a', // 非促销棕\\n danger: '#8b3a3a', // 暗红\\n info: '#4a6b6b', // 暗青\\n success: '#5b7a4a', // 暗绿\\n warning: '#b8943a', // 暗黄\\n line: '#8b7355', // 线色\\n grid: '#d4c5a9' // 网格线\\n };\\n const vintagePalette = ['#8b6914','#a0522d','#5b7a4a','#7a5c6b','#6b7a8a','#b8943a','#8b7355','#7a6a5a'];\\n\\n // ============ Charts ============\\n const chartTrend = echarts.init(document.getElementById('chartTrend'));\\n const chartCategoryPie = echarts.init(document.getElementById('chartCategoryPie'));\\n const chartCategoryStacked = echarts.init(document.getElementById('chartCategoryStacked'));\\n const chartPromoBar = echarts.init(document.getElementById('chartPromoBar'));\\n const chartInventoryAlert = echarts.init(document.getElementById('chartInventoryAlert'));\\n\\n function renderTrend() {\\n const filtered = getFilteredData();\\n const months = raw.monthly_summary.map(m =\u003e m.month);\\n const revenue = months.map(m =\u003e filtered.filter(d =\u003e d.month === m).reduce((s, d) =\u003e s + d.revenue, 0));\\n const cogs = months.map(m =\u003e filtered.filter(d =\u003e d.month === m).reduce((s, d) =\u003e s + d.cogs, 0));\\n const outbound = months.map(m =\u003e filtered.filter(d =\u003e d.month === m).reduce((s, d) =\u003e s + d.outbound, 0));\\n\\n const option = {\\n color: vintagePalette,\\n tooltip: { trigger: 'axis', backgroundColor: '#fcf8ef', borderColor: '#d4c5a9', textStyle: { color: '#3a2c1b', fontFamily: 'Source Serif 4, serif' } },\\n legend: { data: ['销售收入', '销售成本', '出库量'], bottom: 0, textStyle: { fontSize: 11, color: '#5a4a3a', fontFamily: 'Source Serif 4, serif' } },\\n grid: { left: 60, right: 50, top: 30, bottom: 50 },\\n xAxis: { type: 'category', data: months, axisLabel: { fontSize: 11, color: '#5a4a3a' }, axisLine: { lineStyle: { color: '#c8b89a' } }, axisTick: { lineStyle: { color: '#c8b89a' } } },\\n yAxis: [\\n { type: 'value', name: '金额 (¥)', nameTextStyle: { fontSize: 10, color: '#7a6a4e' }, splitLine: { lineStyle: { color: '#e0d4be', type: 'dashed' } }, axisLabel: { color: '#5a4a3a' } },\\n { type: 'value', name: '出库量', nameTextStyle: { fontSize: 10, color: '#7a6a4e', padding: [0,0,0,40] }, splitLine: { show: false }, axisLabel: { color: '#5a4a3a' }, axisLine: { show: true, lineStyle: { color: '#c8b89a' } } }\\n ],\\n series: [\\n { name: '销售收入', type: 'bar', data: revenue, itemStyle: { color: '#8b6914' }, barWidth: '24%' },\\n { name: '销售成本', type: 'bar', data: cogs, itemStyle: { color: '#a0522d' }, barWidth: '24%' },\\n { name: '出库量', type: 'line', yAxisIndex: 1, data: outbound, lineStyle: { color: '#5b7a4a', width: 2 }, symbol: 'diamond', symbolSize: 7, itemStyle: { color: '#5b7a4a' } }\\n ]\\n };\\n chartTrend.setOption(option, true);\\n }\\n\\n function renderCategoryPie() {\\n const filtered = getFilteredData();\\n const catMap = {};\\n filtered.forEach(d =\u003e { catMap[d.category] = (catMap[d.category] || 0) + d.revenue; });\\n const data = Object.keys(catMap).map(k =\u003e ({ name: k, value: catMap[k] }));\\n const option = {\\n color: vintagePalette,\\n tooltip: { trigger: 'item', formatter: '{b}: ¥{c} ({d}%)', backgroundColor: '#fcf8ef', borderColor: '#d4c5a9', textStyle: { color: '#3a2c1b', fontFamily: 'Source Serif 4, serif' } },\\n series: [{\\n type: 'pie',\\n radius: ['35%', '65%'],\\n center: ['50%', '50%'],\\n avoidLabelOverlap: true,\\n label: { show: true, formatter: '{b}\\\\n{d}%', fontSize: 10, color: '#3a2c1b', fontFamily: 'Source Serif 4, serif' },\\n emphasis: { label: { show: true, fontSize: 12, fontWeight: 'bold', color: '#2c1810' } },\\n data: data,\\n itemStyle: { borderRadius: 0, borderColor: '#fcf8ef', borderWidth: 3 }\\n }]\\n };\\n chartCategoryPie.setOption(option, true);\\n }\\n\\n function renderCategoryStacked() {\\n const filtered = getFilteredData();\\n const months = raw.monthly_summary.map(m =\u003e m.month);\\n const categories = [...new Set(filtered.map(d =\u003e d.category))];\\n const series = categories.map(cat =\u003e {\\n const data = months.map(m =\u003e {\\n return filtered.filter(d =\u003e d.month === m \u0026\u0026 d.category === cat).reduce((s, d) =\u003e s + d.revenue, 0);\\n });\\n return { name: cat, type: 'bar', stack: 'total', data: data };\\n });\\n const colors = ['#8b6914', '#a0522d', '#5b7a4a', '#7a5c6b', '#6b7a8a'];\\n series.forEach((s, i) =\u003e { s.itemStyle = { color: colors[i % colors.length] }; });\\n\\n const option = {\\n color: vintagePalette,\\n tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, backgroundColor: '#fcf8ef', borderColor: '#d4c5a9', textStyle: { color: '#3a2c1b', fontFamily: 'Source Serif 4, serif' } },\\n legend: { data: categories, bottom: 0, textStyle: { fontSize: 10, color: '#5a4a3a', fontFamily: 'Source Serif 4, serif' } },\\n grid: { left: 40, right: 30, top: 25, bottom: 50 },\\n xAxis: { type: 'category', data: months, axisLabel: { fontSize: 10, color: '#5a4a3a' }, axisLine: { lineStyle: { color: '#c8b89a' } } },\\n yAxis: { type: 'value', name: '收入 (¥)', nameTextStyle: { fontSize: 10, color: '#7a6a4e' }, splitLine: { lineStyle: { color: '#e0d4be', type: 'dashed' } }, axisLabel: { color: '#5a4a3a' } },\\n series: series\\n };\\n chartCategoryStacked.setOption(option, true);\\n }\\n\\n function renderPromoBar() {\\n const filtered = getFilteredData();\\n const months = raw.monthly_summary.map(m =\u003e m.month);\\n const promoRevenue = months.map(m =\u003e filtered.filter(d =\u003e d.month === m \u0026\u0026 d.promotion === '是').reduce((s, d) =\u003e s + d.revenue, 0));\\n const nonPromoRevenue = months.map(m =\u003e filtered.filter(d =\u003e d.month === m \u0026\u0026 d.promotion === '否').reduce((s, d) =\u003e s + d.revenue, 0));\\n\\n const option = {\\n color: vintagePalette,\\n tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, backgroundColor: '#fcf8ef', borderColor: '#d4c5a9', textStyle: { color: '#3a2c1b', fontFamily: 'Source Serif 4, serif' } },\\n legend: { data: ['促销收入', '非促销收入'], bottom: 0, textStyle: { fontSize: 10, color: '#5a4a3a', fontFamily: 'Source Serif 4, serif' } },\\n grid: { left: 40, right: 30, top: 25, bottom: 50 },\\n xAxis: { type: 'category', data: months, axisLabel: { fontSize: 10, color: '#5a4a3a' }, axisLine: { lineStyle: { color: '#c8b89a' } } },\\n yAxis: { type: 'value', name: '收入 (¥)', nameTextStyle: { fontSize: 10, color: '#7a6a4e' }, splitLine: { lineStyle: { color: '#e0d4be', type: 'dashed' } }, axisLabel: { color: '#5a4a3a' } },\\n series: [\\n { name: '促销收入', type: 'bar', data: promoRevenue, itemStyle: { color: '#c49a3c' }, barWidth: '30%' },\\n { name: '非促销收入', type: 'bar', data: nonPromoRevenue, itemStyle: { color: '#7a6a5a' }, barWidth: '30%' }\\n ]\\n };\\n chartPromoBar.setOption(option, true);\\n }\\n\\n function renderInventoryAlert() {\\n const filtered = getFilteredData();\\n const months = [...new Set(filtered.map(d =\u003e d.month))];\\n const latestMonth = activeMonth !== 'all' ? activeMonth : months.sort().pop() || 'May-25';\\n const skuFiltered = raw.sku_detail.filter(sku =\u003e {\\n if (activeCategory !== 'all' \u0026\u0026 sku.category !== activeCategory) return false;\\n return true;\\n });\\n const alerts = skuFiltered.map(sku =\u003e {\\n const rec = sku.records.find(r =\u003e r.month === latestMonth);\\n return { name: sku.sku_name, end_qty: rec ? rec.end_qty : 0, category: sku.category, lead_time: sku.lead_time };\\n }).sort((a, b) =\u003e a.end_qty - b.end_qty);\\n\\n const names = alerts.map(a =\u003e a.name);\\n const qty = alerts.map(a =\u003e a.end_qty);\\n const colors = qty.map(v =\u003e v \u003c= 30 ? '#8b3a3a' : v \u003c= 60 ? '#b8943a' : '#5b7a4a');\\n\\n const option = {\\n color: vintagePalette,\\n tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, backgroundColor: '#fcf8ef', borderColor: '#d4c5a9', textStyle: { color: '#3a2c1b', fontFamily: 'Source Serif 4, serif' }, formatter: function(params) {\\n const p = params[0];\\n const a = alerts[p.dataIndex];\\n return `${a.name}\u003cbr/\u003e期末库存: ${a.end_qty} 件\u003cbr/\u003e品类: ${a.category}\u003cbr/\u003e提前期: ${a.lead_time} 天`;\\n } },\\n grid: { left: 60, right: 25, top: 10, bottom: 40 },\\n xAxis: { type: 'value', name: '期末库存(件)', nameLocation: 'middle', nameGap: 22, nameTextStyle: { fontSize: 9, color: '#7a6a4e' }, splitLine: { lineStyle: { color: '#e0d4be', type: 'dashed' } }, axisLabel: { color: '#5a4a3a', fontSize: 9 }, axisLine: { lineStyle: { color: '#c8b89a' } } },\\n yAxis: { type: 'category', data: names, axisLabel: { fontSize: 10, color: '#5a4a3a' }, axisLine: { lineStyle: { color: '#c8b89a' } }, axisTick: { lineStyle: { color: '#c8b89a' } } },\\n series: [{\\n type: 'bar',\\n data: qty.map((v, i) =\u003e ({ value: v, itemStyle: { color: colors[i] } })),\\n barWidth: '55%'\\n }]\\n };\\n chartInventoryAlert.setOption(option, true);\\n }\\n\\n function renderSKUTable() {\\n const filtered = getFilteredData();\\n const tbody = document.getElementById('skuTableBody');\\n tbody.innerHTML = '';\\n const skuSet = [...new Set(filtered.map(d =\u003e d.sku_code))];\\n skuSet.forEach(skuCode =\u003e {\\n const sku = raw.sku_detail.find(s =\u003e s.sku_code === skuCode);\\n if (!sku) return;\\n const skuFiltered = filtered.filter(d =\u003e d.sku_code === skuCode);\\n const totalRevenue = skuFiltered.reduce((s, d) =\u003e s + d.revenue, 0);\\n const totalCogs = skuFiltered.reduce((s, d) =\u003e s + d.cogs, 0);\\n const totalOutbound = skuFiltered.reduce((s, d) =\u003e s + d.outbound, 0);\\n const promoCount = skuFiltered.filter(d =\u003e d.promotion === '是').length;\\n const grossProfit = totalRevenue - totalCogs;\\n const margin = totalRevenue \u003e 0 ? (grossProfit / totalRevenue * 100).toFixed(1) + '%' : '—';\\n const tr = document.createElement('tr');\\n tr.innerHTML = `\\n \u003ctd\u003e\u003ccode\u003e${sku.sku_code}\u003c/code\u003e\u003c/td\u003e\\n \u003ctd\u003e\u003cstrong\u003e${sku.sku_name}\u003c/strong\u003e\u003c/td\u003e\\n \u003ctd\u003e\u003cspan class=\\\"tag is-light\\\"\u003e${sku.category}\u003c/span\u003e\u003c/td\u003e\\n \u003ctd\u003e¥${sku.unit_cost}\u003c/td\u003e\\n \u003ctd\u003e¥${sku.market_price}\u003c/td\u003e\\n \u003ctd\u003e${sku.lead_time}天\u003c/td\u003e\\n \u003ctd\u003e${formatCurrency(totalRevenue)}\u003c/td\u003e\\n \u003ctd\u003e${formatCurrency(totalCogs)}\u003c/td\u003e\\n \u003ctd\u003e${formatNum(totalOutbound)}\u003c/td\u003e\\n \u003ctd\u003e${promoCount}\u003c/td\u003e\\n \u003ctd\u003e${formatCurrency(grossProfit)}\u003c/td\u003e\\n \u003ctd\u003e${margin}\u003c/td\u003e\\n `;\\n tbody.appendChild(tr);\\n });\\n document.getElementById('skuCountTag').textContent = skuSet.length + ' 个SKU';\\n }\\n\\n // ============ Resize ============\\n function resizeAll() {\\n [chartTrend, chartCategoryPie, chartCategoryStacked, chartPromoBar, chartInventoryAlert].forEach(c =\u003e c.resize());\\n }\\n window.addEventListener('resize', resizeAll);\\n\\n // ============ Filter Change ============\\n function onFilterChange() {\\n activeMonth = monthFilter.value;\\n activeCategory = categoryFilter.value;\\n activePromotion = promotionFilter.value;\\n updateKPIs();\\n renderTrend();\\n renderCategoryPie();\\n renderCategoryStacked();\\n renderPromoBar();\\n renderInventoryAlert();\\n renderSKUTable();\\n }\\n\\n monthFilter.addEventListener('change', onFilterChange);\\n categoryFilter.addEventListener('change', onFilterChange);\\n promotionFilter.addEventListener('change', onFilterChange);\\n\\n // ============ Init ============\\n function init() {\\n renderTrend();\\n renderCategoryPie();\\n renderCategoryStacked();\\n renderPromoBar();\\n renderInventoryAlert();\\n renderSKUTable();\\n updateKPIs();\\n }\\n\\n init();\\n \u003c/script\u003e\\n\u003cfooter\u003e\\n \u003cstyle\u003e\\n .dashboard-guide-footer-link {\\n transition: transform 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;\\n }\\n .dashboard-guide-footer-link:hover {\\n transform: translateY(-4px);\\n background: #2f4ee8 !important;\\n box-shadow: 0 12px 24px rgba(65, 95, 255, 0.24) !important;\\n }\\n \u003c/style\u003e\\n \u003cdiv style=\\\"padding: 24px 24px 40px; text-align: center; background: transparent; color: #333; font-family: inherit;\\\"\u003e\\n \u003cdiv style=\\\"display: flex; align-items: center; width: 100%; gap: 12px; font-size: 16px; line-height: 1.6; margin-bottom: 16px;\\\"\u003e\\n \u003cspan style=\\\"display: block; height: 1px; flex: 1 1 auto; background: #8a8a8a26;\\\"\u003e\u003c/span\u003e\\n \u003cspan style=\\\"flex: 0 1 auto; min-width: 0; color: #7676767a;\\\"\u003e由 RowSpeak 提供 · 数秒内创建你的 AI 看板。\u003c/span\u003e\\n \u003cspan style=\\\"display: block; height: 1px; flex: 1 1 auto; background: #8a8a8a26;\\\"\u003e\u003c/span\u003e\\n \u003c/div\u003e\\n \u003ca class=\\\"dashboard-guide-footer-link\\\" href=\\\"https://dash.rowspeak.ai/dashboard\\\" target=\\\"_top\\\" style=\\\"display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 8px 16px; border-radius: 8px; background: #415fff; color: #fff; text-decoration: none; box-shadow: 0 8px 18px rgba(65, 95, 255, 0.18);\\\"\u003e\\n \u003cspan\u003e免费试用\u003c/span\u003e\\n \u003cspan style=\\\"margin-left: 4px;\\\"\u003e-\u0026gt;\u003c/span\u003e\\n \u003c/a\u003e\\n \u003c/div\u003e\\n \u003c/footer\u003e\u003c/body\u003e\\n\u003c/html\u003e\",\"dashboardHtmlPreview\":{\"title\":\"库存与销售管理看板\",\"metrics\":[\"总销售收入\",\"总销售成本\",\"总出库量\",\"期末库存金额\",\"毛利率\",\"促销记录数\"]},\"html_content_version\":3}","shared":true,"updated_at":1788226625}