# BSPHP C# 四项目演示 / BSPHP C# 四專案演示 / BSPHP C# Four-Project Demos

| 简体中文 | 繁體中文 | English |
|---------|---------|---------|
| 本仓库包含 4 个完全独立的 C# 客户端，对齐 MFC BSPHP 演示：账号登录 + 卡密控制。 | 本儲存庫包含 4 個完全獨立的 C# 用戶端，對齊 MFC BSPHP 演示：帳號登入 + 卡密控制。 | This repo contains 4 standalone C# clients aligned with MFC BSPHP demos: account login + card license panel. |
| 各项目互不引用，配置与界面均在各自目录内。 | 各專案互不引用，設定與介面均在各自目錄內。 | Projects do not cross-reference; config and UI live inside each project folder. |

---

## 项目一览 / 專案一覽 / Projects

| 目录 | 类型 | appid | 说明 |
|------|------|-------|------|
| `bsphp.login.win` | WPF | `8888888` | 账号登录 + 控制台（13 Tab + ConsoleWindow） |
| `bsphp.login.maui` | MAUI (Windows) | `8888888` | 同上：LoginPage + ConsolePage |
| `bsphp.card.win` | WPF | `66666666` | 卡密登录 + 控制面板（卡密/机器码 + MainWindow） |
| `bsphp.card.maui` | MAUI (Windows) | `66666666` | 同上：LoginPage + MainPage |

---

## 目录结构 / 目錄結構 / Directory Layout

```
BSPHP-C#-DEMO/
├── global.json                 # 根目录 SDK 版本锁定 (.NET 8)
├── README.md
├── tools/
│   └── BsphpApiTest/           # 命令行 API 连通性测试（引用 card.win 配置）
│
├── bsphp.login.win/            # WPF 账号登录
│   ├── Api/
│   │   ├── ApiConfig.cs        # ★ 接口配置（const 变量）
│   │   ├── ApiModels.cs        # 配置模型、返回结果
│   │   ├── BSPHPClient.cs      # 加密通信客户端
│   │   └── BSPHPCrypto.cs      # MD5 / AES / RSA
│   ├── Config/
│   │   └── ApiConfig说明.txt   # 配置字段中文说明
│   ├── MainWindow.xaml(.cs)    # 登录窗 800×600（13 Tab）
│   ├── ConsoleWindow.xaml(.cs) # 登录后控制台 1000×580
│   ├── LoginCaptchaHelper.cs   # 验证码 Tab 规则
│   ├── LoginCaptchaService.cs  # 验证码图片下载与显示
│   ├── MachineIdHelper.cs      # 机器码
│   └── HeartbeatTimerService.cs# 自动心跳 timeout.lg
│
├── bsphp.login.maui/           # MAUI 账号登录（结构同上，页面为 XAML ContentPage）
│   ├── LoginPage.xaml(.cs)
│   ├── ConsolePage.xaml(.cs)
│   ├── WindowSizeHelper.cs
│   ├── App.xaml.cs             # CreateWindow 入口
│   └── MauiProgram.cs
│
├── bsphp.card.win/             # WPF 卡密
│   ├── Api/                    # 同上 Api 层
│   ├── LoginWindow.xaml(.cs)   # 登录窗 700×450（卡密 / 机器码 Tab）
│   └── MainWindow.xaml(.cs)    # 控制面板 1000×580（23 按钮 + 心跳）
│
└── bsphp.card.maui/            # MAUI 卡密
    ├── LoginPage.xaml(.cs)
    ├── MainPage.xaml(.cs)
    └── （其余与 login.maui 同类辅助文件）
```

| 简体中文 | 繁體中文 | English |
|---------|---------|---------|
| `Api/`：协议层，四个项目各自一份，不共享。 | `Api/`：協議層，四個專案各自一份，不共享。 | `Api/`: protocol layer; each project has its own copy. |
| `Config/`：仅保留字段说明文本；**实际配置在 `Api/ApiConfig.cs`**。 | `Config/`：僅保留欄位說明文字；**實際設定在 `Api/ApiConfig.cs`**。 | `Config/`: field docs only; **real config is in `Api/ApiConfig.cs`**. |
| 登录项目：登录成功 → 控制台；注销 → 回到登录窗。 | 登入專案：登入成功 → 控制台；登出 → 回到登入窗。 | Login projects: after login → console; logout → back to login. |
| 卡密项目：验证成功 → 控制面板。 | 卡密專案：驗證成功 → 控制面板。 | Card projects: after verify → control panel. |

---

## 项目配置 / 專案設定 / Project Configuration

**修改位置 / Location：** 各项目 `Api/ApiConfig.cs` 中的 `const` 变量（不再使用 JSON）。

| 变量 | 简体中文 | 繁體中文 | English |
|------|---------|---------|---------|
| `Url` | BSPHP 加密网关完整地址（含 `appid`、`m`） | BSPHP 加密閘道完整位址（含 `appid`、`m`） | Full BSPHP encrypted gateway URL (`appid`, `m`) |
| `MutualKey` | 与后台 `mutualkey` 一致的通信认证 Key | 與後台 `mutualkey` 一致的通訊認證 Key | Mutual authentication key |
| `ServerPrivateKey` | 服务端 RSA 私钥 Base64，解密回包 | 伺服端 RSA 私鑰 Base64，解密回包 | Server RSA private key (Base64) |
| `ClientPublicKey` | 客户端 RSA 公钥 Base64，加密请求签名 | 用戶端 RSA 公鑰 Base64，加密請求簽名 | Client RSA public key (Base64) |
| `CodeUrlPrefix` | 图形验证码 URL 前缀（见下文） | 圖形驗證碼 URL 前綴（見下文） | Captcha image URL prefix (see below) |
| `UseMock` | `true` 本地模拟；`false` 连接真实服务器 | `true` 本機模擬；`false` 連線真實伺服器 | `true` = mock; `false` = live server |

### 两套演示 appid / Two demo app IDs

| 项目 | `Url` 中 appid | 续费/购卡 `daihao` |
|------|----------------|-------------------|
| `bsphp.login.*` | `8888888` | `8888888` |
| `bsphp.card.*` | `66666666` | `66666666` |

### 代码引用示例 / Code usage

```csharp
// 各项目登录/主窗构造函数中
_client = new BsphpClient(ApiConfig.Create());
```

| 简体中文 | 繁體中文 | English |
|---------|---------|---------|
| 详细字段说明另见各项目 `Config/ApiConfig说明.txt`。 | 詳細欄位說明另見各專案 `Config/ApiConfig说明.txt`。 | See each project's `Config/ApiConfig说明.txt` for field notes. |

---

## 图形验证码显示 / 圖形驗證碼顯示 / Captcha Image Display

仅 **账号登录** 项目（`bsphp.login.win` / `bsphp.login.maui`）在登录页展示图形验证码。

| 简体中文 | 繁體中文 | English |
|---------|---------|---------|
| 配置 `CodeUrlPrefix` 后，完整图片地址为：`CodeUrlPrefix + BSphpSeSsL + "&_=" + 时间戳` | 設定 `CodeUrlPrefix` 後，完整圖片位址為：`CodeUrlPrefix + BSphpSeSsL + "&_=" + 時間戳` | With `CodeUrlPrefix` set: `CodeUrlPrefix + BSphpSeSsL + "&_=" + timestamp` |
| 登录演示默认值：`https://demo.bsphp.com/index.php?m=coode&sessl=` | 登入演示預設值：`https://demo.bsphp.com/index.php?m=coode&sessl=` | Login demo default prefix (see `ApiConfig.cs`) |
| 卡密演示 `CodeUrlPrefix` 留空（卡密页一般不需要图形码） | 卡密演示 `CodeUrlPrefix` 留空（卡密頁一般不需要圖形碼） | Card demos leave `CodeUrlPrefix` empty |

### 显示逻辑（对齐 MFC LoginDlg）

| 步骤 | 简体中文 | 繁體中文 | English |
|------|---------|---------|---------|
| 1 | Bootstrap 后调用 `getsetimag.in` 查询当前 Tab 是否开启验证码 | Bootstrap 後呼叫 `getsetimag.in` 查詢當前 Tab 是否開啟驗證碼 | After bootstrap, `getsetimag.in` checks captcha per tab |
| 2 | 短信/邮箱登录、注册、找回等 Tab **强制显示** | 簡訊/郵箱登入、註冊、找回等 Tab **強制顯示** | SMS/email login, register, recover tabs **always show** captcha |
| 3 | 密码登录 → `INGES_LOGIN`；注册 → `INGES_RE`；找回 → `INGES_MACK`；反馈 → `INGES_SAY` | 密碼登入 → `INGES_LOGIN`；註冊 → `INGES_RE`；找回 → `INGES_MACK`；反饋 → `INGES_SAY` | Same `INGES_*` type keys as MFC |
| 4 | Tab 下方显示：验证码图片 + **刷新** + 输入框；提交时作为 `coode` 参数 | Tab 下方顯示：驗證碼圖片 + **刷新** + 輸入框；提交時作為 `coode` 參數 | UI: image + **refresh** + input; sent as `coode` on submit |
| 5 | 实现类：`LoginCaptchaHelper.cs`、`LoginCaptchaService.cs` | 實作類：`LoginCaptchaHelper.cs`、`LoginCaptchaService.cs` | Implementation: `LoginCaptchaHelper.cs`, `LoginCaptchaService.cs` |

---

## 运行环境 / 執行環境 / Prerequisites

- [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0)（根目录 `global.json` 建议 `8.0.422`）
- MAUI 项目额外安装：`dotnet workload install maui`
- 目标平台：**Windows**（WPF / MAUI Windows）

---

## 编译与运行 / 編譯與執行 / Build & Run

```bash
# WPF
dotnet run --project bsphp.login.win
dotnet run --project bsphp.card.win

# MAUI（已使用单 TargetFramework，可直接 run）
dotnet run --project bsphp.login.maui
dotnet run --project bsphp.card.maui

# API 冒烟测试
dotnet run --project tools/BsphpApiTest
```

| 简体中文 | 繁體中文 | English |
|---------|---------|---------|
| 清理构建缓存：对各项目执行 `dotnet clean`，并删除各目录下 `bin/`、`obj/`。 | 清理建置快取：對各專案執行 `dotnet clean`，並刪除各目錄下 `bin/`、`obj/`。 | Clean cache: `dotnet clean` each project; remove `bin/` and `obj/`. |

### 窗口尺寸参考 / Window sizes

| 界面 | 尺寸 | 项目 |
|------|------|------|
| 账号登录窗 | 800×600（可缩放） | `bsphp.login.*` |
| 登录控制台 | 1000×580 | `bsphp.login.*` |
| 卡密登录窗 | 700×450 | `bsphp.card.*` |
| 卡密控制面板 | 1000×580 | `bsphp.card.*` |

---

## 功能概要 / 功能概要 / Features

| 简体中文 | 繁體中文 | English |
|---------|---------|---------|
| 完整 BSPHP 加密协议（`parameter=ENC\|RSA`） | 完整 BSPHP 加密協議（`parameter=ENC\|RSA`） | Full BSPHP crypto (`parameter=ENC\|RSA`) |
| 登录/卡密常用 API 强类型封装 | 登入/卡密常用 API 強類型封裝 | Typed API wrappers for login/card |
| 登录成功自动更新 `SeSsL` | 登入成功自動更新 `SeSsL` | Session `SeSsL` updated on login success |
| 控制面板自动心跳（`timeout.lg` / `timeout.ic`） | 控制面板自動心跳（`timeout.lg` / `timeout.ic`） | Auto heartbeat on control panel |
| 机器码：Windows `MachineGuid` 或持久化 UUID | 機器碼：Windows `MachineGuid` 或持久化 UUID | Machine ID via `MachineGuid` or persisted UUID |

各子项目另有 `README.md` 可查看更细的页面说明。

Each sub-project also has its own `README.md` for page-level details.
