@elf-express/admin-net-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Admin.NET Knowledge MCP Server
2
+
3
+ 為 Admin.NET(Furion + SqlSugar)提供框架知識的 MCP Server,讓 Claude 能直接查詢框架慣例,不需要每次 session 重新說明。
4
+
5
+ ## 提供的工具
6
+
7
+ | 工具 | 說明 |
8
+ | ----------------------- | ----------------------------------------------- |
9
+ | `get_entity_guide` | EntityBase 類別階層、各欄位、如何選擇基礎類別 |
10
+ | `get_service_guide` | IDynamicApiController、BaseService<T>、DTO 命名 |
11
+ | `get_sqlsugar_guide` | AOP 自動填充、Repository 查詢、交易管理 |
12
+ | `get_config_guide` | IConfigurableOptions、JSON 設定檔結構 |
13
+ | `get_plugin_guide` | AppStartup 優先順序、插件結構 |
14
+ | `get_event_guide` | EventSubscribe 訂閱者、發布事件 |
15
+ | `get_attribute_guide` | 所有自訂 Attribute 參考 |
16
+ | `search_knowledge` | 跨主題關鍵字搜尋 |
17
+ | `list_topics` | 列出所有主題 |
18
+
19
+ ## 團隊安裝步驟
20
+
21
+ ### 1. 編譯(第一次或有更新時)
22
+
23
+ ```bash
24
+ cd e:/source/platfrom-admin/.claude/mcp-server
25
+ npm install
26
+ npm run build
27
+ ```
28
+
29
+ ### 2. 設定 Claude Code
30
+
31
+ 在 `C:\Users\{你的名字}\.claude\settings.json` 加入:
32
+
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "admin-net": {
37
+ "command": "node",
38
+ "args": ["e:/source/platfrom-admin/.claude/mcp-server/dist/index.js"]
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ ### 3. 驗證
45
+
46
+ 重新啟動 Claude Code 後,執行 `/mcp` 指令,應看到 `admin-net` 伺服器和 9 個工具。
47
+
48
+ ### 4Tree
49
+
50
+ ```
51
+ .claude/mcp-server/
52
+ ├── src/
53
+ │ ├── index.ts — MCP server 主程式(9 個工具)
54
+ │ └── knowledge/
55
+ │ ├── entity.ts — 實體基礎類別
56
+ │ ├── service.ts — Service/Controller 模式
57
+ │ ├── sqlsugar.ts — ORM + AOP
58
+ │ ├── config.ts — 設定系統
59
+ │ ├── plugin.ts — 插件系統
60
+ │ ├── event.ts — 事件匯流排
61
+ │ └── attributes.ts — 自訂 Attribute
62
+ ├── dist/ — 編譯輸出(已產生)
63
+ ├── package.json
64
+ ├── tsconfig.json
65
+ └── README.md
66
+
67
+ ```
68
+
69
+ ## 更新知識庫
70
+
71
+ 修改 `src/knowledge/` 中的 `.ts` 檔案後,重新執行 `npm run build` 即可。
72
+ 所有人 `git pull` 後重新 build 就能取得最新知識。
package/dist/index.js ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
5
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
+ const zod_1 = require("zod");
7
+ const entity_js_1 = require("./knowledge/entity.js");
8
+ const service_js_1 = require("./knowledge/service.js");
9
+ const sqlsugar_js_1 = require("./knowledge/sqlsugar.js");
10
+ const config_js_1 = require("./knowledge/config.js");
11
+ const plugin_js_1 = require("./knowledge/plugin.js");
12
+ const event_js_1 = require("./knowledge/event.js");
13
+ const attributes_js_1 = require("./knowledge/attributes.js");
14
+ const vue_typescript_js_1 = require("./knowledge/vue-typescript.js");
15
+ const KNOWLEDGE_MAP = {
16
+ entity: entity_js_1.entityGuide,
17
+ service: service_js_1.serviceGuide,
18
+ sqlsugar: sqlsugar_js_1.sqlsugarGuide,
19
+ config: config_js_1.configGuide,
20
+ plugin: plugin_js_1.pluginGuide,
21
+ event: event_js_1.eventGuide,
22
+ attributes: attributes_js_1.attributesGuide,
23
+ "vue-typescript": vue_typescript_js_1.vueTypescriptGuide,
24
+ };
25
+ const TOPIC_DESCRIPTIONS = {
26
+ entity: "實體基礎類別階層(EntityBase, EntityBaseDel, EntityBaseTenant...)",
27
+ service: "Service/Controller 模式(IDynamicApiController, BaseService<T>, CRUD)",
28
+ sqlsugar: "SqlSugar ORM(AOP 自動填充、Repository 查詢、交易管理)",
29
+ config: "設定系統(IConfigurableOptions、JSON 設定檔、Database.json)",
30
+ plugin: "插件系統(AppStartup 優先順序、插件結構、插件間通訊)",
31
+ event: "事件匯流排([EventSubscribe]、IEventSubscriber、發布事件)",
32
+ attributes: "自訂 Attribute([Idempotent]、[DataMask]、[Dict]、[SeedData]...)",
33
+ "vue-typescript": "Vue 3 + TypeScript 採坑記錄(響應式、Element Plus、Vite、Pinia)",
34
+ };
35
+ const server = new mcp_js_1.McpServer({
36
+ name: "admin-net-knowledge",
37
+ version: "1.0.0",
38
+ });
39
+ // 各主題工具(固定回傳對應知識)
40
+ const topicTools = [
41
+ {
42
+ name: "get_entity_guide",
43
+ description: "取得 Admin.NET 實體(Entity)設計指南:EntityBase 類別階層、各屬性說明、如何選擇基礎類別、過濾介面(IDeletedFilter/ITenantIdFilter)",
44
+ topic: "entity",
45
+ },
46
+ {
47
+ name: "get_service_guide",
48
+ description: "取得 Admin.NET Service 設計指南:IDynamicApiController 模式、[ApiDescriptionSettings]、BaseService<T> 泛型 CRUD、DTO 命名慣例",
49
+ topic: "service",
50
+ },
51
+ {
52
+ name: "get_sqlsugar_guide",
53
+ description: "取得 SqlSugar ORM 指南:AOP 自動填充欄位(CreateTime/UpdateTime/TenantId)、Repository 查詢語法、交易管理([UnitOfWork])",
54
+ topic: "sqlsugar",
55
+ },
56
+ {
57
+ name: "get_config_guide",
58
+ description: "取得 Admin.NET 設定系統指南:IConfigurableOptions 用法、JSON 設定檔位置(Database.json、App.json)、多租戶策略",
59
+ topic: "config",
60
+ },
61
+ {
62
+ name: "get_plugin_guide",
63
+ description: "取得 Admin.NET 插件系統指南:[AppStartup(N)] 優先順序、插件目錄結構、ConfigureServices 範例、現有插件清單",
64
+ topic: "plugin",
65
+ },
66
+ {
67
+ name: "get_event_guide",
68
+ description: "取得事件匯流排指南:[EventSubscribe] 訂閱者寫法、IEventSubscriber 必要條件、發布事件語法、系統內建事件常數",
69
+ topic: "event",
70
+ },
71
+ {
72
+ name: "get_attribute_guide",
73
+ description: "取得自訂 Attribute 參考表:[Idempotent] 防重複、[DataMask] 遮罩、[Dict] 字典驗證、[SeedData] 種子資料等 20+ 個 Attribute",
74
+ topic: "attributes",
75
+ },
76
+ {
77
+ name: "get_vue_typescript_guide",
78
+ description: "取得 Vue 3 + TypeScript 採坑記錄:響應式陷阱、Element Plus 常見問題、Vite 模組系統、Pinia 狀態管理、Snowflake ID 精度問題",
79
+ topic: "vue-typescript",
80
+ },
81
+ ];
82
+ // 註冊所有主題工具
83
+ for (const { name, description, topic } of topicTools) {
84
+ server.registerTool(name, { description }, async () => ({
85
+ content: [{ type: "text", text: KNOWLEDGE_MAP[topic] }],
86
+ }));
87
+ }
88
+ // 列出所有主題
89
+ server.registerTool("list_topics", { description: "列出所有可用的知識主題及其簡短說明" }, async () => {
90
+ const lines = Object.entries(TOPIC_DESCRIPTIONS).map(([key, desc]) => `- **${key}**: ${desc}`);
91
+ return {
92
+ content: [
93
+ {
94
+ type: "text",
95
+ text: `# Admin.NET + Vue 知識庫主題\n\n${lines.join("\n")}\n\n使用對應的 get_*_guide 工具取得詳細說明。`,
96
+ },
97
+ ],
98
+ };
99
+ });
100
+ // 跨主題搜尋
101
+ server.registerTool("search_knowledge", {
102
+ description: "在所有知識庫中搜尋關鍵字,回傳包含該關鍵字的相關說明段落",
103
+ inputSchema: { keyword: zod_1.z.string().describe("搜尋關鍵字(中文或英文,例如:TenantId、軟刪除、ref、el-dialog)") },
104
+ }, async ({ keyword }) => {
105
+ const kw = keyword.toLowerCase();
106
+ const results = [];
107
+ for (const [topic, content] of Object.entries(KNOWLEDGE_MAP)) {
108
+ const lines = content.split("\n");
109
+ const matchingBlocks = [];
110
+ let i = 0;
111
+ while (i < lines.length) {
112
+ if (lines[i].toLowerCase().includes(kw)) {
113
+ const start = Math.max(0, i - 2);
114
+ const end = Math.min(lines.length - 1, i + 4);
115
+ matchingBlocks.push(lines.slice(start, end + 1).join("\n"));
116
+ i = end + 1;
117
+ }
118
+ else {
119
+ i++;
120
+ }
121
+ }
122
+ if (matchingBlocks.length > 0) {
123
+ results.push(`## 來自:${topic}(${TOPIC_DESCRIPTIONS[topic]})\n\n${matchingBlocks.slice(0, 3).join("\n---\n")}`);
124
+ }
125
+ }
126
+ if (results.length === 0) {
127
+ return {
128
+ content: [
129
+ {
130
+ type: "text",
131
+ text: `未找到包含「${keyword}」的內容。\n\n可用主題:${Object.keys(KNOWLEDGE_MAP).join("、")}`,
132
+ },
133
+ ],
134
+ };
135
+ }
136
+ return {
137
+ content: [
138
+ {
139
+ type: "text",
140
+ text: `# 搜尋結果:「${keyword}」\n\n${results.join("\n\n---\n\n")}`,
141
+ },
142
+ ],
143
+ };
144
+ });
145
+ async function main() {
146
+ const transport = new stdio_js_1.StdioServerTransport();
147
+ await server.connect(transport);
148
+ }
149
+ main().catch((err) => {
150
+ process.stderr.write(`MCP server error: ${err}\n`);
151
+ process.exit(1);
152
+ });
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.attributesGuide = void 0;
4
+ exports.attributesGuide = `
5
+ # Admin.NET 自訂 Attribute 參考
6
+
7
+ ## 業務邏輯 Attribute
8
+
9
+ ### [IdempotentAttribute] — 冪等請求防重複
10
+ \`\`\`csharp
11
+ [IdempotentAttribute(IntervalTime = 5, Message = "請勿重複提交", ThrowBah = false)]
12
+ public async Task<Result> CreateOrder(OrderInput input)
13
+ {
14
+ // 5 秒內重複呼叫會返回第一次的結果(或拋出例外)
15
+ }
16
+ \`\`\`
17
+ | 參數 | 說明 |
18
+ |------|------|
19
+ | IntervalTime | 防重複間隔秒數(預設 5) |
20
+ | Message | 重複時的錯誤訊息 |
21
+ | ThrowBah | true=拋出例外,false=返回快取結果 |
22
+
23
+ **原理**:組合 路由+UserId+參數 產生 Hash,用分散式快取鎖防重複。
24
+
25
+ ---
26
+
27
+ ### [DataMask] — 資料遮罩
28
+ \`\`\`csharp
29
+ // 手機號碼:134****1234
30
+ [DataMask(3, 4)] // 從第3位開始,遮罩4個字元
31
+ public string PhoneNumber { get; set; }
32
+
33
+ // 身分證:110***********1234
34
+ [DataMask(3, 11)]
35
+ public string IdCard { get; set; }
36
+ \`\`\`
37
+ JSON 序列化時自動套用遮罩,不影響資料庫中的原始資料。
38
+
39
+ ---
40
+
41
+ ### [Dict] — 字典值驗證
42
+ \`\`\`csharp
43
+ // 使用 Enum 驗證
44
+ [Dict(SmsProviderEnum.Aliyun)]
45
+ public SmsProviderEnum? Provider { get; set; }
46
+
47
+ // 使用字典代碼驗證
48
+ [Dict("user_status", AllowNullValue = true)]
49
+ public string Status { get; set; }
50
+ \`\`\`
51
+ | 參數 | 說明 |
52
+ |------|------|
53
+ | AllowNullValue | 是否允許 null(預設 false) |
54
+ | AllowEmptyStrings | 是否允許空字串(預設 false) |
55
+
56
+ ---
57
+
58
+ ### [OwnerUser] — 資料擁有者標記
59
+ \`\`\`csharp
60
+ [OwnerUser]
61
+ public long? CreateUserId { get; set; }
62
+ \`\`\`
63
+ 標記此欄位為資料擁有者 ID,用於資料權限過濾。EntityBase 的 CreateUserId 已套用此 Attribute。
64
+
65
+ ---
66
+
67
+ ## 資料表初始化 Attribute
68
+
69
+ ### 資料庫路由 Attribute
70
+ | Attribute | 用途 |
71
+ |-----------|------|
72
+ | \`[SysTableAttribute]\` | 強制使用主資料庫(不受多租戶影響) |
73
+ | \`[TenantAttribute]\` | 路由至租戶專屬資料庫 |
74
+ | \`[LogTableAttribute]\` | 路由至獨立 Log 資料庫 |
75
+ | \`[IgnoreTableAttribute]\` | SqlSugar 不建立此資料表 |
76
+
77
+ ### 初始化行為 Attribute
78
+ | Attribute | 用途 |
79
+ |-----------|------|
80
+ | \`[SeedDataAttribute]\` | 此實體有對應的種子資料類別 |
81
+ | \`[IncreTableAttribute]\` | 允許增量更新資料表結構(新增欄位) |
82
+ | \`[IncreSeedAttribute]\` | 允許增量更新種子資料(新增記錄) |
83
+ | \`[IgnoreUpdateSeedAttribute]\` | 即使有 IncreTableAttribute 也跳過種子更新 |
84
+ | \`[IgnoreUpdateSeedColumnAttribute]\` | 種子更新時忽略此欄位的比對 |
85
+
86
+ ---
87
+
88
+ ## 匯入/匯出 Attribute
89
+
90
+ ### [ImportDictAttribute] — 匯入時字典轉換
91
+ \`\`\`csharp
92
+ [ImportDictAttribute("gender")] // Excel 匯入時,將"男/女"轉換為對應的字典 Key
93
+ public string Gender { get; set; }
94
+ \`\`\`
95
+
96
+ ### [IgnoreEnumToDictAttribute] — 跳過 Enum 字典轉換
97
+ \`\`\`csharp
98
+ [IgnoreEnumToDictAttribute]
99
+ public SomeEnum InternalStatus { get; set; } // 不加入字典轉換
100
+ \`\`\`
101
+
102
+ ---
103
+
104
+ ## API/回應 Attribute
105
+
106
+ ### [CustomUnifyResultAttribute] — 自訂回應格式
107
+ \`\`\`csharp
108
+ [CustomUnifyResultAttribute(typeof(MyResultProvider))]
109
+ public class SpecialApiService : IDynamicApiController, ITransient
110
+ {
111
+ // 此服務使用自訂回應格式(不使用預設的統一回應)
112
+ }
113
+ \`\`\`
114
+
115
+ ### [CustomJsonPropertyAttribute] — 自訂 JSON 屬性名
116
+ \`\`\`csharp
117
+ [CustomJsonPropertyAttribute("order_no")]
118
+ public string OrderNo { get; set; } // JSON 序列化為 "order_no"
119
+ \`\`\`
120
+
121
+ ---
122
+
123
+ ## 常數分組 Attribute
124
+
125
+ ### [ConstAttribute] — 常數分組
126
+ \`\`\`csharp
127
+ [ConstAttribute("SMS供應商")]
128
+ public class SmsProviderConst
129
+ {
130
+ public const string Aliyun = "aliyun";
131
+ public const string Tencent = "tencent";
132
+ }
133
+ \`\`\`
134
+
135
+ ### [EnumAttribute] — Enum 標記
136
+ \`\`\`csharp
137
+ [EnumAttribute]
138
+ public enum OrderStatusEnum
139
+ {
140
+ [Description("待付款")] Pending = 0,
141
+ [Description("已付款")] Paid = 1,
142
+ [Description("已完成")] Completed = 2
143
+ }
144
+ \`\`\`
145
+
146
+ ---
147
+
148
+ ## Attribute 目錄
149
+ 所有自訂 Attribute 位於:\`Admin.NET.Core/Attribute/\`
150
+
151
+ 常用 Attribute 快速查找:
152
+ - 防重複提交 → IdempotentAttribute
153
+ - 手機/身分證遮罩 → DataMaskAttribute
154
+ - 欄位字典驗證 → DictAttribute
155
+ - 路由至主DB → SysTableAttribute
156
+ - 有種子資料 → SeedDataAttribute
157
+ - 增量更新表結構 → IncreTableAttribute
158
+ `;
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configGuide = void 0;
4
+ exports.configGuide = `
5
+ # Admin.NET 設定系統指南
6
+
7
+ ## IConfigurableOptions 模式
8
+
9
+ Furion 自動將 JSON 設定檔綁定到實作 IConfigurableOptions 的類別,無需手動 Configure<T>()。
10
+
11
+ ### 基本模式
12
+ \`\`\`csharp
13
+ // 設定類別(放在 Admin.NET.Core/Option/ 或 Admin.NET.Application/Option/)
14
+ public sealed class SMSOptions : IConfigurableOptions
15
+ {
16
+ public int VerifyCodeExpireSeconds { get; set; } = 60; // 預設值
17
+ public string Provider { get; set; }
18
+ public AliyunSettings Aliyun { get; set; }
19
+ }
20
+
21
+ // JSON 檔案名稱需與類別名稱去掉 Options 後綴對應
22
+ // SMSOptions → SMS.json(位於 Admin.NET.Application/Configuration/SMS.json)
23
+ \`\`\`
24
+
25
+ ### 需要後處理的模式(PostConfigure)
26
+ \`\`\`csharp
27
+ public sealed class DbConnectionOptions : IConfigurableOptions<DbConnectionOptions>
28
+ {
29
+ public List<DbConnectionConfig> ConnectionConfigs { get; set; }
30
+
31
+ public void PostConfigure(DbConnectionOptions options, IConfiguration configuration)
32
+ {
33
+ // JSON 載入後的自訂處理
34
+ foreach (var config in options.ConnectionConfigs)
35
+ {
36
+ if (config.ConfigId == null)
37
+ config.ConfigId = SqlSugarConst.MainConfigId;
38
+ }
39
+ }
40
+ }
41
+ \`\`\`
42
+
43
+ ### 在 Service 中使用
44
+ \`\`\`csharp
45
+ public class SmsService : IDynamicApiController, ITransient
46
+ {
47
+ private readonly SMSOptions _smsOptions;
48
+
49
+ public SmsService(IOptions<SMSOptions> smsOptions)
50
+ {
51
+ _smsOptions = smsOptions.Value;
52
+ }
53
+ }
54
+ \`\`\`
55
+
56
+ ## 設定檔位置
57
+
58
+ 所有 JSON 設定檔放在 \`Admin.NET.Application/Configuration/\`:
59
+
60
+ | 檔案 | 說明 | 對應 Options 類別 |
61
+ |------|------|------------------|
62
+ | Database.json | 資料庫連線、DB 類型 | DbConnectionOptions |
63
+ | Cache.json | Redis 或記憶體快取 | CacheOptions |
64
+ | App.json | Swagger、插件、CORS、虛擬路徑 | AppOptions |
65
+ | JWT.json | Token 設定(有效期、金鑰) | JWTSettingsOptions |
66
+ | SMS.json | 簡訊供應商設定 | SMSOptions |
67
+ | Alipay.json | 支付寶設定 | AlipayOptions |
68
+ | Wechat.json | 微信設定 | WechatOptions |
69
+ | Logging.json | Serilog 設定 | — |
70
+ | EventBus.json | 事件匯流排(記憶體/Redis/RabbitMQ) | — |
71
+
72
+ ## Database.json 結構
73
+
74
+ \`\`\`json
75
+ {
76
+ "DbConnection": {
77
+ "EnableConsoleSql": true,
78
+ "SuperAdminIgnoreIDeletedFilter": false,
79
+ "ConnectionConfigs": [
80
+ {
81
+ "ConfigId": "0",
82
+ "DbNickName": "主資料庫",
83
+ "DbType": 0,
84
+ "ConnectionString": "Server=.;Database=AdminNET;...",
85
+ "DbSettings": {
86
+ "EnableInitDb": true,
87
+ "EnableDiffLog": false,
88
+ "EnableUnderLine": false
89
+ },
90
+ "TableSettings": {
91
+ "EnableInitTable": true,
92
+ "EnableIncreTable": true
93
+ },
94
+ "SeedSettings": {
95
+ "EnableInitSeed": true,
96
+ "EnableIncreSeed": false
97
+ }
98
+ }
99
+ ]
100
+ }
101
+ }
102
+ \`\`\`
103
+
104
+ ## DbType 對應
105
+
106
+ | 值 | 資料庫 |
107
+ |----|--------|
108
+ | 0 | MySql |
109
+ | 1 | SqlServer |
110
+ | 2 | Sqlite |
111
+ | 3 | Oracle |
112
+ | 4 | PostgreSQL |
113
+ | 5 | Dm(達夢) |
114
+ | 6 | Kdbndp(人大金倉) |
115
+
116
+ ## TenantType 多租戶策略
117
+
118
+ | 值 | 策略 | 說明 |
119
+ |----|------|------|
120
+ | Id | 欄位隔離 | 同一資料庫,用 TenantId 欄位區分 |
121
+ | Schema | Schema 隔離 | 同一資料庫,不同 Schema |
122
+ | Database | 資料庫隔離 | 完全獨立的資料庫 |
123
+
124
+ ## App.json 關鍵設定
125
+
126
+ \`\`\`json
127
+ {
128
+ "App": {
129
+ "ExternalAssemblies": ["plugins"], // 插件目錄
130
+ "CorsUrls": ["http://localhost:9100"], // 允許的 CORS 來源
131
+ "VirtualFileServerOptions": [...], // 虛擬路徑對應
132
+ "UnifyResultSettings": { // 統一回應格式設定
133
+ "DefaultSuccessCode": 200
134
+ }
135
+ }
136
+ }
137
+ \`\`\`
138
+
139
+ ## 讀取任意設定(不透過 Options 類別)
140
+
141
+ \`\`\`csharp
142
+ // 直接讀取設定值
143
+ var value = App.GetConfig<string>("App:CorsUrls:0");
144
+
145
+ // 取得設定區段
146
+ var section = App.Configuration.GetSection("Database:ConnectionConfigs");
147
+ \`\`\`
148
+
149
+ ## 檔案位置
150
+ - Options 類別:\`Admin.NET.Core/Option/\`
151
+ - JSON 設定檔:\`Admin.NET.Application/Configuration/\`
152
+ `;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.entityGuide = void 0;
4
+ exports.entityGuide = `
5
+ # Admin.NET 實體(Entity)設計指南
6
+
7
+ ## 基礎類別階層
8
+
9
+ 所有實體都使用 Snowflake ID 作為主鍵(long 型別,由 YitIdHelper.NextId() 自動產生)。
10
+
11
+ \`\`\`
12
+ EntityBaseId — 只有 Id(long)
13
+ └─ EntityBase — + 審計欄位(CreateTime, UpdateTime, 建立/更新者)
14
+ ├─ EntityBaseDel — + 軟刪除(IsDelete, DeleteTime)
15
+ ├─ EntityBaseOrg — + 組織(OrgId)
16
+ ├─ EntityBaseTenant — + 租戶(TenantId)
17
+ ├─ EntityBaseTenantId — TenantId 別名變體
18
+ ├─ EntityBaseOrgDel — Org + 軟刪除
19
+ ├─ EntityBaseTenantDel — Tenant + 軟刪除
20
+ ├─ EntityBaseTenantOrg — Tenant + Org
21
+ └─ EntityBaseTenantOrgDel — 所有功能(最完整)
22
+ \`\`\`
23
+
24
+ ## 各基礎類別屬性
25
+
26
+ ### EntityBase(所有實體共有)
27
+ | 屬性 | 型別 | 說明 |
28
+ |------|------|------|
29
+ | Id | long | Snowflake ID,AOP 自動生成 |
30
+ | CreateTime | DateTime | 建立時間,AOP Insert 時填入 DateTime.Now |
31
+ | UpdateTime | DateTime? | 更新時間,AOP Update 時填入 DateTime.Now |
32
+ | CreateUserId | long? | 建立者 ID,從 ClaimConst.UserId 取得 |
33
+ | CreateUserName | string | 建立者姓名,從 ClaimConst.RealName 取得 |
34
+ | UpdateUserId | long? | 更新者 ID,AOP 自動填入 |
35
+ | UpdateUserName | string | 更新者姓名,AOP 自動填入 |
36
+
37
+ ### EntityBaseDel(軟刪除)
38
+ | 屬性 | 型別 | 說明 |
39
+ |------|------|------|
40
+ | IsDelete | bool | 是否刪除,預設 false |
41
+ | DeleteTime | DateTime? | 刪除時間,IsDelete=true 時由 AOP 填入 |
42
+
43
+ ### EntityBaseOrg
44
+ | 屬性 | 型別 | 說明 |
45
+ |------|------|------|
46
+ | OrgId | long | 組織 ID,用於資料權限範圍控管 |
47
+
48
+ ### EntityBaseTenant
49
+ | 屬性 | 型別 | 說明 |
50
+ |------|------|------|
51
+ | TenantId | long? | 租戶 ID,AOP Insert 時從 ClaimConst.TenantId 填入 |
52
+
53
+ ## 如何選擇基礎類別
54
+
55
+ - **一般業務資料**(有審計需求):→ \`EntityBase\`
56
+ - **可軟刪除的業務資料**:→ \`EntityBaseDel\`
57
+ - **需要組織隔離**(資料權限):→ \`EntityBaseOrgDel\` 或 \`EntityBaseOrg\`
58
+ - **多租戶資料**:→ \`EntityBaseTenantDel\` 或 \`EntityBaseTenant\`
59
+ - **完整功能(多租戶 + 組織 + 軟刪除)**:→ \`EntityBaseTenantOrgDel\`
60
+ - **系統配置/日誌(不需審計)**:→ \`EntityBaseId\`
61
+
62
+ ## 自動過濾介面
63
+
64
+ 實體實作以下介面後,SqlSugar AOP 會自動套用 WHERE 條件:
65
+
66
+ \`\`\`csharp
67
+ public interface IDeletedFilter { bool IsDelete { get; set; } } // 自動加 WHERE IsDelete=0
68
+ public interface ITenantIdFilter { long? TenantId { get; set; } } // 自動加 WHERE TenantId=目前租戶
69
+ public interface IOrgIdFilter { long OrgId { get; set; } } // 自動加組織資料權限過濾
70
+ \`\`\`
71
+
72
+ **注意**:EntityBaseDel 已實作 IDeletedFilter,EntityBaseTenant 已實作 ITenantIdFilter,無需手動實作。
73
+
74
+ ## 實體路由(資料庫選擇)
75
+
76
+ SqlSugar Repository 會依照以下 Attribute 決定連接哪個資料庫:
77
+
78
+ | Attribute | 用途 |
79
+ |-----------|------|
80
+ | \`[SysTableAttribute]\` | 強制使用主資料庫連線 |
81
+ | \`[TenantAttribute]\` | 路由至租戶專屬資料庫 |
82
+ | \`[LogTableAttribute]\` | 路由至獨立 Log 資料庫 |
83
+ | \`[IgnoreTableAttribute]\` | 不建立資料表 |
84
+
85
+ ## 初始化相關 Attribute
86
+
87
+ | Attribute | 說明 |
88
+ |-----------|------|
89
+ | \`[SeedDataAttribute]\` | 標記此實體有種子資料 |
90
+ | \`[IncreTableAttribute]\` | 允許增量更新資料表(新增欄位) |
91
+ | \`[IncreSeedAttribute]\` | 允許增量更新種子資料 |
92
+ | \`[IgnoreUpdateSeedAttribute]\` | 跳過種子資料更新 |
93
+
94
+ ## 範例
95
+
96
+ \`\`\`csharp
97
+ // 一般業務資料(有軟刪除)
98
+ [SugarTable("sys_order", "訂單表")]
99
+ public class SysOrder : EntityBaseDel
100
+ {
101
+ [SugarColumn(ColumnDescription = "訂單編號", Length = 32)]
102
+ public string OrderNo { get; set; }
103
+
104
+ [SugarColumn(ColumnDescription = "金額", ColumnDataType = "decimal(18,2)")]
105
+ public decimal Amount { get; set; }
106
+ }
107
+
108
+ // 多租戶資料(含組織 + 軟刪除)
109
+ [SugarTable("biz_project", "專案表")]
110
+ public class BizProject : EntityBaseTenantOrgDel
111
+ {
112
+ [SugarColumn(ColumnDescription = "專案名稱", Length = 100)]
113
+ public string ProjectName { get; set; }
114
+ }
115
+ \`\`\`
116
+
117
+ ## 檔案位置
118
+ - 基礎類別:\`Admin.NET.Core/Entity/EntityBase.cs\`
119
+ - 過濾介面:\`Admin.NET.Core/Entity/IEntityFilter.cs\`
120
+ `;