This commit is contained in:
zhx 2026-06-23 11:16:07 +08:00
parent 467b582ddd
commit 806692e7f9
2 changed files with 39 additions and 267 deletions

39
app/da_huwaa.html Normal file
View File

@ -0,0 +1,39 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Delete Huwaa Voice Party Account | Huwaa Voice Party</title>
<meta name="description" content="This page explains how Huwaa Voice Party users can request permanent deletion of their account and associated data.">
<link rel="canonical" href="https://h5.haiyihy.com/Huwaadelete-account.html">
</head>
<body>
<h1>Delete Huwaa Voice Party Account</h1>
<p>Effective date: 2026-04-13</p>
<p>Contact: chekrindo@gmail.com / +85247410298</p>
<p><a href="mailto:chekrindo@gmail.com?subject=Delete%20Huwaa%20Voice%20Party%20Account">Start a deletion request by email</a></p>
<p>This page explains how Huwaa Voice Party users can request permanent deletion of their account and associated data.</p>
<h2>1. Who can use this page</h2>
<p>Use this page if you created a Huwaa Voice Party account and want to request permanent deletion of that account and the associated user data managed by Huwaa Voice Party.</p><p>You can submit a deletion request even if you no longer have access to the Huwaa Voice Party app on your device.</p>
<h2>2. How to submit a deletion request</h2>
<p>Send your deletion request by email to chekrindo@gmail.com.</p><p>Please use the subject line: Delete Huwaa Voice Party Account.</p>
<p>- Your Huwaa Voice Party UID, if available.</p><p>- Your registered email address or phone number.</p><p>- Your Huwaa Voice Party nickname or profile name.</p><p>- A clear statement that you want your Huwaa Voice Party account and associated data to be deleted.</p>
<h2>3. Identity verification</h2>
<p>To protect account security and prevent unauthorized deletion, we may ask you to complete a reasonable identity-verification step before processing your request.</p>
<h2>4. What will be deleted</h2>
<p>After your request is verified and approved, we will delete your Huwaa Voice Party account and the associated account data that is managed in our systems, including profile information and other user data linked to that account, unless retention is required for legitimate reasons described below.</p>
<h2>5. Data that may be retained</h2>
<p>Certain records may be retained for a limited period where reasonably necessary for fraud prevention, abuse handling, dispute resolution, financial recordkeeping, tax, security, or legal and regulatory compliance.</p>
<h2>6. Processing time</h2>
<p>We aim to complete verified deletion requests within 7 business days, although certain cases may require additional time if further verification or compliance review is necessary.</p>
<h2>7. Contact</h2>
<p>If you have questions about account deletion or personal-data handling, contact chekrindo@gmail.com or call +85247410298.</p>
</body>
</html>

View File

@ -1,267 +0,0 @@
# Flutter H5 排行榜对接文档
本文说明 Flutter App 如何打开 H5 排行榜、向 H5 传递登录态,以及接收 H5 通过 JSBridge 发回的导航事件。
## 入口地址
本地开发:
```text
http://127.0.0.1:30000/rank/index.html?env=local&token={access_token}&app_code=lalu
```
测试环境:
```text
https://{h5-test-domain}/rank/index.html?env=test&token={access_token}&app_code=lalu
```
线上环境:
```text
https://{h5-domain}/rank/index.html?token={access_token}&app_code=lalu
```
`env` 规则:
| 参数 | 说明 |
| ----------- | -------------------------------------------------------- |
| 不传 | H5 请求 `https://api.global-interaction.com/` |
| `env=test` | H5 请求 `https://api-test.global-interaction.com/` |
| `env=local` | H5 请求 `http://localhost:13000/`,用于本机 gateway 联调 |
## URL 参数
| 参数 | 必填 | 说明 |
| -------------- | ---- | --------------------------------------------------------------------------------- |
| `token` | 是 | App 登录后拿到的 access token。H5 会作为 `Authorization: Bearer <token>` 调后端。 |
| `access_token` | 否 | `token` 的兼容别名。 |
| `accessToken` | 否 | `token` 的兼容别名。 |
| `app_code` | 是 | App 编码,当前传 `lalu`。H5 会作为 `X-App-Code` 请求头。 |
| `appCode` | 否 | `app_code` 的兼容别名。 |
| `env` | 否 | API 环境切换,见上表。 |
H5 启动后会调用:
```http
GET /api/v1/users/me/overview
Authorization: Bearer <token>
X-App-Code: lalu
```
这个接口用于确认登录态并缓存当前用户信息。排行榜数据使用同一个 token 和 app code 请求。
## H5 页面能力
排行榜页面地址:
```text
/rank/index.html
```
页面内包含三个榜单,通过 tab 切换:
| H5 Tab | 后端 `board_type` | 说明 |
| -------- | ----------------- | ---------------------------- |
| `Wealth` | `sent` | 财富榜,按用户送礼总金币排行 |
| `Room` | `room` | 房间榜,按房间收礼总金币排行 |
| `Charm` | `received` | 魅力榜,按用户收礼总金币排行 |
时间维度:
| H5 Tab | 后端 `period` |
| --------- | ------------- |
| `Daily` | `today` |
| `Weekly` | `week` |
| `Monthly` | `month` |
排行榜接口:
```http
GET /api/v1/activities/user-leaderboards?board_type=sent&period=today&page=1&page_size=20
Authorization: Bearer <token>
X-App-Code: lalu
```
H5 会分页加载,`page_size=20`。如果无 token 或接口失败,页面会展示 Figma 默认占位数据,不阻塞页面打开。
## Flutter JSBridge
H5 会按以下优先级尝试发送消息:
1. `window.flutter_inappwebview.callHandler("HyAppBridge", action, payload)`
2. `window.HyAppBridgeChannel.postMessage(jsonString)`
3. `window.FlutterBridge.postMessage(jsonString)`
4. `window.webkit.messageHandlers.HyAppBridge.postMessage({ action, payload })`
Flutter 只需要实现其中一种即可。推荐统一注册 `HyAppBridge`
### 消息格式
`flutter_inappwebview.callHandler`postMessage 的消息是 JSON 字符串:
```json
{
"action": "openUser",
"payload": {
"user_id": "10001"
}
}
```
### H5 发出的 action
| action | payload | 触发场景 | Flutter 行为 |
| -------------- | -------------------------- | --------------------------------- | -------------------------------------------------- |
| `ready` | `{ "page": "rank" }` | H5 初始化完成 | 可关闭加载态 |
| `back` | `{}` | 用户点击左上角返回 | 关闭 WebView 或返回上一页 |
| `openUser` | `{ "user_id": "10001" }` | 点击财富榜/魅力榜用户头像、榜单项 | 打开用户详情页 |
| `openRoom` | `{ "room_id": "room_id" }` | 点击房间榜房间头像、榜单项 | 进入或打开房间详情 |
| `openRankNote` | `{ "board_type": "sent" }` | 点击右上角问号 | 当前 H5 已内置说明页Flutter 可只打点,不需要跳转 |
`board_type` 取值:
| 值 | 说明 |
| ---------- | ------ |
| `sent` | 财富榜 |
| `room` | 房间榜 |
| `received` | 魅力榜 |
## Flutter 示例
### flutter_inappwebview
```dart
final url = Uri.parse(
'http://127.0.0.1:30000/rank/index.html'
'?env=local'
'&token=${Uri.encodeComponent(accessToken)}'
'&app_code=lalu',
);
InAppWebView(
initialUrlRequest: URLRequest(url: WebUri(url.toString())),
onWebViewCreated: (controller) {
controller.addJavaScriptHandler(
handlerName: 'HyAppBridge',
callback: (args) async {
final action = args.isNotEmpty ? args[0] as String : '';
final payload = args.length > 1 && args[1] is Map
? Map<String, dynamic>.from(args[1] as Map)
: <String, dynamic>{};
switch (action) {
case 'ready':
// 关闭 loading
break;
case 'back':
Navigator.of(context).maybePop();
break;
case 'openUser':
final userId = payload['user_id']?.toString() ?? '';
if (userId.isNotEmpty) {
// TODO: 打开用户详情页
}
break;
case 'openRoom':
final roomId = payload['room_id']?.toString() ?? '';
if (roomId.isNotEmpty) {
// TODO: 打开房间或房间详情页
}
break;
case 'openRankNote':
// H5 内部已展示说明页,这里可做埋点
break;
}
return {'ok': true};
},
);
},
)
```
### webview_flutter JavaScriptChannel
如果使用 `webview_flutter`,可以注入 `HyAppBridgeChannel`
```dart
final controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel(
'HyAppBridgeChannel',
onMessageReceived: (message) {
final data = jsonDecode(message.message) as Map<String, dynamic>;
final action = data['action']?.toString() ?? '';
final payload = data['payload'] is Map
? Map<String, dynamic>.from(data['payload'] as Map)
: <String, dynamic>{};
switch (action) {
case 'ready':
break;
case 'back':
Navigator.of(context).maybePop();
break;
case 'openUser':
final userId = payload['user_id']?.toString() ?? '';
break;
case 'openRoom':
final roomId = payload['room_id']?.toString() ?? '';
break;
}
},
)
..loadRequest(Uri.parse(rankUrl));
```
## 后端依赖
H5 依赖以下 Gateway HTTP 接口:
| 接口 | 说明 |
| ------------------------------------------ | ----------------------------- |
| `GET /api/v1/users/me/overview` | 解析 token 后获取当前用户信息 |
| `GET /api/v1/activities/user-leaderboards` | 获取排行榜 |
业务接口返回 envelope
```json
{
"code": "OK",
"message": "ok",
"request_id": "req_xxx",
"data": {}
}
```
H5 也兼容旧的 `code: 0` 成功格式。
## 本地联调
`hyapp-h5` 目录运行:
```bash
make run
```
默认打开:
```text
http://127.0.0.1:30000/rank/index.html?env=local
```
Flutter 真机调本机服务时,`env=local` 对 H5 来说会请求 `http://localhost:13000/`。如果 WebView 运行在真机上,`localhost` 指向手机自身,不是开发机。真机联调建议:
1. 使用测试环境 `env=test`
2. 或把 H5/API 部署到同一局域网可访问地址。
3. 或后续给 H5 增加可配置 `api_base` 参数。
## 验收点
1. Flutter 打开 H5 时带上 `token``app_code`
2. H5 首次加载后发出 `ready`
3. 点击左上角返回Flutter 收到 `back` 并关闭 WebView。
4. 点击财富榜/魅力榜用户Flutter 收到 `openUser`
5. 点击房间榜房间Flutter 收到 `openRoom`
6. 切换 `Wealth / Room / Charm``Daily / Weekly / Monthly`H5 正确请求排行榜接口。
7. 点击右上角问号H5 展示说明页,返回后仍停留在排行榜页。