79 lines
4.5 KiB
Markdown
79 lines
4.5 KiB
Markdown
# Store Management API 客户端
|
|
|
|
独立的 API 类库(当前继承仓库的 net8.0-windows 目标框架),使用 RestSharp 112.1.0 连接 StoreWeb。WPF 项目已引用该类库。每个服务地址及用户会话创建一个 StoreApiClient,建议在应用容器注册为单例,退出应用时释放。
|
|
|
|
## 调用
|
|
|
|
```csharp
|
|
using Store.Management.Api;
|
|
using Store.Management.Api.Authentication;
|
|
using Store.Management.Api.Users;
|
|
using Store.Management.Api.Transport;
|
|
|
|
using var api = new StoreApiClient(new ApiClientOptions
|
|
{
|
|
BaseUrl = new Uri("https://your-server/"), // 替换为实际服务地址
|
|
Version = "v1",
|
|
Timeout = TimeSpan.FromSeconds(30)
|
|
});
|
|
try
|
|
{
|
|
await api.Auth.LoginAsync(new LoginRequest
|
|
{
|
|
UserName = userName,
|
|
Password = passwordMd5, // UTF-8 密码的 32 位大写 MD5,保留原密码首尾空格
|
|
DeviceId = deviceId, // 可选;稳定设备标识由宿主应用管理
|
|
DeviceName = Environment.MachineName
|
|
});
|
|
var me = await api.Auth.MeAsync();
|
|
var page = await api.Users.SearchAsync(new UserSearchRequest
|
|
{
|
|
Page = 1, PageSize = 50, Keyword = ""
|
|
});
|
|
var created = await api.Users.CreateAsync(new UserCreateRequest
|
|
{
|
|
UserName = "new-user", Password = initialPassword, NickName = "新用户"
|
|
});
|
|
await api.Users.UpdateAsync(new UserUpdateRequest { Id = created.Id, NickName = "修改后的昵称" });
|
|
await api.Auth.LogoutAsync();
|
|
}
|
|
catch (ApiException ex)
|
|
{
|
|
// 显示 ex.Message;根据 Kind 区分失败类型,TraceId 可用于联系服务端排查。
|
|
// Unauthorized 时导航登录页;HTTP 403 不清除会话。
|
|
}
|
|
```
|
|
|
|
示例中的账号、密码摘要、设备标识由调用方提供;登录窗口已负责计算密码摘要,API 层不重复计算。异步方法均支持 CancellationToken;主动取消抛出 OperationCanceledException,本地输入校验抛出 ValidationException。
|
|
|
|
## 文件与职责
|
|
|
|
- StoreApiClient.cs:组合会话、传输层与业务模块,集中管理生命周期。
|
|
- ApiClientOptions.cs:服务地址、版本和超时配置。
|
|
- Transport/ApiTransport.cs:唯一 HTTP 出口,统一 Bearer、JSON、查询参数、校验及错误映射。
|
|
- Transport/ApiException.cs:区分网络、超时、HTTP、业务、响应格式与认证错误,保留状态码、业务码与 TraceId。
|
|
- Authentication/:登录、退出、当前用户;Token 仅存内存。
|
|
- Models/:服务端响应信封与分页模型。
|
|
- Users/:用户分页、查询、添加与修改,DTO 只包含当前基础功能所需字段。
|
|
|
|
## 协议与扩展
|
|
|
|
对齐 StoreWeb 的 AuthController、TokenResult、UnifyResultFilter 和用户管理控制器。成功码为 200;HTTP 200 内的业务失败同样抛出 ApiException。先读取响应状态与业务码,再解析成功 data,避免错误响应的数据结构掩盖业务错误。登录读取 data.token,认证采用 Bearer opaque Token,不解析 JWT,不根据首次登录的有效期自行判定续期。HTTP 或业务 401 清除当前请求所用的会话;旧请求的 401 不清除新 Token。
|
|
|
|
后续商品模块按 Users 的方式新增独立 DTO、接口和实现,由 StoreApiClient 暴露模块入口。模块通过 Transport.GetRequiredAsync<T> 发送有数据请求,通过 SendAsync<object> 发送无数据操作。路由采用 user/GetAllUser 这样的相对路径,传输层自动添加版本。简单参数使用 query,复杂参数使用 body,HTTP 方法与服务端契约一致。避免按常规 REST 习惯猜测当前服务端的动作路由。
|
|
|
|
请求不自动重试,避免添加、修改操作重复执行。禁止自动重定向;服务地址应直接指向最终 API 地址。退出时即使服务端请求失败也清理本地 Token,并将错误交给宿主;此时服务端会话可能仍有效。Session.Clear 可用于本地退出,不撤销服务器会话。
|
|
|
|
登录界面由宿主项目提供;API 层不包含 Token 磁盘持久化、自动刷新或商品接口。实际地址由宿主提供,尚未进行真实服务联调。
|
|
|
|
## 验证
|
|
|
|
在仓库根目录运行:
|
|
|
|
```powershell
|
|
dotnet build Store.Management.slnx
|
|
dotnet run --project Tests/Store.Management.Api.SmokeTests/Store.Management.Api.SmokeTests.csproj
|
|
```
|
|
|
|
模拟 HTTP 测试覆盖登录路由、Bearer、分页序列化与解析、输入边界、业务错误、无效 JSON、403、HTTP 与业务 401、无效 Token/data、旧请求 401 会话隔离、登录退出串行、退出失败清理及主动取消,不会调用真实服务。
|