wanshenmean
2026-03-30 b9b411438c49ec8c882de5d5889b6e232ac0ae9a
docs: 修正实现计划中的问题

- 修正 GetWeekKey 使用 ISO 8601 周计算
- 修正 StockAgeDistribution 使用 SQL 过滤而非内存计算
- 移除无用的 updateWeeklyTrendChart 方法
- 移除未使用的 dailyData 和 loadDailyStats
- 添加 window resize 处理器

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
已修改1个文件
63 ■■■■ 文件已修改
Code/WMS/docs/superpowers/plans/2026-03-30-dashboard-chart-plan.md 63 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/docs/superpowers/plans/2026-03-30-dashboard-chart-plan.md
@@ -219,10 +219,12 @@
private string GetWeekKey(DateTime date)
{
    // 获取周一开始的周
    // 获取周一开始的周 (ISO 8601)
    var diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7;
    var monday = date.AddDays(-diff);
    return monday.ToString("yyyy-Www");
    var weekNum = System.Globalization.CultureInfo.InvariantCulture
        .Calendar.GetWeekOfYear(monday, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    return $"{monday.Year}-W{weekNum:D2}";
}
```
@@ -262,16 +264,14 @@
public async Task<WebResponseContent> StockAgeDistribution()
{
    var now = DateTime.Now;
    var stocks = await _db.Queryable<Dt_StockInfo>()
        .Select(s => s.CreateDate)
        .ToListAsync();
    // 使用 SQL 直接分组统计,避免加载所有数据到内存
    var result = new[]
    {
        new { Range = "7天内", Count = stocks.Count(s => (now - s).TotalDays <= 7) },
        new { Range = "7-30天", Count = stocks.Count(s => (now - s).TotalDays > 7 && (now - s).TotalDays <= 30) },
        new { Range = "30-90天", Count = stocks.Count(s => (now - s).TotalDays > 30 && (now - s).TotalDays <= 90) },
        new { Range = "90天以上", Count = stocks.Count(s => (now - s).TotalDays > 90) }
        new { Range = "7天内", Count = await _db.Queryable<Dt_StockInfo>().Where(s => EF.Functions.DateDiffDay(s.CreateDate, now) <= 7).CountAsync() },
        new { Range = "7-30天", Count = await _db.Queryable<Dt_StockInfo>().Where(s => EF.Functions.DateDiffDay(s.CreateDate, now) > 7 && EF.Functions.DateDiffDay(s.CreateDate, now) <= 30).CountAsync() },
        new { Range = "30-90天", Count = await _db.Queryable<Dt_StockInfo>().Where(s => EF.Functions.DateDiffDay(s.CreateDate, now) > 30 && EF.Functions.DateDiffDay(s.CreateDate, now) <= 90).CountAsync() },
        new { Range = "90天以上", Count = await _db.Queryable<Dt_StockInfo>().Where(s => EF.Functions.DateDiffDay(s.CreateDate, now) > 90).CountAsync() }
    };
    return WebResponseContent.Instance.OK(null, result);
@@ -402,7 +402,6 @@
        MonthOutbound: 0,
        TotalStock: 0
      },
      dailyData: [],
      weeklyData: [],
      monthlyData: [],
      stockAgeData: [],
@@ -412,9 +411,15 @@
  mounted() {
    this.initCharts();
    this.loadData();
    window.addEventListener("resize", this.handleResize);
  },
  beforeUnmount() {
    window.removeEventListener("resize", this.handleResize);
    Object.values(this.charts).forEach(chart => chart.dispose());
  },
  methods: {
    handleResize() {
      Object.values(this.charts).forEach(chart => chart.resize());
  },
  methods: {
    initCharts() {
@@ -428,7 +433,6 @@
    async loadData() {
      await this.loadOverview();
      await this.loadDailyStats();
      await this.loadWeeklyStats();
      await this.loadMonthlyStats();
      await this.loadStockAgeDistribution();
@@ -449,23 +453,12 @@
      }
    },
    async loadDailyStats() {
      try {
        const res = await this.http.get("/api/Dashboard/DailyStats", { days: 30 });
        if (res.Status && res.Data) {
          this.dailyData = res.Data;
        }
      } catch (e) {
        console.error("加载每日统计失败", e);
      }
    },
    async loadWeeklyStats() {
      try {
        const res = await this.http.get("/api/Dashboard/WeeklyStats", { weeks: 12 });
        if (res.Status && res.Data) {
          this.weeklyData = res.Data;
          this.updateWeeklyTrendChart();
          this.updateWeekChart();
        }
      } catch (e) {
        console.error("加载每周统计失败", e);
@@ -597,7 +590,7 @@
      this.charts.month.setOption(option, true);
    },
    // 更新月度趋势图表(折线+柱状组合)
    // 更新月度趋势图表(折线图)
    updateMonthlyTrendChart() {
      const option = {
        tooltip: { trigger: "axis" },
@@ -617,28 +610,6 @@
        series: [
          { name: "入库", type: "line", data: this.monthlyData.map(m => m.Inbound), itemStyle: { color: "#5470c6" } },
          { name: "出库", type: "line", data: this.monthlyData.map(m => m.Outbound), itemStyle: { color: "#91cc75" } }
        ]
      };
      this.charts.monthlyTrend.setOption(option, true);
    },
    // 更新周趋势图表
    updateWeeklyTrendChart() {
      const option = {
        tooltip: { trigger: "axis" },
        legend: { data: ["入库", "出库"], textStyle: { color: "#fff" } },
        xAxis: {
          type: "category",
          data: this.weeklyData.map(w => w.Week),
          axisLabel: { color: "#fff", rotate: 45 }
        },
        yAxis: {
          type: "value",
          axisLabel: { color: "#fff" }
        },
        series: [
          { name: "入库", type: "bar", data: this.weeklyData.map(w => w.Inbound), itemStyle: { color: "#5470c6" } },
          { name: "出库", type: "bar", data: this.weeklyData.map(w => w.Outbound), itemStyle: { color: "#91cc75" } }
        ]
      };
      this.charts.monthlyTrend.setOption(option, true);