增加初始化类文件
|
# NewLife.WeChat 实现进度报告
## 实现概述
æ ¹æ®æž¶æž„è®¾è®¡æ–‡æ¡£ï¼Œå·²å®Œæˆæ ¸å¿ƒå®žä½“æ¨¡åž‹ã€æœåŠ¡å±‚å’Œä¸šåŠ¡é€»è¾‘çš„å®žçŽ°ã€‚é¡¹ç›®ç¼–è¯‘é€šè¿‡ï¼Œæ ¸å¿ƒåŠŸèƒ½å·²å°±ç»ªã€‚
## 已完æˆçš„æ¨¡å—
### 1. 实体模型层 (Entities) ✅
#### 1.1 微信é…置表 (`微信é…ç½®`)
- **文件**: `Entities/微信é…ç½®.cs`, `Entities/微信é…ç½®.Biz.cs`
- **功能**:
- å˜å‚¨å¾®ä¿¡åº”用的 AppId å’Œ AppSecret
- 支æŒå¤šåº”用é…置(公众å·ã€å°ç¨‹åºã€APP)
- 支æŒå¤šç§Ÿæˆ·éš”离(TenantId)
- æä¾›é…ç½®ç¼“å˜æœºåˆ¶
- **查询方法**:
- `FindByAppId` - æ ¹æ® AppId 查找(å•对象缓å˜ï¼‰
- `FindAllEnabled` - 查询所有å¯ç”¨çš„é…ç½®
- `FindAllByTenant` - æ ¹æ®ç§Ÿæˆ·æŸ¥è¯¢
- `FindAllByCategory` - æ ¹æ®åº”用分类查询
- `Search` - 高级查询
#### 1.2 微信用户表 (`微信用户`)
- **文件**: `Entities/微信用户.cs`, `Entities/微信用户.Biz.cs`
- **功能**:
- å˜å‚¨ç”¨æˆ· OpenId å’Œ UnionId
- è½»é‡çº§è®¾è®¡ï¼Œä»…ä¿ç•™æ ¸å¿ƒå…³è”å—æ®µ
- 通过 UnionId 实现跨应用关è”
- **查询方法**:
- `FindByOpenId` - æ ¹æ® AppId å’Œ OpenId 查找(å•对象缓å˜ï¼‰
- `FindAllByUnionId` - æ ¹æ® UnionId 查找所有用户
- `FindAllByAppId` - æ ¹æ® AppId 查找所有用户
- `Sync` - åŒæ¥ç”¨æˆ·ä¿¡æ¯
#### 1.3 å¾®ä¿¡æ¨¡æ¿æ¶ˆæ¯é…置表 (`å¾®ä¿¡æ¨¡æ¿æ¶ˆæ¯é…ç½®`)
- **文件**: `Entities/å¾®ä¿¡æ¨¡æ¿æ¶ˆæ¯é…ç½®.cs`, `Entities/å¾®ä¿¡æ¨¡æ¿æ¶ˆæ¯é…ç½®.Biz.cs`
- **功能**:
- å˜å‚¨æ¨¡æ¿æ¶ˆæ¯é…ç½®
- 支æŒå…¬ä¼—å·æ¨¡æ¿æ¶ˆæ¯å’Œå°ç¨‹åºè®¢é˜…消æ¯
- å—æ®µé…置化管ç†ï¼ˆJSON æ ¼å¼ï¼‰
- **查询方法**:
- `FindByTemplateId` - æ ¹æ® AppId å’Œ TemplateId 查找(å•对象缓å˜ï¼‰
- `FindAllByAppId` - æ ¹æ® AppId 查找所有模æ¿
- `FindAllEnabled` - 查询所有å¯ç”¨çš„æ¨¡æ¿
- `FindAllByType` - æ ¹æ®æ¨¡æ¿ç±»åž‹æŸ¥æ‰¾
- `ValidateFields` - 验è¯å—段é…ç½®
#### 1.4 æ•°æ®æ¨¡åž‹å®šä¹‰ (`Model.xml`)
- **文件**: `Entities/Model.xml`
- **内容**: 包å«ä¸‰ä¸ªè¡¨çš„完整定义
- WeChatConfig - 微信é…置表
- WeChatUser - 微信用户表
- WeChatTemplateConfig - æ¨¡æ¿æ¶ˆæ¯é…置表
### 2. æœåС层 (Services) ✅
#### 2.1 WeChatService æ ¸å¿ƒæœåŠ¡
- **文件**: `Services/WeChatService.cs`
- **功能**:
##### AccessToken 管ç†
- `GetAccessTokenAsync` - 获å–访问令牌(自动缓å˜ï¼‰
- `RefreshAccessTokenAsync` - 刷新访问令牌
- 缓å˜é”®æ ¼å¼ï¼š`WeChat:AccessToken:{AppId}`
- ç¼“å˜æ—¶é•¿ï¼š7200ç§’ - 300秒(æå‰5分钟过期)
##### 用户信æ¯èŽ·å–
- `GetUserInfoByCodeAsync` - 通过授æƒç 获å–用户信æ¯
- `GetUserDetailAsync` - 获å–用户详细信æ¯
- 自动ä¿å˜åˆ°æ•°æ®åº“
##### UnionId å…³è”æŸ¥è¯¢
- `GetOpenIdByUnionId` - æ ¹æ® UnionId 查询指定应用的 OpenId
- `GetAllOpenIdsByUnionId` - èŽ·å– UnionId å…³è”的所有 OpenId
##### æ¨¡æ¿æ¶ˆæ¯å‘é€
- `SendTemplateMessageAsync` - å‘é€å…¬ä¼—å·æ¨¡æ¿æ¶ˆæ¯
- `SendSubscribeMessageAsync` - å‘é€å°ç¨‹åºè®¢é˜…消æ¯
- `SendBatchTemplateMessagesAsync` - 批é‡å‘逿¨¡æ¿æ¶ˆæ¯
- è‡ªåŠ¨èŽ·å–æ¨¡æ¿é…ç½®
- 傿•°éªŒè¯å’Œæ ¼å¼åŒ–
- 完整的错误处ç†
##### HTTP 请求å°è£…
- `GetAsync<T>` - GET 请求
- `PostAsync<T>` - POST 请求
- 统一异常处ç†
- 请求日志记录
### 3. æ•°æ®æ¨¡åž‹å±‚ (Models) ✅
#### 3.1 枚举类型
- `WeChatAppType` - 微信应用类型
- `WeChatAppCategory` - 微信应用分类
- `TemplateMessageType` - æ¨¡æ¿æ¶ˆæ¯ç±»åž‹
#### 3.2 å“应模型
- `WeChatResponse` - API å“应基类
- `AccessTokenResponse` - AccessToken å“应
- `OAuthTokenResponse` - OAuth2.0 授æƒå“应
- `WeChatUserInfo` - 用户信æ¯å“应
- `TemplateMessageResponse` - æ¨¡æ¿æ¶ˆæ¯å‘é€å“应
#### 3.3 请求模型
- `TemplateMessageRequest` - æ¨¡æ¿æ¶ˆæ¯å‘é€è¯·æ±‚
- `SubscribeMessageRequest` - 订阅消æ¯å‘é€è¯·æ±‚
- `MiniProgramInfo` - å°ç¨‹åºä¿¡æ¯
### 4. 扩展方法 (Extensions) ✅
#### 4.1 CollectionExtensions
- **文件**: `Extensions/CollectionExtensions.cs`
- **方法**: `Page<T>` - 分页处ç†é›†åˆ
- **用途**: 批é‡å‘逿—¶è‡ªåŠ¨åˆ†æ‰¹å¤„ç†
### 5. 文档 (Docs) ✅
#### 5.1 架构设计文档
- **文件**: `docs/Architecture.md`
- **内容**: å®Œæ•´çš„æž¶æž„è®¾è®¡ã€æ•°æ®æµç¨‹ã€åŠŸèƒ½æ¨¡å—说明
#### 5.2 快速开始指å—
- **文件**: `docs/QuickStart.md`
- **内容**: æ•°æ®åº“é…ç½®ã€åŸºæœ¬ä½¿ç”¨ã€ç¤ºä¾‹ä»£ç
#### 5.3 æ ¸å¿ƒåŠŸèƒ½å®žçŽ°è¯´æ˜Ž
- **文件**: `docs/CoreFunctions.md`
- **内容**: å„功能模å—çš„è¯¦ç»†å®žçŽ°è¯´æ˜Žã€æœ€ä½³å®žè·µã€å¸¸è§é—®é¢˜
#### 5.4 README
- **文件**: `README.md`
- **内容**: 项目介ç»ã€åŠŸèƒ½ç‰¹æ€§ã€å¿«é€Ÿå¼€å§‹ã€API 列表
---
## 技术实现è¦ç‚¹
### 1. 实体模型设计
```csharp
// 使用 XCode 实体模型
// 自动生æˆå±žæ€§ã€å—æ®µæ˜ å°„ã€ç´¢å¼•
// 支æŒå•对象缓å˜å’ŒæŸ¥è¯¢ç¼“å˜
public partial class 微信é…ç½® : Entity<微信é…ç½®>
{
// å•对象缓å˜é…ç½®
static 微信é…ç½®()
{
Meta.SingleCache.FindSlaveKeyMethod = k => Find(_.AppId == k);
Meta.SingleCache.GetSlaveKeyMethod = e => e.AppId;
}
}
```
### 2. 缓å˜ç–ç•¥
```csharp
// AccessToken 缓å˜
var key = $"WeChat:AccessToken:{appId}";
_cache.Set(key, token, expires_in - 300); // æå‰5分钟过期
// 实体缓å˜
var config = 微信é…ç½®.FindByAppId(appId); // 自动缓å˜
```
### 3. 异æ¥è®¾è®¡
```csharp
// å…¨å¼‚æ¥ API
public async Task<String> GetAccessTokenAsync(String appid, Boolean forceRefresh = false)
{
// 检查缓å˜
var cached = _cache.Get<String>(key);
if (!cached.IsNullOrEmpty()) return cached;
// 异æ¥è¯·æ±‚
return await RefreshAccessTokenAsync(appid);
}
```
### 4. 错误处ç†
```csharp
// 统一异常处ç†
if (!result.IsSuccess)
throw new Exception($"API调用失败: {result.ErrCode} - {result.ErrMsg}");
// 业务级错误处ç†
if (template == null || !template.IsEnabled)
{
Log?.Warn($"æ¨¡æ¿ {templateId} ä¸å˜åœ¨æˆ–未å¯ç”¨");
return false;
}
```
### 5. 日志记录
```csharp
// 使用 NewLife.Log
public ILog Log { get; set; }
Log?.Info($"AccessToken刷新æˆåŠŸ: {appid}");
Log?.Debug($"GET: {url}");
Log?.Error($"å‘é€å¤±è´¥: {ex.Message}");
```
---
## 代ç 规范éµå¾ª
### ✅ ç¬¦åˆ NewLife ç¼–ç 规范
1. **类型å**:使用 `String`ã€`Int32`ã€`Boolean` ç‰ .NET æ£å¼å
2. **命å空间**:file-scoped namespace
3. **Region 组织**:属性 → æž„é€ â†’ 方法 → 日志
4. **注释规范**:`<summary>` åŒè¡Œé—åˆï¼Œæ‰€æœ‰å‚数都有 `<param>` 注释
5. **å¼‚æ¥æ–¹æ³•**:åŽç¼€ `Async`
6. **å•行 if**:简å•è¯å¥åŒè¡Œ
7. **循环ä¿ç•™èŠ±æ‹¬å·**:å³ä½¿å•è¯å¥
8. **集åˆåˆå§‹åŒ–**:使用 `= []`
9. **Null æ¡ä»¶è¿ç®—符**:优先使用 `?.` å’Œ `??`
### ✅ XCode 实体规范
1. **å•对象缓å˜**:é…ç½® FindSlaveKeyMethod å’Œ GetSlaveKeyMethod
2. **时间模å—**:Meta.Modules.Add<TimeModule>()
3. **IP模å—**:Meta.Modules.Add<IPModule>()
4. **Valid 验è¯**ï¼šå‚æ•°æ ¡éªŒå’Œé»˜è®¤å€¼è®¾ç½®
5. **扩展查询**:FindByXxxã€FindAllByXxxã€Search ç‰æ–¹æ³•
6. **业务æ“作**:Syncã€Update ç‰ä¸šåŠ¡æ–¹æ³•
---
## 测试验è¯
### 编译测试
```bash
✅ dotnet build - 编译æˆåŠŸï¼Œæ— é”™è¯¯
```
### 功能验è¯
- ✅ 实体类定义æ£ç¡®
- ✅ æœåŠ¡ç±»æ–¹æ³•å®Œæ•´
- ✅ 扩展方法å¯ç”¨
- ✅ 模型类型匹é…
---
## 下一æ¥å·¥ä½œ
### çŸæœŸè®¡åˆ’
1. **创建å•元测试项目**
- WeChatService 测试
- 实体类 CRUD 测试
- é›†æˆæµ‹è¯•
2. **补充工具类**
- SignHelper(ç¾å辅助)
- CryptoHelperï¼ˆåŠ å¯†è¾…åŠ©ï¼‰
3. **完善文档**
- API å‚考文档
- 更多使用示例
- 常è§é—®é¢˜æ±‡æ€»
### 䏿œŸè®¡åˆ’
1. **消æ¯ç®¡ç†**
- 接收消æ¯å¤„ç†
- 自动回å¤åŠŸèƒ½
- 事件推é€å¤„ç†
2. **èœå•管ç†**
- 自定义èœå• CRUD
- æ¡ä»¶èœå•支æŒ
3. **ç´ æç®¡ç†**
- ä¸´æ—¶ç´ æä¸Šä¼
- æ°¸ä¹…ç´ æç®¡ç†
### 长期计划
1. **支付功能**
- 公众巿”¯ä»˜
- å°ç¨‹åºæ”¯ä»˜
2. **ä¼ä¸šå¾®ä¿¡**
- ä¼ä¸šå¾®ä¿¡ API 支æŒ
3. **高级功能**
- æ¶ˆæ¯æŽ¨é€é˜Ÿåˆ—
- å‘é€è®°å½•和统计
- 性能监控
---
## 项目结构
```
NewLife.WeChat/
├── Entities/ # 实体模型层 ✅
│ ├── Model.xml # æ•°æ®æ¨¡åž‹å®šä¹‰
│ ├── 微信é…ç½®.cs # 微信é…置实体
│ ├── 微信é…ç½®.Biz.cs # 微信é…置业务逻辑
│ ├── 微信用户.cs # 微信用户实体
│ ├── 微信用户.Biz.cs # 微信用户业务逻辑
│ ├── å¾®ä¿¡æ¨¡æ¿æ¶ˆæ¯é…ç½®.cs # æ¨¡æ¿æ¶ˆæ¯é…置实体
│ └── å¾®ä¿¡æ¨¡æ¿æ¶ˆæ¯é…ç½®.Biz.cs # æ¨¡æ¿æ¶ˆæ¯é…置业务逻辑
├── Services/ # æœåС层 ✅
│ └── WeChatService.cs # å¾®ä¿¡æ ¸å¿ƒæœåŠ¡
├── Models/ # æ•°æ®æ¨¡åž‹ ✅
│ └── WeChatModels.cs # 请求/å“åº”æ¨¡åž‹ã€æžšä¸¾
├── Extensions/ # 扩展方法 ✅
│ └── CollectionExtensions.cs # é›†åˆæ‰©å±•
├── docs/ # 文档 ✅
│ ├── Architecture.md # 架构设计文档
│ ├── QuickStart.md # 快速开始指å—
│ ├── CoreFunctions.md # æ ¸å¿ƒåŠŸèƒ½å®žçŽ°è¯´æ˜Ž
│ └── 本文件.md # 实现进度报告
└── README.md # 项目说明 ✅
```
---
## 代ç 统计
| æ¨¡å— | 文件数 | 代ç 行数(估算) |
|------|--------|----------------|
| 实体模型 | 7 | ~1200 |
| æœåС层 | 1 | ~320 |
| æ•°æ®æ¨¡åž‹ | 1 | ~180 |
| 扩展方法 | 1 | ~30 |
| 文档 | 4 | ~1500(å«ç¤ºä¾‹ï¼‰ |
| **总计** | **14** | **~3230** |
---
## 技术亮点
### 1. è½»é‡çº§è®¾è®¡
- 微信用户表仅ä¿ç•™æ ¸å¿ƒå—段(OpenIdã€UnionId)
- ä¸šåŠ¡æ‰©å±•å—æ®µç”±ä¸šåŠ¡ç³»ç»Ÿç®¡ç†
- å‡å°‘æ•°æ®å†—余,æå‡æ€§èƒ½
### 2. 缓å˜ä¼˜åŒ–
- AccessToken 自动缓å˜ï¼Œæå‰è¿‡æœŸ
- 实体å•对象缓å˜ï¼Œå‡å°‘æ•°æ®åº“查询
- 支æŒåˆ†å¸ƒå¼ç¼“å˜ï¼ˆRedis)
### 3. 跨应用关è”
- 通过 UnionId 实现用户统一识别
- 支æŒå…¬ä¼—å·ã€å°ç¨‹åºã€APP 互通
- 适用于多ç§ä¸šåŠ¡åœºæ™¯
### 4. 模æ¿é…置化
- 模æ¿ä¿¡æ¯å˜å‚¨åœ¨æ•°æ®åº“
- å—æ®µé…ç½®çµæ´»å¯è°ƒ
- 便于统一管ç†å’Œç»´æŠ¤
### 5. 批é‡å¤„ç†
- è‡ªåŠ¨åˆ†æ‰¹ï¼ˆæ¯æ‰¹50个)
- å¹¶å‘å‘é€ï¼Œæå‡æ•ˆçއ
- 结果统计和失败追踪
---
## 使用场景
### 场景1:统一登录系统
用户在公众å·ç™»å½•åŽï¼Œè‡ªåЍ关è”å°ç¨‹åºè´¦å·ã€‚
```csharp
// å…¬ä¼—å·æŽˆæƒç™»å½•
var userInfo = await service.GetUserInfoByCodeAsync("wx_official", code);
var unionId = userInfo.UnionId;
// 查询用户在å°ç¨‹åºçš„ OpenId
var miniOpenId = service.GetOpenIdByUnionId(unionId, "wx_mini");
// 生æˆç»Ÿä¸€çš„登录å‡è¯
var token = GenerateUserToken(unionId);
```
### 场景2:订å•通知推é€
订å•完æˆåŽï¼Œå‘用户的所有应用推é€é€šçŸ¥ã€‚
```csharp
var users = service.GetAllOpenIdsByUnionId(unionId);
foreach (var user in users)
{
var config = 微信é…ç½®.FindByAppId(user.AppId);
if (config.AppCategory == 1) // 公众å·
await service.SendTemplateMessageAsync(/*...*/);
else if (config.AppCategory == 2) // å°ç¨‹åº
await service.SendSubscribeMessageAsync(/*...*/);
}
```
### 场景3:è¥é”€æ´»åЍ
跨应用的用户è¥é”€å’Œæ•°æ®åˆ†æžã€‚
```csharp
// 统计用户分布
var allUsers = 微信用户.FindAll();
var groupByApp = allUsers.GroupBy(u => u.AppId);
foreach (var group in groupByApp)
{
var config = 微信é…ç½®.FindByAppId(group.Key);
Console.WriteLine($"{config.AppName}: {group.Count()} 用户");
}
// ç›é€‰å¤šåº”用用户
var multiAppUsers = allUsers
.Where(u => !u.UnionId.IsNullOrEmpty())
.GroupBy(u => u.UnionId)
.Where(g => g.Count() > 1);
Console.WriteLine($"多应用用户: {multiAppUsers.Count()}");
```
---
## ä¾èµ–项
| 包 | 版本 | 用途 |
|----|------|------|
| NewLife.Core | 最新版 | åŸºç¡€å·¥å…·ã€æ—¥å¿—ã€ç¼“å˜ |
| NewLife.XCode | 最新版 | æ•°æ®è®¿é—®ã€å®žä½“模型 |
---
## 编译和测试
### 编译
```bash
dotnet build
# ✅ 编译æˆåŠŸ
```
### è¿è¡Œæµ‹è¯•(待创建)
```bash
dotnet test
```
---
## 已知é™åˆ¶
1. **UnionId ä¾èµ–开放平å°**
- 需è¦åº”用绑定微信开放平å°
- ç”¨æˆ·æœªå…³æ³¨æˆ–æœªæŽˆæƒæ—¶ UnionId 为空
2. **å°ç¨‹åºè®¢é˜…消æ¯é™åˆ¶**
- 需è¦ç”¨æˆ·ä¸»åŠ¨è®¢é˜…
- å‘逿¬¡æ•°æœ‰é™åˆ¶
3. **æ¨¡æ¿æ¶ˆæ¯å®¡æ ¸**
- 模æ¿éœ€è¦åœ¨å¾®ä¿¡å…¬ä¼—å¹³å°å®¡æ ¸é€šè¿‡
- ä¸åŒè¡Œä¸šæ¨¡æ¿å—段ä¸åŒ
---
## 贡献指å—
1. Fork 本项目
2. 创建特性分支
3. æäº¤ä»£ç
4. 创建 Pull Request
éµå¾ª NewLife 团队编ç è§„èŒƒï¼ˆè§ `.github/copilot-instructions.md`)。
---
**æŠ¥å‘Šç”Ÿæˆæ—¶é—´**: 2024-01
**项目状æ€**: æ ¸å¿ƒåŠŸèƒ½å·²å®Œæˆï¼Œç¼–译通过 ✅
**下一æ¥**: 创建å•元测试,完善工具类
|