NewLife/YuQue

统一 Widget GetData 返回类型为公开类 KpiData

将多个 Widget 组件(如 BookCountWidget、DocCountWidget、NavCountWidget、TodayDocsWidget、TotalHitsWidget、WordCountWidget)的 GetData 方法返回类型由匿名对象统一替换为新公开类 KpiData,解决跨程序集 dynamic 绑定时因匿名类型 internal 导致的 RuntimeBinderException。KpiData 定义 Value、Trend、Url 属性,作为 KPI 卡片的数据契约,便于魔方 Dashboard 视图渲染。
大石头 authored at 2026-09-02 19:03:34
9c60a4b
Tree
1 Parent(s) 59a0260
Summary: 7 changed files with 22 additions and 6 deletions.
Modified +1 -1
Modified +1 -1
Added +16 -0
Modified +1 -1
Modified +1 -1
Modified +1 -1
Modified +1 -1
Modified +1 -1
diff --git a/NewLife.YuqueWeb/Widgets/BookCountWidget.cs b/NewLife.YuqueWeb/Widgets/BookCountWidget.cs
index e6ed7ea..6dd49f8 100644
--- a/NewLife.YuqueWeb/Widgets/BookCountWidget.cs
+++ b/NewLife.YuqueWeb/Widgets/BookCountWidget.cs
@@ -14,7 +14,7 @@ public class BookCountWidget : IWidget
         var books = Book.GetValids().Count;
         var groups = Group.Meta.Count;
 
-        return new
+        return new KpiData
         {
             Value = books.ToString("n0"),
             Trend = $"知识组 {groups} 个",
Modified +1 -1
diff --git a/NewLife.YuqueWeb/Widgets/DocCountWidget.cs b/NewLife.YuqueWeb/Widgets/DocCountWidget.cs
index 53a3131..3edb10d 100644
--- a/NewLife.YuqueWeb/Widgets/DocCountWidget.cs
+++ b/NewLife.YuqueWeb/Widgets/DocCountWidget.cs
@@ -12,7 +12,7 @@ public class DocCountWidget : IWidget
     {
         var (enable, pub) = Document.GetCounts();
 
-        return new
+        return new KpiData
         {
             Value = enable.ToString("n0"),
             Trend = $"公开 {pub} 篇",
Added +16 -0
diff --git a/NewLife.YuqueWeb/Widgets/KpiData.cs b/NewLife.YuqueWeb/Widgets/KpiData.cs
new file mode 100644
index 0000000..91d71c2
--- /dev/null
+++ b/NewLife.YuqueWeb/Widgets/KpiData.cs
@@ -0,0 +1,16 @@
+namespace NewLife.YuqueWeb.Widgets;
+
+/// <summary>KPI 小卡数据。工作台 KPI 组件返回的公开数据模型,承载 { Value, Trend, Url } 渲染契约。
+/// 必须是公开类型:匿名类型编译为 internal,业务程序集返回匿名对象时,魔方 Dashboard 视图
+/// (NewLife.Cube.dll)跨程序集 dynamic 绑定会抛 RuntimeBinderException('object' 不含 'Value')</summary>
+public class KpiData
+{
+    /// <summary>主数值</summary>
+    public String Value { get; set; }
+
+    /// <summary>趋势描述。可为简单 HTML 片段</summary>
+    public String Trend { get; set; }
+
+    /// <summary>点击跳转地址</summary>
+    public String Url { get; set; }
+}
Modified +1 -1
diff --git a/NewLife.YuqueWeb/Widgets/NavCountWidget.cs b/NewLife.YuqueWeb/Widgets/NavCountWidget.cs
index b092663..fbb86f4 100644
--- a/NewLife.YuqueWeb/Widgets/NavCountWidget.cs
+++ b/NewLife.YuqueWeb/Widgets/NavCountWidget.cs
@@ -12,7 +12,7 @@ public class NavCountWidget : IWidget
     {
         var (enable, total) = Nav.GetCounts();
 
-        return new
+        return new KpiData
         {
             Value = enable.ToString("n0"),
             Trend = $"共 {total} 项",
Modified +1 -1
diff --git a/NewLife.YuqueWeb/Widgets/TodayDocsWidget.cs b/NewLife.YuqueWeb/Widgets/TodayDocsWidget.cs
index cf7395d..f55d4e2 100644
--- a/NewLife.YuqueWeb/Widgets/TodayDocsWidget.cs
+++ b/NewLife.YuqueWeb/Widgets/TodayDocsWidget.cs
@@ -12,7 +12,7 @@ public class TodayDocsWidget : IWidget
     {
         var count = Document.GetTodayCount();
 
-        return new
+        return new KpiData
         {
             Value = count.ToString(),
             Trend = "今日内容更新",
Modified +1 -1
diff --git a/NewLife.YuqueWeb/Widgets/TotalHitsWidget.cs b/NewLife.YuqueWeb/Widgets/TotalHitsWidget.cs
index 80a4b05..47da910 100644
--- a/NewLife.YuqueWeb/Widgets/TotalHitsWidget.cs
+++ b/NewLife.YuqueWeb/Widgets/TotalHitsWidget.cs
@@ -12,7 +12,7 @@ public class TotalHitsWidget : IWidget
     {
         var (_, hits, localHits) = Document.GetScale();
 
-        return new
+        return new KpiData
         {
             Value = hits.ToString("n0"),
             Trend = $"本站点击 {localHits}",
Modified +1 -1
diff --git a/NewLife.YuqueWeb/Widgets/WordCountWidget.cs b/NewLife.YuqueWeb/Widgets/WordCountWidget.cs
index 116f3da..d85cc17 100644
--- a/NewLife.YuqueWeb/Widgets/WordCountWidget.cs
+++ b/NewLife.YuqueWeb/Widgets/WordCountWidget.cs
@@ -14,7 +14,7 @@ public class WordCountWidget : IWidget
         // 超过1万字用万字展示,否则原样
         var value = words >= 10_000 ? (words / 10_000d).ToString("0.0") + "万字" : words.ToString("n0");
 
-        return new
+        return new KpiData
         {
             Value = value,
             Trend = "正文字数合计",