NewLife/NewLife.WeiXin

微信对接项目
大石头 authored at 2026-02-27 21:01:48
73a4254
Tree
0 Parent(s)
Summary: 25 changed files with 1791 additions and 0 deletions.
Added +112 -0
Added +406 -0
Added +506 -0
Added +32 -0
Added +30 -0
Added +31 -0
Added +26 -0
Added +0 -0
Added +0 -0
Added +21 -0
Added +52 -0
Added +59 -0
Added +11 -0
Added +9 -0
Added +18 -0
Added +48 -0
Added +30 -0
Added +58 -0
Added +13 -0
Added +229 -0
Added +28 -0
Added +12 -0
Added +23 -0
Added +11 -0
Added +26 -0
Added +112 -0
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..0f826be
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,112 @@
+# EditorConfig is awesome:http://EditorConfig.org
+# https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
+
+# top-most EditorConfig file
+root = true
+
+# Don't use tabs for indentation.
+[*]
+indent_style = space
+# (Please don't specify an indent_size here; that has too many unintended consequences.)
+
+# Code files
+[*.{cs,csx,vb,vbx}]
+indent_size = 4
+insert_final_newline = false
+charset = utf-8-bom
+end_of_line = crlf
+
+# Xml project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# Xml config files
+[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
+indent_size = 2
+
+# JSON files
+[*.json]
+indent_size = 2
+
+# Dotnet code style settings:
+[*.{cs,vb}]
+# Sort using and Import directives with System.* appearing first
+dotnet_sort_system_directives_first = true
+
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = flush_left
+
+#csharp_space_after_cast = true
+#csharp_space_after_keywords_in_control_flow_statements = true
+#csharp_space_between_method_declaration_parameter_list_parentheses = true
+#csharp_space_between_method_call_parameter_list_parentheses = true
+#csharp_space_between_parentheses = control_flow_statements, type_casts
+
+# 单行放置代码
+csharp_preserve_single_line_statements = true
+csharp_preserve_single_line_blocks = true
+
+# Avoid "this." and "Me." if not necessary
+dotnet_style_qualification_for_field = false:warning
+dotnet_style_qualification_for_property = false:warning
+dotnet_style_qualification_for_method = false:warning
+dotnet_style_qualification_for_event = false:warning
+
+# Use language keywords instead of framework type names for type references
+dotnet_style_predefined_type_for_locals_parameters_members = false:suggestion
+dotnet_style_predefined_type_for_member_access = false:suggestion
+#dotnet_style_require_accessibility_modifiers = for_non_interface_members:none/always:suggestion
+
+# Suggest more modern language features when available
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+
+# CSharp code style settings:
+[*.cs]
+# Prefer "var" everywhere
+csharp_style_var_for_built_in_types = true:warning
+csharp_style_var_when_type_is_apparent = true:warning
+csharp_style_var_elsewhere = true:warning
+
+# Prefer method-like constructs to have a block body
+csharp_style_expression_bodied_methods = when_on_single_line:suggestion
+csharp_style_expression_bodied_constructors = when_on_single_line:suggestion
+csharp_style_expression_bodied_operators = when_on_single_line:suggestion
+
+# Prefer property-like constructs to have an expression-body
+csharp_style_expression_bodied_properties = true:suggestion
+csharp_style_expression_bodied_indexers = true:suggestion
+#csharp_style_expression_bodied_accessors = true:suggestion
+
+# Suggest more modern language features when available
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_pattern_local_over_anonymous_function = true:suggestion
+
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+
+# 单行不需要大括号
+csharp_prefer_braces = false:suggestion
+
+# Newline settings
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+
+[*.md]
+trim_trailing_whitespace = false
\ No newline at end of file
Added +406 -0
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000..3c5b1dd
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,406 @@
+# NewLife Copilot 协作指令
+
+本说明适用于新生命团队(NewLife)及其全部开源/衍生项目,规范 Copilot 及类似智能助手在 C#/.NET 项目中的协作行为。
+
+> 目标:把"每次请求必须携带的通用规则"控制在可接受体积;组件/业务专项流程放在 `.github/instructions/`,按需读取。
+
+---
+
+## 1. 核心原则
+
+| 原则 | 说明 |
+|------|------|
+| **提效** | 减少机械样板,聚焦业务/核心算法 |
+| **一致** | 风格、结构、命名、API 行为稳定 |
+| **可控** | 限制改动影响面,可审计,兼容友好 |
+| **可靠** | 先检索再生成,不虚构,不破坏现有合约 |
+| **主动** | 发现问题主动修复,不回避合理优化 |
+
+---
+
+## 2. 适用范围
+
+- 含 NewLife 组件或衍生的全部 C#/.NET 仓库
+- 不含纯前端/非 .NET/市场文案
+- 存在本文件 → 必须遵循
+
+---
+
+## 3. 组件专用指令索引(按需加载)
+
+以下专用指令**仅在相关任务时**才需要读取,避免每次请求都携带大段流程/示例。
+
+### 3.1 XCode / Cube(数据库 & Web 快速开发)
+
+当任务涉及以下任一信号时,请**先搜索并检查当前仓库** `.github/instructions/xcode.instructions.md` **是否存在**,若存在则读取并遵循:
+
+- 需求包含:XCode/Cube/魔方/实体生成/模型 XML/数据类库/数据库 CRUD/Controller 生成/`xcodetool`/`xcode` 命令
+- 解决方案/项目中出现:`NewLife.XCode` 包引用
+- 存在:`Model.xml`、`*.xcode.xml`、`*.Data.csproj`(或项目名以 `.Data` 结尾)
+- 代码出现命名空间/类型:`XCode.*`、`Entity`(XCode 实体基类)、XCode 相关特性/接口
+- **用户提到修改任意 `.xml` 文件**(如 `member.xml`、`area.xml` 等配置文件),应**主动搜索** `xcode.instructions.md` 判断是否需要引入
+
+**主动检测策略**:当用户提及 XML 文件修改时,即使未明确提到 XCode 关键字,也应先用 `file_search` 搜索 `xcode.instructions.md`,若存在则读取,以确定该 XML 文件是否属于 XCode/Cube 体系。
+
+未满足以上条件时,**不要**引入 XCode/Cube 初始化流程,避免干扰其它仓库的常规开发。
+
+---
+
+## 4. 工作流
+
+```
+需求分类 → 检索 → 评估 → 设计 → 实施 → 验证 → 说明
+```
+
+1. **需求分类**:功能/修复/性能/重构/文档
+2. **检索**:相关类型、目录、方法、已有扩展/工具(**优先复用**)
+3. **评估**:是否公共 API?是否性能热点?**是否存在潜在问题?**
+4. **设计**:列出改动点 + 兼容/降级策略
+5. **实施**:
+   - 完成用户请求的核心任务
+   - **顺带修复**发现的明显缺陷(资源泄漏、空引用、逻辑错误)
+   - **顺带优化**可简化的重复代码
+   - 保留原注释与结构,除非注释本身有误
+6. **验证**:
+   - 代码变更:必须编译通过;运行相关单元测试(未找到需说明)
+   - 仅文档变更(未修改任何代码文件):可跳过编译与单元测试
+7. **说明**:变更摘要/影响范围/风险点
+
+### 4.1 主动优化原则
+
+当用户请求分析或优化代码时,**应主动**:
+
+| 类型 | 行动 |
+|------|------|
+| **架构梳理** | 梳理代码架构并进行重构,让代码结构更清晰易懂 |
+| **语法现代化** | 使用最新的 C# 语法来简化代码,提升可读性 |
+| **缺陷修复** | 资源泄漏、空引用风险、并发问题、逻辑错误 → 直接修复,让代码更健壮 |
+| **性能优化** | 无用分配、重复计算、可池化资源 → 通过缓存减少耗时的重复计算 |
+| **代码简化** | 重复代码提取、冗余判断合并、现代语法替换 → 在不影响可读性前提下简化 |
+| **注释完善** | 补充类、接口、属性、方法头部的注释,以及方法内部重要代码的注释 |
+| **架构参考** | 参考网络上同类功能的优秀架构,给出架构调整建议 |
+
+**架构调整策略**:
+- **改动较小**:直接调整,完成后说明变更内容
+- **改动较大**:先列出调整方案,询问用户意见,待确认后再修改
+
+**不应过度保守**:
+- ❌ 仅添加注释而忽略明显的代码问题
+- ❌ 发现资源泄漏却不修复
+- ❌ 看到重复代码却不提取
+- ❌ 用户要求优化时只做表面工作
+
+**保持谨慎的场景**:
+- 公共 API 签名变更 → 需说明兼容性影响
+- 性能关键路径 → 需有依据或说明推理
+- 大范围重构 → 需先与用户确认范围
+
+### 4.2 防御性注释规则
+
+在旧有代码中,经常可以看到**被注释掉的代码**,这些注释代码前面通常带有说明文字。
+
+**这些是防御性注释**:
+- 记录了过去曾经踩过的坑
+- 目的是告诉后来人不要按照注释代码去写,否则会有问题
+- **禁止删除此类防御性注释**,用于警示后人
+
+**识别特征**:
+```csharp
+// 曾经尝试过 xxx 方案,但会导致 yyy 问题
+// var result = DoSomethingWrong();
+
+// 不要使用 xxx,否则会造成 yyy
+// await client.SendAsync(data);
+
+// 这里不能用 xxx,因为 yyy
+// stream.Flush();
+```
+
+**处理原则**:
+- ✅ 保留这类带说明的注释代码
+- ✅ 可以补充更详细的说明,解释为什么不能这样做
+- ❌ 不要删除这类防御性注释
+- ❌ 不要尝试"恢复"这些被注释的代码
+
+---
+
+## 5. 编码规范
+
+### 5.1 基础规范
+
+| 项目 | 规范 |
+|------|------|
+| 语言版本 | `<LangVersion>latest</LangVersion>`,所有目标框架均使用最新 C# 语法 |
+| 命名空间 | file-scoped namespace |
+| 类型名 | **必须**使用 .NET 正式名 `String`/`Int32`/`Boolean` 等,避免 `string`/`int`/`bool` |
+| 兼容性 | 代码需兼容 .NET 4.5+;**禁止**使用 `ArgumentNullException.ThrowIfNull`,改用 `if (value == null) throw new ArgumentNullException(nameof(value));` |
+| 单文件 | 每文件一个主要公共类型;较大平台差异使用 `partial` |
+
+### 5.2 命名规范
+
+| 成员类型 | 命名规则 | 示例 |
+|---------|---------|------|
+| 类型/公共成员 | PascalCase | `UserService`、`GetName()` |
+| 参数/局部变量 | camelCase | `userName`、`count` |
+| 私有字段(实例/静态) | `_camelCase` | `_cache`、`_instance` |
+| 属性/方法(实例/静态) | PascalCase | `Name`、`Default`、`Create()` |
+| 扩展方法类 | `xxxHelper` 或 `xxxExtensions` | `StringHelper`、`CollectionExtensions` |
+
+### 5.3 代码风格
+
+```csharp
+// ✅ 单行 if:单语句且整行不过长时同行
+if (value == null) return;
+if (key == null) throw new ArgumentNullException(nameof(key));
+
+// ✅ 单行 if:语句较长时另起一行
+if (value == null)
+    throw new ArgumentNullException(nameof(value), "Value cannot be null");
+
+// ✅ 多分支单语句:不加花括号
+if (count > 0)
+    DoSomething();
+else
+    DoOther();
+
+// ✅ 循环必须保留花括号(即使单语句)
+foreach (var item in list)
+{
+    Process(item);
+}
+```
+
+### 5.4 Region 组织结构
+
+较长的类使用 `#region` 分段组织,顺序为:`属性` → `静态`(如有)→ `构造` → `方法` → `辅助`(如有)→ `日志`。
+
+**日志 Region 规则**:
+- 类代码中如果带有 `ILog Log { get; set; }` 和 `WriteLog` 方法
+- **必须放在类代码的最后**
+- **必须用名为"日志"的 region 包裹**
+- 不要放在"辅助" region 中,应单独作为"日志" region
+
+### 5.5 现代 C# 语法
+
+优先使用最新语法(switch 表达式、模式匹配、目标类型 `new`、record 等),即使目标框架是 net45。
+
+### 5.6 集合表达式
+
+优先使用集合表达式 `[]` 初始化集合:`List<String> Tags { get; set; } = [];`
+
+### 5.7 Null 条件运算符
+
+优先使用 `?.` / `??` 简化空值检查:`span?.AppendTag("test");` `var name = user?.Profile?.Name ?? "";`
+
+---
+
+## 6. 多目标框架
+
+NewLife 支持 `net45` 到 `net10`,常用条件符号:`NETFRAMEWORK`、`NETSTANDARD2_0`、`NETCOREAPP`、`NET5_0_OR_GREATER`、`NET6_0_OR_GREATER`、`NET8_0_OR_GREATER`。
+
+新增 API 时需评估各框架兼容性,必要时提供降级实现。
+
+---
+
+## 7. 文档注释
+
+| 规则 | 说明 |
+|------|------|
+| `<summary>` | **必须同一行闭合**,简短描述方法用途 |
+| `<param>` | **必须为每个参数添加**,无论方法可见性如何 |
+| `<returns>` | 有返回值时必须添加 |
+| `<remarks>` | 复杂方法可增加详细说明(可多行) |
+| 覆盖范围 | `public`/`protected` 成员必须注释;`private`/`internal` 建议添加 |
+| `[Obsolete]` | 必须包含迁移建议 |
+
+**正确示例**:`/// <summary>获取名称</summary>` `/// <param name="id">编号</param>`
+
+**禁止**:`<summary>` 拆成多行;缺少 `<param>`;有参数但无 param 标签。
+
+---
+
+## 8. 异步与性能
+
+| 规范 | 说明 |
+|------|------|
+| 方法命名 | 异步方法后缀 `Async` |
+| ConfigureAwait | 库内部默认 `ConfigureAwait(false)` |
+| 高频路径 | 优先对象池/`ArrayPool<T>`/`Span`,避免多余分配 |
+| 反射/Linq | 仅用于非热点路径;热点使用手写循环/缓存 |
+| 池化资源 | 明确获取/归还;异常分支不遗失归还 |
+
+**内置工具优先**:`Pool.StringBuilder`、`Runtime.TickCount64`、`ToInt()`/`ToBoolean()` 等扩展方法。
+
+---
+
+## 9. 日志与追踪
+
+规则:若类包含 `ILog Log` 与 `WriteLog`,必须放在类末尾,并用名为"日志"的 `#region` 包裹;关键过程可使用 `Tracer?.NewSpan()` 埋点。
+
+---
+
+## 10. 错误处理
+
+- **精准异常类型**:`ArgumentNullException`/`InvalidOperationException` 等
+- **参数校验**:空/越界/格式
+- **TryXxx 模式**:不用异常作常规分支
+- **类型转换**:优先使用 `ToInt()`/`ToBoolean()` 等扩展方法
+- **对外异常**:不暴露内部实现/路径
+
+---
+
+## 11. 测试规范
+
+| 项目 | 规范 |
+|------|------|
+| 框架 | xUnit |
+| 命名 | `{ClassName}Tests` |
+| 描述 | `[DisplayName("中文描述意图")]` |
+| IO | 使用临时目录;端口用 0/随机 |
+| 覆盖 | 正常/边界/异常/并发(必要时) |
+
+### 测试执行策略
+
+1. 优先检索 `{ClassName}` 引用,若落入测试项目则运行
+2. 未命中则查找 `{ClassName}Tests.cs`
+3. **未发现相关测试需明确说明**,不自动创建测试项目
+
+---
+
+## 12. NuGet 发布规范
+
+| 类型 | 命名规则 | 示例 |
+|------|---------|------|
+| 正式版 | `{主版本}.{子版本}.{年}.{月日}` | `11.9.2025.0701` |
+| 测试版 | `{主版本}.{子版本}.{年}.{月日}-beta{时分}` | `11.9.2025.0701-beta0906` |
+
+- **正式版**:每月月初发布
+- **测试版**:提交代码到 GitHub 时自动发布
+
+---
+
+## 13. Markdown 文档规范
+
+| 项目 | 规范 |
+|------|------|
+| 文件编码 | **必须** UTF-8,**禁止** GB2312/GBK/UTF-8 BOM |
+| 默认存放 | 代码库根目录下的 `Doc` 目录 |
+| 文件命名 | 优先**中文文件名**,简洁描述内容 |
+
+**注意**:已有文件**必须先读取**再增量修改,**禁止直接覆盖**。
+
+---
+
+## 14. Copilot 行为守则
+
+### 必须
+
+- 简体中文回复
+- 输出前检索现有实现,**禁止重复造轮子**
+- 先列方案再实现
+- 标记不确定上下文为"需查看文件"
+- **发现明显缺陷时主动修复**(资源泄漏、空引用、逻辑错误)
+- **用户要求优化时深入分析**,不做表面工作
+
+### 鼓励
+
+- 提取重复代码为公共方法
+- 简化冗余的条件判断
+- 使用现代 C# 语法改进可读性
+- 补充缺失的资源释放逻辑
+- 修正错误或过时的注释
+
+### 禁止
+
+- 虚构 API/文件/类型
+- 伪造测试结果/性能数据
+- 擅自删除公共/受保护成员
+- 擅自删除已有代码注释(除非注释本身错误)
+- **删除防御性注释**(带说明的注释代码,记录历史踩坑经验)
+- 仅删除空白行制造"格式优化"提交
+- 删除循环体的花括号
+- 将 `<summary>` 拆成多行
+- 将 `String`/`Int32` 改为 `string`/`int`
+- 新增外部依赖(除非说明理由并给出权衡)
+- 在热点路径添加未缓存反射/复杂 Linq
+- 输出敏感凭据/内部地址
+- **发现问题却视而不见**
+- **用户要求优化时仅做注释/测试等表面工作**
+
+---
+
+## 15. 变更说明模板
+
+提交或答复需包含:
+
+```markdown
+## 概述
+做了什么 / 为什么
+
+## 影响
+- 公共 API:是/否
+- 性能影响:无/有(说明)
+
+## 兼容性
+降级策略 / 条件编译点
+
+## 风险
+潜在回归 / 性能开销
+
+## 后续
+是否补测试 / 文档
+```
+
+---
+
+## 16. 术语说明
+
+| 术语 | 定义 |
+|------|------|
+| **热点路径** | 经性能分析或高频调用栈确认的关键执行段 |
+| **基线** | 变更前的功能/性能参考数据 |
+| **顺带修复** | 在完成主任务过程中,修复发现的相关问题 |
+| **防御性注释** | 被注释掉的代码,前面带有说明,记录历史踩坑经验,用于警示后人 |
+
+---
+
+## 17. 代码优化检查清单
+
+当进行代码优化时,按以下清单逐项检查:
+
+### 架构与结构
+- [ ] 代码架构是否清晰?是否需要重构?
+- [ ] 类的职责是否单一?是否需要拆分?
+- [ ] 是否有重复代码可以提取为公共方法?
+- [ ] Region 组织是否符合规范(属性→静态→构造→方法→辅助→日志)?
+
+### 语法现代化
+- [ ] 是否可以使用更简洁的 C# 语法?(switch 表达式、模式匹配等)
+- [ ] 集合初始化是否使用了集合表达式 `[]`?
+- [ ] 是否可以使用 null 条件运算符 `?.` 简化代码?
+
+### 健壮性
+- [ ] 是否存在空引用风险?
+- [ ] 资源是否正确释放?(IDisposable、流、连接等)
+- [ ] 异常处理是否完善?
+- [ ] 并发场景是否线程安全?
+
+### 性能
+- [ ] 是否存在可以缓存的重复计算?
+- [ ] 是否有不必要的对象分配?
+- [ ] 热点路径是否避免了反射和复杂 Linq?
+- [ ] 是否使用了对象池/ArrayPool 等池化技术?
+
+### 注释与文档
+- [ ] 类、接口是否有 `<summary>` 注释?
+- [ ] 公共方法是否有完整的参数和返回值注释?
+- [ ] 方法内重要逻辑是否有注释说明?
+- [ ] 防御性注释是否保留?
+
+### 日志
+- [ ] `ILog Log` 和 `WriteLog` 是否放在类的最后?
+- [ ] 是否用名为"日志"的 region 包裹?
+
+---
+
+(完)
Added +506 -0
diff --git a/.github/instructions/xcode.instructions.md b/.github/instructions/xcode.instructions.md
new file mode 100644
index 0000000..dcd5984
--- /dev/null
+++ b/.github/instructions/xcode.instructions.md
@@ -0,0 +1,506 @@
+# XCode 协作指令
+
+本指令面向新生命团队(NewLife)开源数据中间件 XCode,帮助 Copilot 在 .NET 项目中正确使用 XCode 进行数据建模和实体操作。
+
+---
+
+## 1. XCode 定位与边界
+
+### 1.1 技术栈定位
+
+```
+NewLife.Core(基础库)
+       ↓
+   NewLife.XCode(数据中间件)← 本指令
+       ↓
+   NewLife.Cube(Web 快速开发框架)→ cube.instructions.md
+```
+
+### 1.2 职责边界
+
+| 层级 | 职责 | 指令文件 |
+|------|------|---------|
+| **NewLife.Core** | 基础扩展、日志、缓存、网络等 | `copilot-instructions.md` |
+| **NewLife.XCode** | 数据建模、ORM、实体增删改查、数据库操作 | 本指令 |
+| **NewLife.Cube** | Web 管理后台、控制器、视图、权限 | `cube.instructions.md` |
+
+### 1.3 本指令覆盖范围
+
+**包含**:
+- 数据模型设计(Model.xml)
+- 实体类生成与使用
+- 数据库 CRUD 操作
+- 项目初始化与 XCode 接入
+
+**不包含**(由 cube.instructions.md 负责):
+- Web 控制器逻辑
+- 视图与前端交互
+- 权限管理配置
+- 魔方区域深度定制
+
+---
+
+## 2. 使用场景与快速入口
+
+### 2.1 场景一:已有项目接入 XCode
+
+1. 引入 NuGet 包:`dotnet add package NewLife.XCode`
+2. 创建或编辑 `Model.xml` 进行数据建模
+3. 执行 `xcode` 命令生成实体类
+4. 在业务代码中使用实体类进行数据操作
+
+### 2.2 场景二:从零创建新项目
+
+1. 安装模板:`dotnet new install NewLife.Templates`
+2. 创建数据类库:`dotnet new xcode -n {系统名}.Data`
+3. 创建应用项目:
+   - Web 应用:`dotnet new cube -n {系统名}Web`
+   - 控制台应用:`dotnet new nconsole -n {系统名}App`
+4. 编辑 `Model.xml` 进行数据建模
+5. 执行 `xcode` 生成实体类
+
+### 2.3 核心工作流
+
+```
+理解业务需求 → 数据建模(Model.xml) → 生成实体类(xcode) → 编写业务代码
+```
+
+**关键点**:无论哪种场景,核心都是 **充分理解业务需求,在 Model.xml 中设计合理的数据表结构**。
+
+---
+
+## 3. 环境准备
+
+### 3.1 前置要求
+
+```powershell
+# 检查 .NET SDK(要求 8.0+)
+dotnet --version
+
+# 安装全局工具 xcodetool
+dotnet tool install xcodetool -g
+```
+
+### 3.2 模板版本检查
+
+NewLife.Templates 模板会持续更新,使用前需检查版本:
+
+```powershell
+# 查看模板详情
+dotnet new details NewLife.Templates
+```
+
+**判定规则**:输出包含类似 `包版本: 1.1.2025.820-beta1836`
+- 其中 `1.1.2025.820` 表示 v1.1,发布日期为 2025-08-20
+- **要求**:发布日期需 > 2025-08-01(即严格晚于 2025-08-01)
+
+```powershell
+# 若未安装或版本过旧,执行安装/更新
+dotnet new install NewLife.Templates
+```
+
+> **强约束**:仅当未安装或发布日期 ≤ 2025-08-01 时才执行安装;否则保持现状,避免无谓变更。
+
+### 3.3 模板说明
+
+| 模板 | 命令 | 用途 |
+|------|------|------|
+| `xcode` | `dotnet new xcode -n Name.Data` | 数据类库项目 |
+| `cube` | `dotnet new cube -n NameWeb` | Web 管理后台 |
+| `nconsole` | `dotnet new nconsole -n NameApp` | 控制台应用 |
+
+---
+
+## 4. Model.xml 完整参考
+
+### 4.1 文件结构
+
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<EntityModel xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
+             xs:schemaLocation="https://newlifex.com https://newlifex.com/Model202509.xsd" 
+             xmlns="https://newlifex.com/Model202509.xsd">
+  <Option>
+    <!-- 全局配置 -->
+  </Option>
+  <Tables>
+    <Table>
+      <Columns>
+        <Column />
+      </Columns>
+      <Indexes>
+        <Index />
+      </Indexes>
+    </Table>
+  </Tables>
+</EntityModel>
+```
+
+### 4.2 Option 配置项
+
+| 配置项 | 说明 | 示例 |
+|--------|------|------|
+| `Namespace` | 命名空间 | `Zero.Data` |
+| `ConnName` | 数据库连接名 | `Zero` |
+| `Output` | 实体类输出目录 | `.\` |
+| `BaseClass` | 实体基类 | `Entity` |
+| `ChineseFileName` | 使用中文文件名 | `True` |
+| `Nullable` | 生成可空引用类型 | `True` |
+| `HasIModel` | 实现 IModel 接口 | `True` |
+| `ModelClass` | 模型类模板 | `{name}Model` |
+| `ModelsOutput` | 模型类输出目录 | `.\Models\` |
+| `ModelInterface` | 模型接口模板 | `I{name}` |
+| `InterfacesOutput` | 接口输出目录 | `.\Interfaces\` |
+| `NameFormat` | 命名格式 | `Default`/`Upper`/`Lower`/`Underline` |
+| `DisplayName` | 魔方区域显示名 | `订单管理` |
+| `CubeOutput` | 魔方控制器输出目录 | `../../Web/Areas/Order` |
+
+### 4.3 Table 属性
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Name` | 实体类名 | `User` |
+| `TableName` | 数据库表名(可选,默认同 Name) | `sys_user` |
+| `Description` | 表说明 | `用户。用户账号信息` |
+| `ConnName` | 独立连接名(覆盖全局) | `Log` |
+| `BaseType` | 基类(支持实体继承) | `EntityBase` |
+| `InsertOnly` | 仅插入模式(日志表优化) | `True` |
+| `IsView` | 视图标识 | `True` |
+
+### 4.4 Column 属性完整参考
+
+#### 基础属性
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Name` | 属性名 | `UserName` |
+| `ColumnName` | 数据库列名(可选) | `user_name` |
+| `DataType` | 数据类型 | `Int32`/`Int64`/`String`/`DateTime`/`Boolean`/`Double`/`Decimal` |
+| `Description` | 字段说明 | `用户名。登录账号` |
+| `Length` | 字符串长度 | `50`/`200`/`-1`(大文本) |
+| `Precision` | 数值精度 | `18` |
+| `Scale` | 小数位数 | `2` |
+
+#### 主键与标识
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `PrimaryKey` | 主键 | `True` |
+| `Identity` | 自增标识 | `True` |
+| `Master` | 主字段(业务主要字段) | `True` |
+
+#### 约束与默认值
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Nullable` | 允许空 | `False` |
+| `DefaultValue` | 默认值 | `0`/`''`/`getdate()` |
+
+#### 映射关系(Map)
+
+格式:`表名@主键@显示字段@属性名`
+
+| 格式 | 说明 | 示例 |
+|------|------|------|
+| `Table@Id@Name` | 基本映射(三段) | `Role@Id@Name` |
+| `Table@Id@Name@RoleName` | 指定属性名(四段) | `Role@Id@Name@RoleName` |
+| `NS.Table@Id@Path@AreaPath` | 完整命名空间 | `XCode.Membership.Area@Id@Path@AreaPath` |
+
+#### 元素类型(ItemType)
+
+用于魔方前端渲染和数据验证:
+
+| ItemType | 说明 |
+|----------|------|
+| `image` | 图片上传 |
+| `file` | 文件上传 |
+| `mail` | 邮箱格式 |
+| `mobile` | 手机号格式 |
+| `url` | URL 链接 |
+| `TimeSpan` | 时间间隔(秒转可读格式) |
+| `GMK` | 字节数转 GB/MB/KB |
+| `html` | HTML 富文本 |
+| `code` | 代码编辑器 |
+| `json` | JSON 编辑器 |
+
+#### 显示选项(ShowIn)
+
+控制字段在魔方各区域的显示,支持三种语法:
+
+**语法一:具名列表(推荐)**
+```
+ShowIn="List,Search"          # List和Search显示
+ShowIn="-EditForm,-Detail"    # 编辑表单和详情隐藏
+ShowIn="All,-Detail"          # 全部显示,详情隐藏
+ShowIn="None,Search,Add"      # 全部隐藏,搜索和添加显示
+```
+
+区域别名:`List(L)`、`Detail(D)`、`AddForm(Add/A)`、`EditForm(Edit/E)`、`Search(S)`、`Form(F)`(同时控制 Add 和 Edit)
+
+**语法二:管道分隔**
+```
+ShowIn="Y|Y|N||A"   # List=显示|Detail=显示|Add=隐藏|Edit=自动|Search=自动
+```
+
+**语法三:5字符掩码**
+```
+ShowIn="11110"      # 1=显示, 0=隐藏, A/?/-=自动
+```
+
+#### 分表字段(DataScale)
+
+| 值 | 说明 |
+|----|------|
+| `time` | 大数据单表的时间字段(用于雪花 ID) |
+| `timeShard:yyMMdd` | 分表字段,按日期格式分表 |
+
+#### 其他属性
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Type` | 枚举类型 | `XCode.Membership.SexKinds` |
+| `Category` | 表单分组 | `登录信息`/`扩展` |
+| `Attribute` | 额外特性 | `XmlIgnore, IgnoreDataMember` |
+| `Model` | 是否包含在模型类中 | `False` |
+| `RawType` | 原始数据库类型 | `varchar(50)` |
+
+### 4.5 Index 属性
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Columns` | 索引列(逗号分隔) | `Name`/`Category,CreateTime` |
+| `Unique` | 唯一索引 | `True` |
+
+### 4.6 完整示例
+
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<EntityModel xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
+             xs:schemaLocation="https://newlifex.com https://newlifex.com/Model202509.xsd" 
+             xmlns="https://newlifex.com/Model202509.xsd">
+  <Option>
+    <Namespace>Order.Data</Namespace>
+    <ConnName>Order</ConnName>
+    <Output>.\</Output>
+    <ChineseFileName>True</ChineseFileName>
+    <Nullable>True</Nullable>
+    <HasIModel>True</HasIModel>
+    <DisplayName>订单管理</DisplayName>
+    <CubeOutput>../../OrderWeb/Areas/Order</CubeOutput>
+  </Option>
+  <Tables>
+    <Table Name="Order" Description="订单。电商订单主表">
+      <Columns>
+        <Column Name="Id" DataType="Int64" PrimaryKey="True" DataScale="time" Description="编号" />
+        <Column Name="OrderNo" DataType="String" Master="True" Length="50" Nullable="False" Description="订单号" />
+        <Column Name="UserId" DataType="Int32" Map="User@Id@Name" Description="用户" />
+        <Column Name="Status" DataType="Int32" Type="Order.Data.OrderStatus" Description="状态" />
+        <Column Name="TotalAmount" DataType="Decimal" Precision="18" Scale="2" Description="总金额" />
+        <Column Name="Remark" DataType="String" Length="500" Description="备注" Category="扩展" />
+        <Column Name="CreateUser" DataType="String" Description="创建者" Model="False" Category="扩展" />
+        <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="创建时间" Category="扩展" />
+        <Column Name="UpdateTime" DataType="DateTime" Description="更新时间" Model="False" Category="扩展" />
+      </Columns>
+      <Indexes>
+        <Index Columns="OrderNo" Unique="True" />
+        <Index Columns="UserId" />
+        <Index Columns="Status,CreateTime" />
+      </Indexes>
+    </Table>
+  </Tables>
+</EntityModel>
+```
+
+---
+
+## 5. 实体类操作指南
+
+### 5.1 基础 CRUD
+
+```csharp
+// 新增
+var entity = new User { Name = "test", Password = "123456" };
+entity.Insert();
+
+// 查询单个
+var user = User.FindByKey(1);
+var user = User.Find(User._.Name == "test");
+
+// 查询列表
+var list = User.FindAll();
+var list = User.FindAll(User._.Status == 1, User._.Id.Desc(), null, 0, 10);
+
+// 更新
+user.Name = "newName";
+user.Update();
+
+// 删除
+user.Delete();
+
+// 保存(自动判断 Insert/Update)
+entity.Save();
+```
+
+### 5.2 高级查询
+
+```csharp
+// 分页查询
+var page = new PageParameter { PageIndex = 1, PageSize = 20 };
+var list = User.FindAll(User._.Status == 1, page);
+
+// 条件组合
+var where = new WhereExpression();
+where &= User._.Status == 1;
+where &= User._.CreateTime >= DateTime.Today;
+if (!key.IsNullOrEmpty()) where &= User._.Name.Contains(key);
+var list = User.FindAll(where, page);
+
+// 统计
+var count = User.FindCount(User._.Status == 1);
+
+// 查询最大/最小值
+var maxId = User.FindMax(User._.Id, null);
+```
+
+### 5.3 批量操作
+
+```csharp
+// 批量插入
+var list = new List<User>();
+list.Insert();
+
+// 批量更新
+User.Update(User._.Status == 2, User._.Status == 1);
+
+// 批量删除
+User.Delete(User._.Status == 0);
+```
+
+### 5.4 异步操作
+
+```csharp
+var user = await User.FindAsync(User._.Id == 1);
+var list = await User.FindAllAsync(User._.Status == 1, page);
+await entity.InsertAsync();
+await entity.SaveAsync();  // 异步保存,用于日志等高频写入
+```
+
+### 5.5 缓存查询
+
+```csharp
+// 实体缓存(适用于小表)
+var list = User.FindAllWithCache();
+
+// 单对象缓存(按主键)
+var user = User.FindByKeyWithCache(1);
+```
+
+---
+
+## 6. 多模块项目结构
+
+对于复杂业务系统,建议按模块组织:
+
+```
+Zero.Data/
+├── Order/           # 订单模块
+│   ├── Order.xml    # 订单模型
+│   ├── 订单.cs
+│   └── 订单明细.cs
+├── Product/         # 商品模块
+│   ├── Product.xml  # 商品模型
+│   ├── 商品.cs
+│   └── 分类.cs
+└── Member/          # 会员模块
+    ├── Member.xml   # 会员模型
+    └── 会员.cs
+```
+
+每个模块目录内有独立的 `*.xml` 模型文件,在各自目录执行 `xcode` 命令生成实体类。
+
+---
+
+## 7. xcode 命令参考
+
+```powershell
+# 在模型文件所在目录执行(自动查找所有 *.xml)
+xcode
+
+# 指定模型文件
+xcode Model.xml
+xcode Order.xml
+```
+
+**执行效果**:
+1. 读取 XML 模型文件
+2. 生成实体类(`*.cs`)
+3. 生成模型类(如配置了 `ModelClass`)
+4. 生成接口(如配置了 `ModelInterface`)
+5. 生成数据字典(`*.htm`)
+6. 生成魔方控制器(如配置了 `CubeOutput`)
+
+---
+
+## 8. 常见问题
+
+### 8.1 模型文件命名
+
+- 默认:`Model.xml`
+- 推荐:`{系统英文名}.xml` 或 `{模块名}.xml`
+- 复杂项目:每个模块目录一个模型文件
+
+### 8.2 实体类生成位置
+
+- 实体类生成在 `xcode` 命令执行目录
+- 可通过 `Output` 配置项指定输出目录
+- 魔方控制器通过 `CubeOutput` 指定
+
+### 8.3 数据库连接
+
+在应用配置文件中配置连接字符串:
+
+```json
+{
+  "ConnectionStrings": {
+    "Order": "Server=.;Database=Order;Uid=sa;Pwd=xxx"
+  }
+}
+```
+
+连接名对应 Model.xml 中的 `ConnName`。
+
+---
+
+## 9. 与 Cube 的协作
+
+当需要生成 Web 管理界面时:
+
+1. 在 Model.xml 中配置 `CubeOutput` 指向 Web 项目的 Areas 目录
+2. 配置 `DisplayName` 作为魔方区域名称
+3. 执行 `xcode` 自动生成控制器
+4. 深度定制请参考 `cube.instructions.md`
+
+---
+
+## 10. Copilot 行为指引
+
+### 10.1 数据建模时
+
+1. **充分理解业务**:在设计表结构前,确保理解业务场景和数据关系
+2. **合理设计主键**:
+   - 普通表:`Int32` 自增主键
+   - 大数据表:`Int64` + `DataScale="time"`(雪花 ID)
+3. **必要的索引**:为查询条件字段添加索引
+4. **字段长度**:String 类型必须指定合理的 `Length`
+
+### 10.2 生成代码时
+
+1. 确保在正确目录执行 `xcode`
+2. 生成后检查编译是否通过
+3. 如需修改生成的代码,应修改 Model.xml 后重新生成
+
+### 10.3 边界意识
+
+- 数据模型和实体操作 → 本指令
+- Web 控制器和界面 → `cube.instructions.md`
+- 基础编码规范 → `copilot-instructions.md`
Added +32 -0
diff --git a/.github/workflows/publish-beta.yml b/.github/workflows/publish-beta.yml
new file mode 100644
index 0000000..d591c90
--- /dev/null
+++ b/.github/workflows/publish-beta.yml
@@ -0,0 +1,32 @@
+name: publish-beta
+
+on:
+  push:
+    branches: [ master ]
+    paths:
+        - 'NewLife.WeiXin/**'
+  workflow_dispatch:
+
+jobs:
+  build-publish:
+
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v4
+    - name: Setup dotNET
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: |
+          6.x
+          7.x
+          8.x
+          9.x
+          10.x
+    - name: Build
+      run: |
+        dotnet pack --version-suffix $(date "+%Y.%m%d-beta%H%M") -c Release -o out NewLife.WeiXin/NewLife.WeiXin.csproj
+        dotnet pack --version-suffix $(date "+%Y.%m%d-beta%H%M") -c Release -o out NewLife.WeiXinWeb/NewLife.WeiXinWeb.csproj
+    - name: Publish
+      run: |
+        dotnet nuget push ./out/*.nupkg --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.nugetKey }}
Added +30 -0
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..09693ee
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,30 @@
+name: publish
+
+on:
+  push:
+    tags: [ v* ]
+  workflow_dispatch:
+
+jobs:
+  build-publish:
+
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v4
+    - name: Setup dotNET
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: |
+          6.x
+          7.x
+          8.x
+          9.x
+          10.x
+    - name: Build
+      run: |
+        dotnet pack --version-suffix $(date "+%Y.%m%d") -c Release -o out NewLife.WeiXin/NewLife.WeiXin.csproj
+        dotnet pack --version-suffix $(date "+%Y.%m%d") -c Release -o out NewLife.WeiXinWeb/NewLife.WeiXinWeb.csproj
+    - name: Publish
+      run: |
+        dotnet nuget push ./out/*.nupkg --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.nugetKey }}
Added +31 -0
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..d5eb09b
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,31 @@
+name: test
+
+on:
+  push:
+    branches: [ '*' ]
+  pull_request:
+    branches: [ '*' ]
+  workflow_dispatch:
+
+jobs:
+  build-publish:
+
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v4
+    - name: Setup dotNET
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: |
+          6.x
+          7.x
+          8.x
+          9.x
+          10.x
+    - name: Build
+      run: |
+        dotnet build -c Release
+    - name: Test
+      run: |
+        dotnet test -c Release XUnitTest/XUnitTest.csproj
Added +26 -0
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..72bf59c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,26 @@
+################################################################################
+# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
+################################################################################
+
+/.vs
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+/packages
+*.user
+/Data
+/Log
+*.log
+*.htm
+*.nuspec
+*.nupkg
+/BinTest
+/BinUnitTest
+/NewLife.WeiXinWeb/Locations/Config
Added +0 -0
diff --git a/Doc/leaf.png b/Doc/leaf.png
new file mode 100644
index 0000000..cb15e89
Binary files /dev/null and b/Doc/leaf.png differ
Added +0 -0
diff --git a/Doc/newlife.snk b/Doc/newlife.snk
new file mode 100644
index 0000000..31ae707
Binary files /dev/null and b/Doc/newlife.snk differ
Added +21 -0
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f3d40f6
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 新生命开发团队
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Added +52 -0
diff --git a/NewLife.WeiXin.sln b/NewLife.WeiXin.sln
new file mode 100644
index 0000000..f82d24e
--- /dev/null
+++ b/NewLife.WeiXin.sln
@@ -0,0 +1,52 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.32112.339
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{582E00A2-4FA4-41DC-84AD-EE264A9FF4D8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XUnitTest", "XUnitTest\XUnitTest.csproj", "{08A39462-0531-45AB-ACBB-03F62AF4400F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{719C113A-6804-4150-8473-BF889F06DFD6}"
+	ProjectSection(SolutionItems) = preProject
+		.editorconfig = .editorconfig
+		.github\workflows\publish-beta.yml = .github\workflows\publish-beta.yml
+		.github\workflows\publish.yml = .github\workflows\publish.yml
+		Readme.MD = Readme.MD
+		.github\workflows\test.yml = .github\workflows\test.yml
+	EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NewLife.WeiXin", "NewLife.WeiXin\NewLife.WeiXin.csproj", "{9C7D96F5-136F-4FBD-8D58-18105263D041}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewLife.WeiXinWeb", "NewLife.WeiXinWeb\NewLife.WeiXinWeb.csproj", "{393023C1-CCC2-40E3-AE4B-2AA6B4A20BC1}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{582E00A2-4FA4-41DC-84AD-EE264A9FF4D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{582E00A2-4FA4-41DC-84AD-EE264A9FF4D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{582E00A2-4FA4-41DC-84AD-EE264A9FF4D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{582E00A2-4FA4-41DC-84AD-EE264A9FF4D8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{08A39462-0531-45AB-ACBB-03F62AF4400F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{08A39462-0531-45AB-ACBB-03F62AF4400F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{08A39462-0531-45AB-ACBB-03F62AF4400F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{08A39462-0531-45AB-ACBB-03F62AF4400F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9C7D96F5-136F-4FBD-8D58-18105263D041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9C7D96F5-136F-4FBD-8D58-18105263D041}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9C7D96F5-136F-4FBD-8D58-18105263D041}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9C7D96F5-136F-4FBD-8D58-18105263D041}.Release|Any CPU.Build.0 = Release|Any CPU
+		{393023C1-CCC2-40E3-AE4B-2AA6B4A20BC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{393023C1-CCC2-40E3-AE4B-2AA6B4A20BC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{393023C1-CCC2-40E3-AE4B-2AA6B4A20BC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{393023C1-CCC2-40E3-AE4B-2AA6B4A20BC1}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {323831A1-A95B-40AB-B9AD-36A0BC10C2CB}
+	EndGlobalSection
+EndGlobal
Added +59 -0
diff --git a/NewLife.WeiXin/NewLife.WeiXin.csproj b/NewLife.WeiXin/NewLife.WeiXin.csproj
new file mode 100644
index 0000000..b01edf8
--- /dev/null
+++ b/NewLife.WeiXin/NewLife.WeiXin.csproj
@@ -0,0 +1,59 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFrameworks>net45;net461;netstandard2.0;netstandard2.1</TargetFrameworks>
+    <AssemblyTitle>微信对接库</AssemblyTitle>
+    <Description>微信对接库</Description>
+    <Company>新生命开发团队</Company>
+    <Copyright>©2002-2026 新生命开发团队</Copyright>
+    <VersionPrefix>1.0</VersionPrefix>
+    <VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
+    <Version>$(VersionPrefix).$(VersionSuffix)</Version>
+    <FileVersion>$(Version)</FileVersion>
+    <AssemblyVersion>$(VersionPrefix).*</AssemblyVersion>
+    <Deterministic>false</Deterministic>
+    <OutputPath>..\Bin</OutputPath>
+    <GenerateDocumentationFile>True</GenerateDocumentationFile>
+    <LangVersion>latest</LangVersion>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+    <SignAssembly>True</SignAssembly>
+    <AssemblyOriginatorKeyFile>..\Doc\newlife.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+
+  <PropertyGroup>
+    <PackageId>$(AssemblyName)</PackageId>
+    <Authors>$(Company)</Authors>
+    <PackageProjectUrl>https://newlifex.com/core</PackageProjectUrl>
+    <PackageIcon>leaf.png</PackageIcon>
+    <RepositoryUrl>https://github.com/NewLifeX/NewLife.WeiXin</RepositoryUrl>
+    <RepositoryType>git</RepositoryType>
+    <PackageTags>新生命团队;X组件;NewLife;$(AssemblyName)</PackageTags>
+    <PackageReleaseNotes></PackageReleaseNotes>
+    <PackageLicenseExpression>MIT</PackageLicenseExpression>
+    <PublishRepositoryUrl>true</PublishRepositoryUrl>
+    <EmbedUntrackedSources>true</EmbedUntrackedSources>
+    <IncludeSymbols>true</IncludeSymbols>
+    <SymbolPackageFormat>snupkg</SymbolPackageFormat>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Compile Remove="IpHelper.cs" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.103">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="NewLife.Core" Version="11.11.2026.201" />
+    <PackageReference Include="NewLife.Stardust" Version="3.7.2026.201" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Content Include="..\Doc\leaf.png" Link="leaf.png" PackagePath="\" />
+  </ItemGroup>
+
+</Project>
Added +11 -0
diff --git a/NewLife.WeiXin/WeiXinFactory.cs b/NewLife.WeiXin/WeiXinFactory.cs
new file mode 100644
index 0000000..4c8a54e
--- /dev/null
+++ b/NewLife.WeiXin/WeiXinFactory.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NewLife.WeiXin;
+
+internal class WeiXinFactory
+{
+}
Added +9 -0
diff --git a/NewLife.WeiXinWeb/appsettings.Development.json b/NewLife.WeiXinWeb/appsettings.Development.json
new file mode 100644
index 0000000..770d3e9
--- /dev/null
+++ b/NewLife.WeiXinWeb/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+  "DetailedErrors": true,
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  }
+}
Added +18 -0
diff --git a/NewLife.WeiXinWeb/appsettings.json b/NewLife.WeiXinWeb/appsettings.json
new file mode 100644
index 0000000..da92fac
--- /dev/null
+++ b/NewLife.WeiXinWeb/appsettings.json
@@ -0,0 +1,18 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+  "ConnectionStrings": {
+    "WeiXin": "Data Source=..\\Data\\WeiXin.db;showsql=false;Provider=Sqlite",
+
+    //"Location_MySql": "server=.;database=gps;user=gps;password=gps;Provider=MySql",
+    //"Membership_MySql": "server=.;database=gps;user=gps;password=gps;Provider=MySql",
+
+    "Cube": "MapTo=Membership",
+    "Log": "MapTo=Membership"
+  }
+}
Added +48 -0
diff --git a/NewLife.WeiXinWeb/MapSetting.cs b/NewLife.WeiXinWeb/MapSetting.cs
new file mode 100644
index 0000000..b833715
--- /dev/null
+++ b/NewLife.WeiXinWeb/MapSetting.cs
@@ -0,0 +1,48 @@
+using System.ComponentModel;
+using NewLife.Configuration;
+using XCode.Configuration;
+
+namespace IoTWeb;
+
+/// <summary>地址配置</summary>
+[Config("Map")]
+public class MapSetting : Config<MapSetting>
+{
+    #region 静态
+    static MapSetting() => Provider = new DbConfigProvider { UserId = 0, Category = "Map" };
+    #endregion
+
+    #region 属性
+    /// <summary>启用地图。默认true</summary>
+    [Description("启用地图。默认true")]
+    public Boolean Enable { get; set; } = true;
+
+    /// <summary>地图提供者。默认NewLife</summary>
+    [Description("地图提供者。默认NewLife")]
+    public String MapProvider { get; set; } = "NewLife";
+
+    /// <summary>Js地图密钥。浏览器端密钥</summary>
+    [Description("Js地图密钥。浏览器端密钥")]
+    public String JsKey { get; set; }
+
+    /// <summary>地图服务密钥。WebService密钥</summary>
+    [Description("地图服务密钥。WebService密钥")]
+    public String ServiceKey { get; set; }
+
+    /// <summary>地图中心城市。默认西安</summary>
+    [Description("地图中心城市。默认西安")]
+    public String CenterCity { get; set; } = "西安";
+
+    /// <summary>缩放等级。默认6看全国,17最小</summary>
+    [Description("缩放等级。默认6看全国,17最小")]
+    public Int32 ZoomLevel { get; set; } = 6;
+
+    /// <summary>卫星图。默认false</summary>
+    [Description("卫星图。默认false")]
+    public Boolean Earth { get; set; }
+
+    /// <summary>缓存天数。更新数据库记录的时间,默认30天</summary>
+    [Description("缓存天数。更新数据库记录的时间,默认30天")]
+    public Int32 CacheDays { get; set; } = 30;
+    #endregion
+}
\ No newline at end of file
Added +30 -0
diff --git a/NewLife.WeiXinWeb/NewLife.WeiXinWeb.csproj b/NewLife.WeiXinWeb/NewLife.WeiXinWeb.csproj
new file mode 100644
index 0000000..f9d4bf6
--- /dev/null
+++ b/NewLife.WeiXinWeb/NewLife.WeiXinWeb.csproj
@@ -0,0 +1,30 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFrameworks>net6.0;net8.0;net10.0</TargetFrameworks>
+    <AssemblyTitle>微信Api</AssemblyTitle>
+    <Description>微信Api接口</Description>
+    <Company>新生命开发团队</Company>
+    <Copyright>©2002-2026 新生命开发团队</Copyright>
+    <VersionPrefix>1.0</VersionPrefix>
+    <VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
+    <Version>$(VersionPrefix).$(VersionSuffix)</Version>
+    <FileVersion>$(Version)</FileVersion>
+    <AssemblyVersion>$(VersionPrefix).*</AssemblyVersion>
+    <Deterministic>false</Deterministic>
+    <OutputPath>..\Bin\NewLife.WeiXinWeb</OutputPath>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <LangVersion>latest</LangVersion>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="NewLife.Cube.Core" Version="6.9.2026.201" />
+    <PackageReference Include="NewLife.Stardust.Extensions" Version="3.7.2026.201" />
+    <PackageReference Include="NewLife.XCode" Version="11.24.2026.201" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\NewLife.WeiXin\NewLife.WeiXin.csproj" />
+  </ItemGroup>
+
+</Project>
Added +58 -0
diff --git a/NewLife.WeiXinWeb/Program.cs b/NewLife.WeiXinWeb/Program.cs
new file mode 100644
index 0000000..af8835b
--- /dev/null
+++ b/NewLife.WeiXinWeb/Program.cs
@@ -0,0 +1,58 @@
+using NewLife.Cube;
+using NewLife.Log;
+using XCode;
+
+// 日志输出到控制台,并拦截全局异常
+XTrace.UseConsole();
+
+var builder = WebApplication.CreateBuilder(args);
+var services = builder.Services;
+
+// 配置星尘。借助StarAgent,或者读取配置文件 config/star.config 中的服务器地址、应用标识、密钥
+var star = services.AddStardust(null);
+
+// 初始配置
+var set = NewLife.Setting.Current;
+if (set.IsNew)
+{
+    set.DataPath = "../Data";
+    set.Save();
+}
+
+_ = EntityFactory.InitAllAsync();
+
+//services.AddSingleton<MapService>();
+
+// Add services to the container.
+builder.Services.AddRazorPages();
+
+// 引入魔方
+services.AddCube();
+
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+if (!app.Environment.IsDevelopment())
+{
+    app.UseExceptionHandler("/Error");
+    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+    app.UseHsts();
+}
+
+app.UseHttpsRedirection();
+app.UseStaticFiles();
+
+app.UseRouting();
+
+app.UseAuthorization();
+
+app.UseCube(app.Environment);
+
+app.MapControllerRoute(
+    name: "default",
+    pattern: "{controller=CubeHome}/{action=Index}/{id?}");
+
+// 启用星尘注册中心,向注册中心注册服务,服务消费者将自动更新服务端地址列表
+app.RegisterService("NewLife.WeiXin", null, app.Environment.EnvironmentName);
+
+app.Run();
Added +13 -0
diff --git a/NewLife.WeiXinWeb/Properties/launchSettings.json b/NewLife.WeiXinWeb/Properties/launchSettings.json
new file mode 100644
index 0000000..ed1eb77
--- /dev/null
+++ b/NewLife.WeiXinWeb/Properties/launchSettings.json
@@ -0,0 +1,13 @@
+{
+  "profiles": {
+    "http": {
+      "commandName": "Project",
+      "dotnetRunMessages": true,
+      "launchBrowser": true,
+      "applicationUrl": "http://localhost:5122",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    }
+  }
+}
Added +229 -0
diff --git a/Readme.MD b/Readme.MD
new file mode 100644
index 0000000..4024bc9
--- /dev/null
+++ b/Readme.MD
@@ -0,0 +1,229 @@
+# NewLife.WeiXin - 地图组件库
+
+![GitHub top language](https://img.shields.io/github/languages/top/newlifex/NewLife.WeiXin?logo=github)
+![GitHub License](https://img.shields.io/github/license/newlifex/NewLife.WeiXin?logo=github)
+![Nuget Downloads](https://img.shields.io/nuget/dt/NewLife.WeiXin?logo=nuget)
+![Nuget](https://img.shields.io/nuget/v/NewLife.WeiXin?logo=nuget)
+![Nuget (with prereleases)](https://img.shields.io/nuget/vpre/NewLife.WeiXin?label=dev%20nuget&logo=nuget)
+
+地图组件库  
+
+源码: https://github.com/NewLifeX/NewLife.WeiXin  
+Nuget:`NewLife.WeiXin`  
+
+## 功能特性
+- 统一接口 IMap,屏蔽百度 / 高德 / 腾讯 / 天地图 / 企业自建(NewLifeMap) 差异
+- 地理编码(地址→坐标)/ 逆地理编码(坐标→地址)
+- 路径距离/驾车时间(不同厂商策略参数差异已抽象)
+- 行政区划查询(高德)
+- POI / 语义信息融合,自动补充地址组件
+- IP 定位(百度)
+- 多 Key 轮询与自动熔断 + 定时恢复(内置限流/失效关键字识别)
+- 坐标系互转:WGS84 / GCJ02 / BD09(内置常用转换公式)及厂商在线批量转换(百度特殊 from/to 映射)
+- 可选抛出异常 `ThrowException`,便于上层统一处理
+- 多目标框架:net45 / net461 / netstandard2.0 / netstandard2.1(兼容老项目与现代 .NET)
+- 强命名签名,适合反射与插件体系
+- Stardust 注册中心集成(`NewLifeMap` 提供者)支持服务发现与多实例地址自动刷新
+
+## 安装
+```bash
+# 稳定版
+ dotnet add package NewLife.WeiXin
+# 预览版(带日期)
+ dotnet add package NewLife.WeiXin --prerelease
+```
+
+## 快速开始
+```csharp
+using NewLife.WeiXin;
+using NewLife.Data;
+
+// 选择一个具体地图提供者(BaiduMap / AMap / TencentMap / TianDiMap / NewLifeMap)
+var map = new BaiduMap { AppKey = "<BAIDU_AK>" }; // 多个 key 用逗号分隔
+
+// 1. 正向地理编码:地址 -> 坐标
+var geo = await map.GetGeoAsync("北京市海淀区上地十街10号", city: "北京", coordtype: "bd09ll", formatAddress: true);
+Console.WriteLine($"Point: {geo?.Location}  语义:{geo?.Title}");
+
+// 2. 逆地理编码:坐标 -> 地址
+var addr = await map.GetReverseGeoAsync(new GeoPoint(116.30815, 40.056885), "bd09ll");
+Console.WriteLine(addr?.Address);
+
+// 3. 距离(驾车)
+var d = await map.GetDistanceAsync(new GeoPoint(116.30815, 40.056885), new GeoPoint(116.39745, 39.909187), "bd09ll");
+Console.WriteLine($"Distance={d?.Distance}m Duration={d?.Duration}s");
+
+// 4. 坐标转换(离线公式)
+var list = await map.ConvertAsync(new List<GeoPoint> { new(116.30815, 40.056885) }, from: "wgs84", to: "bd09");
+Console.WriteLine(list[0]);
+```
+> 坐标系需使用球面坐标(经纬度),输出为 BD09 坐标系的点。
+
+## 通过工厂动态创建
+```csharp
+var m1 = Map.Create("Baidu");     // 自动匹配 *Map 后缀
+var m2 = Map.Create("AMap");      // 高德
+var m3 = Map.Create("NewLifeMap");
+```
+> `AppKey` 在实例化后设置;多个 key 以逗号分隔,内部轮询使用。
+
+## 提供者说明
+| 提供者 | 类名 | 主要能力 | 备注 |
+| ------ | ---- | -------- | ---- |
+| 百度地图 | `BaiduMap` | 地理/逆地理/距离/POI检索/IP定位/坐标转换(在线+离线) | `KeyName=ak` |
+| 高德地图 | `AMap` | 地理/逆地理/距离/行政区划/坐标转换(离线) | `KeyName=key` |
+| 腾讯地图 | `TencentMap` | (若实现) 地理/逆地理/距离 | 同模式 |
+| 天地图 | `TianDiMap` | (若实现) 地理/逆地理 | |
+| 新生命地图平台 | `NewLifeMap` | 企业聚合接口(后端微服务统一封装) | 通过 Stardust 服务发现 |
+
+`TencentMap.cs` / `TianDiMap.cs` 若为空或未实现,可按 AMap/BaiduMap 模式扩展。
+
+## NewLifeMap & 星尘集成
+```csharp
+// 方式1:直接指定服务端
+var map = new NewLifeMap("http://mapapi.company.local") { AppKey = "<KEY>" };
+
+// 方式2:依赖注入 + Stardust Registry 自动解析地址
+services.AddSingleton<IMap, NewLifeMap>();
+// NewLifeMap(IServiceProvider) 构造函数中会尝试:IRegistry -> StarFactory
+```
+当后端 NewLife.WeiXinWeb 节点列表变化时,绑定的 `ApiHttpClient` 会自动更新,可在多副本/蓝绿发布中无感切换。
+
+## AppKey 多 Key 轮询与熔断
+- 传入 `AppKey="k1,k2,k3"`
+- 每次请求递增索引取余
+- 若响应命中无效关键字(如:`TOO_FREQUENT`, `LIMIT`, `INVALID` 等),调用 `RemoveKey()` 将其暂时下线
+- 下线 key 会放入 `_pendingKeys`,定时器到期后自动恢复
+- 恢复时间策略:当前实现为调用处自行传入(例如 1 小时)
+
+## 坐标系说明
+| 名称 | 说明 | 常见厂商 |
+| ---- | ---- | -------- |
+| WGS84 | 国际通用 GPS | 设备原始定位 |
+| GCJ02 | 国测局加偏 | 高德 / 腾讯 / 绝大多数国内在线地图 |
+| BD09 | 百度加偏 | 百度 |
+
+调用示例:
+```csharp
+var rs = await map.ConvertAsync(new [] { new GeoPoint(lng, lat) }, from:"wgs84", to:"gcj02");
+```
+百度在线转换需要 from/to 索引值,本库已封装。
+
+## 常用 API 一览
+```csharp
+Task<GeoAddress?> GetGeoAsync(string address, string? city=null, string? coordtype=null, bool formatAddress=false);
+Task<GeoAddress?> GetReverseGeoAsync(GeoPoint point, string? coordtype);
+Task<Driving?>    GetDistanceAsync(GeoPoint origin, GeoPoint destination, string? coordtype, int type=0);
+Task<IList<GeoPoint>> ConvertAsync(IList<GeoPoint> points, string from, string to);
+```
+扩展(BaiduMap / AMap 特有):
+```csharp
+Task<GeoAddress?> PlaceSearchAsync(...);      // BaiduMap POI / 区域检索
+Task<IList<GeoArea>> GetAreaAsync(...);       // AMap 行政区划
+Task<IDictionary<string, object?>> IpLocationAsync(...); // BaiduMap IP 定位
+```
+
+## 错误处理
+- 默认:接口返回非成功状态不会抛异常,方法返回 null
+- 设置 `map.ThrowException = true;` 后抛出 `Exception`,便于外层统一捕获
+- 最近一次请求调试信息:`LastUrl` / `LastString` / `LastResult` / `LastKey`
+
+## 扩展一个新地图提供者步骤
+1. 新建类 `XXXMap : Map, IMap`
+2. 设置 `Server` / `KeyName`
+3. 重写 `InvokeAsync<T>` 解析该厂商统一返回结构 & 错误码
+4. 实现 `GetGeoAsync` / `GetReverseGeoAsync` / 其它所需能力
+5. 若有专属限流/失效特征,重写 `IsValidKey` 返回 true 触发临时下线
+6. 提交单元测试覆盖主要功能与边界
+
+## 单元测试
+仓库包含 `XUnitTest` 工程:
+- `*MapTests`:针对不同提供者的编码/逆编码测试
+- 请将真实 Key 放入本地用户机密或环境变量,不要提交到仓库
+
+运行:
+```bash
+dotnet test -c Release
+```
+
+## 构建
+```bash
+dotnet build -c Release
+```
+输出(多框架编译)位于 `Bin/`。
+
+## Roadmap / TODO
+- [ ] 补全 `TencentMap` / `TianDiMap` 具体实现(若仍为空)
+- [ ] 为 `NewLifeMap` 聚合平台补充正向地理编码与距离计算接口
+- [ ] 增加并发限速(令牌桶)可选适配,避免密钥整体封禁
+- [ ] 添加 Benchmark 基准对比(批量坐标转换)
+- [ ] 丰富故障统计 / Metrics(成功率、平均耗时、Key 命中率)
+
+## 版本策略
+主版本 = 兼容性变更;次版本 = 新功能;修订号 = 修复 / 优化。`VersionSuffix` 带日期,便于快速定位构建。
+
+## 贡献
+欢迎 Issue / PR:Bug、性能优化、支持更多地图、补充文档与测试。提交前请阅读 `.github/copilot-instructions.md` 以保持代码风格一致。
+
+## 许可证
+MIT,保留版权声明即可自由使用于商业 / 开源项目。
+
+---
+
+## NewLifeMap
+地图提供者NewLifeMap指向内置MapApi地图接口平台,屏蔽各家接口差异,支持自定义修改。  
+NewLifeMap 可明文制定服务端地址,也可以借助依赖注入自动从星尘注册中心获取。  
+
+## 新生命项目矩阵
+各项目默认支持net9.0/netstandard2.1/netstandard2.0/net4.62/net4.5,旧版(2024.0801)支持net4.0/net2.0  
+
+|                               项目                               | 年份  | 说明                                                                                        |
+| :--------------------------------------------------------------: | :---: | ------------------------------------------------------------------------------------------- |
+|                             基础组件                             |       | 支撑其它中间件以及产品项目                                                                  |
+|          [NewLife.Core](https://github.com/NewLifeX/X)           | 2002  | 核心库,日志、配置、缓存、网络、序列化、APM性能追踪                                         |
+|    [NewLife.XCode](https://github.com/NewLifeX/NewLife.XCode)    | 2005  | 大数据中间件,单表百亿级,MySql/SQLite/SqlServer/Oracle/PostgreSql/达梦,自动分表,读写分离 |
+|      [NewLife.Net](https://github.com/NewLifeX/NewLife.Net)      | 2005  | 网络库,单机千万级吞吐率(2266万tps),单机百万级连接(400万Tcp长连接)                     |
+| [NewLife.Remoting](https://github.com/NewLifeX/NewLife.Remoting) | 2011  | 协议通信库,提供CS应用通信框架,支持Http/RPC通信框架,高吞吐,物联网设备低开销易接入        |
+|     [NewLife.Cube](https://github.com/NewLifeX/NewLife.Cube)     | 2010  | 魔方快速开发平台,集成了用户权限、SSO登录、OAuth服务端等,单表100亿级项目验证               |
+|    [NewLife.Agent](https://github.com/NewLifeX/NewLife.Agent)    | 2008  | 服务管理组件,把应用安装成为操作系统守护进程,Windows服务、Linux的Systemd                   |
+|     [NewLife.Zero](https://github.com/NewLifeX/NewLife.Zero)     | 2020  | Zero零代脚手架,基于NewLife组件生态的项目模板NewLife.Templates,Web、WebApi、Service        |
+|                              中间件                              |       | 对接知名中间件平台                                                                          |
+|    [NewLife.Redis](https://github.com/NewLifeX/NewLife.Redis)    | 2017  | Redis客户端,微秒级延迟,百万级吞吐,丰富的消息队列,百亿级数据量项目验证                   |
+| [NewLife.RocketMQ](https://github.com/NewLifeX/NewLife.RocketMQ) | 2018  | RocketMQ纯托管客户端,支持Apache RocketMQ和阿里云消息队列,十亿级项目验                     |
+|     [NewLife.MQTT](https://github.com/NewLifeX/NewLife.MQTT)     | 2019  | 物联网消息协议,MqttClient/MqttServer,客户端支持阿里云物联网                               |
+|      [NewLife.IoT](https://github.com/NewLifeX/NewLife.IoT)      | 2022  | IoT标准库,定义物联网领域的各种通信协议标准规范                                             |
+|   [NewLife.Modbus](https://github.com/NewLifeX/NewLife.Modbus)   | 2022  | ModbusTcp/ModbusRTU/ModbusASCII,基于IoT标准库实现,支持ZeroIoT平台和IoTEdge网关            |
+|  [NewLife.Siemens](https://github.com/NewLifeX/NewLife.Siemens)  | 2022  | 西门子PLC协议,基于IoT标准库实现,支持IoT平台和IoTEdge                                      |
+|      [NewLife.WeiXin](https://github.com/NewLifeX/NewLife.WeiXin)      | 2022  | 地图组件库,封装百度地图、高德地图、腾讯地图、天地图                                        |
+|    [NewLife.Audio](https://github.com/NewLifeX/NewLife.Audio)    | 2023  | 音频编解码库,PCM/ADPCMA/G711A/G722U/WAV/AAC                                                |
+|                             产品平台                             |       | 产品平台级,编译部署即用,个性化自定义                                                      |
+|         [Stardust](https://github.com/NewLifeX/Stardust)         | 2018  | 星尘,分布式服务平台,节点管理、APM监控中心、配置中心、注册中心、发布中心                   |
+|           [AntJob](https://github.com/NewLifeX/AntJob)           | 2019  | 蚂蚁调度,分布式大数据计算平台(实时/离线),蚂蚁搬家分片思想,万亿级数据量项目验证         |
+|      [NewLife.ERP](https://github.com/NewLifeX/NewLife.ERP)      | 2021  | 企业ERP,产品管理、客户管理、销售管理、供应商管理                                           |
+|         [CrazyCoder](https://github.com/NewLifeX/XCoder)         | 2006  | 码神工具,众多开发者工具,网络、串口、加解密、正则表达式、Modbus、MQTT                      |
+|           [EasyIO](https://github.com/NewLifeX/EasyIO)           | 2023  | 简易文件存储,支持分布式系统中文件集中存储。                                                |
+|           [XProxy](https://github.com/NewLifeX/XProxy)           | 2005  | 产品级反向代理,NAT代理、Http代理                                                           |
+|        [HttpMeter](https://github.com/NewLifeX/HttpMeter)        | 2022  | Http压力测试工具                                                                            |
+|         [GitCandy](https://github.com/NewLifeX/GitCandy)         | 2015  | Git源代码管理系统                                                                           |
+|          [SmartOS](https://github.com/NewLifeX/SmartOS)          | 2014  | 嵌入式操作系统,完全独立自主,支持ARM Cortex-M芯片架构                                      |
+|          [SmartA2](https://github.com/NewLifeX/SmartA2)          | 2019  | 嵌入式工业计算机,物联网边缘网关,高性能.NET8主机,应用于工业、农业、交通、医疗             |
+|                          FIoT物联网平台                          | 2020  | 物联网整体解决方案,建筑、环保、农业,软硬件及大数据分析一体化,单机十万级点位项目验证      |
+|                        UWB高精度室内定位                         | 2020  | 厘米级(10~20cm)高精度室内定位,软硬件一体化,与其它系统联动,大型展厅项目验证             |
+
+
+
+## 新生命开发团队
+![XCode](https://newlifex.com/logo.png)  
+
+新生命团队(NewLife)成立于2002年,是新时代物联网行业解决方案提供者,致力于提供软硬件应用方案咨询、系统架构规划与开发服务。  
+团队主导的80多个开源项目已被广泛应用于各行业,Nuget累计下载量高达400余万次。  
+团队开发的大数据中间件NewLife.XCode、蚂蚁调度计算平台AntJob、星尘分布式平台Stardust、缓存队列组件NewLife.Redis以及物联网平台FIoT,均成功应用于电力、高校、互联网、电信、交通、物流、工控、医疗、文博等行业,为客户提供了大量先进、可靠、安全、高质量、易扩展的产品和系统集成服务。  
+
+我们将不断通过服务的持续改进,成为客户长期信赖的合作伙伴,通过不断的创新和发展,成为国内优秀的IoT服务供应商。  
+
+`新生命团队始于2002年,部分开源项目具有20年以上漫长历史,源码库保留有2010年以来所有修改记录`  
+网站:https://newlifex.com  
+开源:https://github.com/newlifex  
+QQ群:1600800/1600838  
+微信公众号:  
+![智能大石头](https://newlifex.com/stone.jpg)  
Added +28 -0
diff --git a/Test/Program.cs b/Test/Program.cs
new file mode 100644
index 0000000..9ecb7a8
--- /dev/null
+++ b/Test/Program.cs
@@ -0,0 +1,28 @@
+using NewLife.Log;
+
+namespace Test
+{
+    class Program
+    {
+        static void Main(String[] args)
+        {
+            XTrace.UseConsole();
+
+            try
+            {
+                Test1();
+            }
+            catch (Exception ex)
+            {
+                XTrace.WriteException(ex);
+            }
+
+            Console.WriteLine("OK!");
+            Console.ReadKey();
+        }
+
+        static async void Test1()
+        {
+        }
+    }
+}
\ No newline at end of file
Added +12 -0
diff --git a/Test/Properties/PublishProfiles/FolderProfile.pubxml b/Test/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 0000000..3c0e917
--- /dev/null
+++ b/Test/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>..\Bin\Test\publish\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
Added +23 -0
diff --git a/Test/Test.csproj b/Test/Test.csproj
new file mode 100644
index 0000000..884fee5
--- /dev/null
+++ b/Test/Test.csproj
@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net10.0</TargetFramework>
+    <OutputPath>..\Bin\Test</OutputPath>
+    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <LangVersion>latest</LangVersion>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="NewLife.Core" Version="11.11.2026.201" />
+    <PackageReference Include="NewLife.Stardust.Extensions" Version="3.7.2026.201" />
+    <PackageReference Include="NewLife.XCode" Version="11.24.2026.201" />
+    <PackageReference Include="xunit.assert" Version="2.9.3" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\NewLife.WeiXin\NewLife.WeiXin.csproj" />
+  </ItemGroup>
+
+</Project>
Added +11 -0
diff --git a/XUnitTest/BasicTest.cs b/XUnitTest/BasicTest.cs
new file mode 100644
index 0000000..fc3553e
--- /dev/null
+++ b/XUnitTest/BasicTest.cs
@@ -0,0 +1,11 @@
+using Xunit;
+
+namespace XUnitTest;
+
+public class BasicTest
+{
+    [Fact]
+    public async void ConvertAsync()
+    {
+    }
+}
\ No newline at end of file
Added +26 -0
diff --git a/XUnitTest/XUnitTest.csproj b/XUnitTest/XUnitTest.csproj
new file mode 100644
index 0000000..3c73cb5
--- /dev/null
+++ b/XUnitTest/XUnitTest.csproj
@@ -0,0 +1,26 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net10.0</TargetFramework>
+    <OutputPath>..\Bin\UnitTest</OutputPath>
+
+    <IsPackable>false</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
+    <PackageReference Include="NewLife.Core" Version="11.11.2026.201" />
+    <PackageReference Include="NewLife.UnitTest" Version="1.1.2026.102" />
+    <PackageReference Include="xunit" Version="2.9.3" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\NewLife.WeiXin\NewLife.WeiXin.csproj" />
+  </ItemGroup>
+
+</Project>