优化:根据新的API优化框架代码

This commit is contained in:
ivan 2026-04-02 18:40:31 +08:00
parent e77f5f45b7
commit bdab80b2bd
16 changed files with 730 additions and 90 deletions

View File

@ -77,7 +77,7 @@ void main() {
```
调用层 (原始字段)
ProxyClient.request()
ProxyClient.request()(自动加 `pkg`;默认加 `User_token`
字段映射 (原始 → V2)
@ -86,6 +86,10 @@ AES 加密
发送请求
```
**请求头**`ProxyClient` 会将 [AppConfig.packageName] 写入映射后的包名字段(原始名 `pkg`);若已设置用户 token默认还会写入 `User_token`。**`UserApi.fast_login` 等无需登录态接口**内部使用 `includeUserTokenInHeader: false`,避免把旧 token 打进 `filter_type`。其余请求也可在直接调用 `ProxyClient.request` 时传入该参数。
**请求体**:各 `*Api` 方法使用与《客户端指南》解密表一致的**原始字段名**(如 `referer``deviceId``fileUrls` / `contentType` / `content`)。
### 3.2 响应流程
```
@ -131,9 +135,10 @@ AES 解密
final res = await UserApi.fastLogin(
deviceId: '设备ID',
sign: 'MD5(deviceId)大写',
app: 'HAndroid', // 必填HIOS / HAndroid
referer: '归因来源', // 可选
ch: '渠道号', // 可选
type: '类型', // 可选
type: 'fb', // 可选;未传时默认 fb
);
if (res.isSuccess) {
@ -157,9 +162,17 @@ if (res.isSuccess) {
#### 5.1.2 getCommonInfo - 获取用户通用信息
```dart
final config = ApiClient.instance.config;
final backendApp = defaultTargetPlatform == TargetPlatform.iOS
? config.backendAppTypeIOS
: config.backendAppTypeAndroid;
final res = await UserApi.getCommonInfo(
app: '应用ID',
app: backendApp, // 必填HIOS / HAndroid 等与后端约定
pkg: config.packageName, // 必填:包名
userId: '用户ID', // 可选
deviceId: '设备ID', // 可选
// client / ch / inviteBy / clientId 可选
);
if (res.isSuccess) {
@ -173,7 +186,7 @@ if (res.isSuccess) {
```dart
final res = await UserApi.getAccount(
app: '应用ID',
app: 'HAndroid',
userId: '用户ID', // 可选
);
@ -191,6 +204,46 @@ if (res.isSuccess) {
- `isVip`: 是否 VIP
- `freeTimes`: 免费次数
#### 5.1.4 getAppLanguage - App 语言配置
`GET /v1/config/app-language`(需登录)
```dart
final res = await UserApi.getAppLanguage(
pkg: ApiClient.instance.config.packageName,
lang: 'en', // 可选
);
```
**返回实体**: `AppLanguageConfigResponse``config` 为语言配置 JSON 字符串)
#### 5.1.5 getCreditsPage - 积分分页流水
`ImageApi.getCreditsPageInfo` 相同,路径 `GET /v1/user/credits-page`
```dart
final res = await UserApi.getCreditsPage(page: '1', size: '10', type: '1');
```
#### 5.1.6 getUserPayments - 用户支付记录
```dart
final res = await UserApi.getUserPayments(
app: backendApp,
userId: '用户ID',
);
```
**返回实体**: `UserPaymentsListResponse``items`: `UserPaymentRecord` 列表)
#### 5.1.7 getUnreadMessageCount - 未读消息数
```dart
final res = await UserApi.getUnreadMessageCount(types: '类型列表'); // types 可选
```
**返回实体**: `UnreadMessageCountResponse`
---
### 5.2 PaymentApi - 支付相关
@ -199,7 +252,8 @@ if (res.isSuccess) {
```dart
final res = await PaymentApi.getGooglePayActivities(
app: '应用ID', // 可选
app: 'HAndroid', // 可选;默认 `AppConfig.backendAppTypeAndroid`
client: '客户端', // 可选
country: '国家', // 可选
);
@ -226,7 +280,7 @@ if (res.isSuccess) {
```dart
final res = await PaymentApi.getPaymentMethods(
activityId: '活动ID',
activityId: 12345, // int与接口一致
country: '国家', // 可选
);
@ -252,7 +306,7 @@ if (res.isSuccess) {
```dart
final res = await PaymentApi.createPayment(
app: '应用ID',
app: 'HAndroid', // HIOS / HAndroid
userId: '用户ID',
activityId: '活动ID',
paymentMethod: '支付方式',
@ -271,7 +325,24 @@ if (res.isSuccess) {
- `payUrl`: 支付链接
- `status`: 状态
#### 5.2.4 getOrderDetail - 获取订单详情
#### 5.2.4 getPaymentDetailList - 支付订单列表
`GET /v1/payment/getPaymentDetailList`
```dart
final res = await PaymentApi.getPaymentDetailList(
app: 'HAndroid',
userId: '用户ID',
paymentMethod: 'GOOGLEPAY', // 可选
filterStatus: 'SUCCESS', // 可选
);
```
**返回实体**: `PaymentOrderListResponse``orders`: `PaymentOrderSummary` 列表)
#### 5.2.5 getOrderDetail - 获取订单详情
Query 使用原始字段 `id`(值为订单/支付 ID
```dart
final res = await PaymentApi.getOrderDetail(
@ -290,7 +361,7 @@ if (res.isSuccess) {
- `status`: 状态
- `amount`: 金额
#### 5.2.5 googlepay - Google Pay 回调
#### 5.2.6 googlepay - Google Pay 回调
```dart
final res = await PaymentApi.googlepay(
@ -410,26 +481,29 @@ if (res.isSuccess) {
#### 5.3.6 getCreditsPageInfo - 获取积分页面信息
对应 `GET /v1/user/credits-page`(与 `UserApi.getCreditsPage` 相同)。
```dart
final res = await ImageApi.getCreditsPageInfo(
app: '应用ID',
userId: '用户ID', // 可选
ch: '渠道', // 可选
page: '1',
size: '10',
type: '1',
);
// 或UserApi.getCreditsPage(page: '1', size: '10', type: '1');
if (res.isSuccess) {
final info = res.data!;
final credits = info.credits;
final freeTimes = info.freeTimes;
final isVip = info.isVip;
final total = info.total;
final records = info.records;
final credits = info.credits; // 若后端仍返回单屏字段则可用
}
```
**返回实体**: `CreditsPageInfoResponse`
- `credits`: 积分
- `freeTimes`: 免费次数
- `isVip`: 是否 VIP
- `vipExpireTime`: VIP 过期时间
- `total` / `current` / `pages` / `size` / `records`: 分页与流水(新接口)
- `credits` / `freeTimes` / `isVip` / `vipExpireTime`: 兼容旧字段
- `records` 项见 `CreditRecordItem`
---
@ -587,6 +661,7 @@ class AuthService {
final res = await UserApi.fastLogin(
deviceId: deviceId,
sign: sign,
app: 'HAndroid', // 或 AppConfig.backendAppTypeAndroid / IOS
referer: 'organic',
);
@ -613,7 +688,7 @@ class PaymentService {
}
// 2. 获取支付方式
static Future<List<PaymentMethodItem>> getPaymentMethods(String activityId) async {
static Future<List<PaymentMethodItem>> getPaymentMethods(int activityId) async {
final res = await PaymentApi.getPaymentMethods(activityId: activityId);
return res.data?.paymentMethods ?? [];
}
@ -625,7 +700,7 @@ class PaymentService {
required String paymentMethod,
}) async {
final res = await PaymentApi.createPayment(
app: ApiClient.instance.config.appId,
app: ApiClient.instance.config.backendAppTypeAndroid,
userId: userId,
activityId: activityId,
paymentMethod: paymentMethod,

View File

@ -47,15 +47,13 @@
### 4.1 接口
```dart
// Android
// Androidapp 默认 backendAppTypeAndroid可传 client
final res = await PaymentApi.getGooglePayActivities(
app: '应用ID', // 可选
country: '国家', // 可选
);
// iOS
// iOSapp 默认 backendAppTypeIOS
final res = await PaymentApi.getApplePayActivities(
app: '应用ID', // 可选
country: '国家', // 可选
);
```
@ -85,7 +83,7 @@ class PaymentProductItem {
```dart
final res = await PaymentApi.getPaymentMethods(
activityId: '活动ID',
activityId: 12345, // int
country: '国家', // 可选
);
@ -104,7 +102,7 @@ if (res.isSuccess) {
```dart
final res = await PaymentApi.createPayment(
app: '应用ID',
app: 'HAndroid', // HIOS / HAndroid
userId: '用户ID',
activityId: '活动ID',
paymentMethod: '支付方式',
@ -132,7 +130,7 @@ if (res.isSuccess) {
```dart
// 1. 创建订单(直接走谷歌支付)
final createRes = await PaymentApi.createPayment(
app: '应用ID',
app: 'HAndroid',
userId: '用户ID',
activityId: '活动ID',
paymentMethod: 'GooglePay',
@ -232,6 +230,7 @@ class GooglePayCallbackResponse {
| `getApplePayActivities` | GET | `PaymentProductsResponse` |
| `getPaymentMethods` | POST | `PaymentMethodsResponse` |
| `createPayment` | POST | `CreatePaymentResponse` |
| `getPaymentDetailList` | GET | `PaymentOrderListResponse` |
| `getOrderDetail` | GET | `OrderDetailResponse` |
| `googlepay` | POST | `GooglePayCallbackResponse` |
@ -250,7 +249,7 @@ class GooglePayCallbackResponse {
| 活动 ID | activityId | - |
| 支付方式 | paymentMethod | - |
| 支付子类型 | paymentType | - |
| 订单 ID | orderId | orderId |
| 订单 / 支付 ID(详情 query | `id`Dart 仍用参数名 orderId | orderId |
| 购买签名 | signature | - |
| 购买数据 | purchaseData | - |
| 商品 ID | - | productId |

View File

@ -102,12 +102,20 @@ class ProxyClient {
/// [headers][queryParams][body] 使****
/// [AppConfig.fieldMapping] V2
/// data V2
///
/// ****
/// - [AppConfig.packageName] `pkg` `stakeholder`
/// - [userToken] [includeUserTokenInHeader] true `User_token`
///
/// **** `includeUserTokenInHeader: false`
/// token `filter_type`
Future<ApiResponse> request({
required String path,
required String method,
Map<String, String>? headers,
Map<String, String>? queryParams,
Map<String, dynamic>? body,
bool includeUserTokenInHeader = true,
}) async {
final pk = config.proxyKeys;
final mapping = config.fieldMapping;
@ -116,7 +124,9 @@ class ProxyClient {
if (config.packageName.isNotEmpty) {
headersMap[mapping.headerPackageNameField] = config.packageName;
}
if (userToken != null && userToken!.isNotEmpty) {
if (includeUserTokenInHeader &&
userToken != null &&
userToken!.isNotEmpty) {
headersMap[mapping.headerUserTokenField] = userToken!;
}
headersMap = mapping.mapRequest(headersMap);
@ -168,6 +178,8 @@ class ProxyClient {
///
/// [headers][queryParams][body] 使****
/// [entityFactory] data
///
/// [request] [includeUserTokenInHeader]
Future<EntityResponse<T>> requestEntity<T extends Entity>({
required String path,
required String method,
@ -175,6 +187,7 @@ class ProxyClient {
Map<String, String>? headers,
Map<String, String>? queryParams,
Map<String, dynamic>? body,
bool includeUserTokenInHeader = true,
}) async {
final response = await request(
path: path,
@ -182,6 +195,7 @@ class ProxyClient {
headers: headers,
queryParams: queryParams,
body: body,
includeUserTokenInHeader: includeUserTokenInHeader,
);
if (response.isSuccess && response.data is Map<String, dynamic>) {

View File

@ -28,6 +28,9 @@ const FieldMapping petsHeroAIFieldMapping = FieldMapping({
// === ===
'activityId': 'warrior',
'country': 'vambrace',
'client': 'filter',
'id': 'timing',
'filterStatus': 'quest',
'orderId': 'federation',
'payUrl': 'convert',
'productId': 'helm',
@ -51,6 +54,8 @@ const FieldMapping petsHeroAIFieldMapping = FieldMapping({
'cursor': 'platoon',
'declaration': 'declaration',
'quest': 'quest',
'imgCount': 'indicator',
'aspectRatio': 'caption',
'ext': 'nexus',
'imgUrl': 'congregation',
'poseId': 'profit',

View File

@ -368,13 +368,67 @@ class MyTasksResponse extends Entity {
};
}
///
/// `/v1/user/credits-page` records
class CreditRecordItem extends Entity {
CreditRecordItem({
this.subBusinessType,
this.credits,
this.createTime,
this.businessId,
this.type,
this.businessType,
});
final String? subBusinessType;
final int? credits;
final int? createTime;
final String? businessId;
final int? type;
final String? businessType;
static int? _toInt(dynamic v) {
if (v == null) return null;
if (v is int) return v;
if (v is num) return v.toInt();
if (v is String && v.isNotEmpty) return int.tryParse(v);
return null;
}
@override
factory CreditRecordItem.fromJson(Map<String, dynamic> json) {
return CreditRecordItem(
subBusinessType: json['subBusinessType'] as String?,
credits: _toInt(json['credits']),
createTime: _toInt(json['createTime']),
businessId: json['businessId'] as String?,
type: _toInt(json['type']),
businessType: json['businessType'] as String?,
);
}
@override
Map<String, dynamic> toJson() => {
'subBusinessType': subBusinessType,
'credits': credits,
'createTime': createTime,
'businessId': businessId,
'type': type,
'businessType': businessType,
};
}
/// + `/v1/user/credits-page`
class CreditsPageInfoResponse extends Entity {
CreditsPageInfoResponse({
this.credits,
this.freeTimes,
this.vipExpireTime,
this.isVip,
this.total,
this.current,
this.pages,
this.size,
this.records,
});
final int? credits;
@ -382,13 +436,43 @@ class CreditsPageInfoResponse extends Entity {
final String? vipExpireTime;
final bool? isVip;
///
final int? total;
///
final int? current;
///
final int? pages;
///
final int? size;
final List<CreditRecordItem>? records;
static int? _toInt(dynamic v) {
if (v == null) return null;
if (v is int) return v;
if (v is num) return v.toInt();
if (v is String && v.isNotEmpty) return int.tryParse(v);
return null;
}
@override
factory CreditsPageInfoResponse.fromJson(Map<String, dynamic> json) {
final recList = json['records'] as List<dynamic>?;
return CreditsPageInfoResponse(
credits: json['credits'] as int?,
freeTimes: json['freeTimes'] as int?,
credits: _toInt(json['credits']),
freeTimes: _toInt(json['freeTimes']),
vipExpireTime: json['vipExpireTime'] as String?,
isVip: json['isVip'] as bool?,
isVip: json['isVip'] is bool ? json['isVip'] as bool? : null,
total: _toInt(json['total']),
current: _toInt(json['current']),
pages: _toInt(json['pages']),
size: _toInt(json['size']),
records: recList
?.map((e) => CreditRecordItem.fromJson(e as Map<String, dynamic>))
.toList(),
);
}
@ -398,5 +482,10 @@ class CreditsPageInfoResponse extends Entity {
'freeTimes': freeTimes,
'vipExpireTime': vipExpireTime,
'isVip': isVip,
'total': total,
'current': current,
'pages': pages,
'size': size,
'records': records?.map((e) => e.toJson()).toList(),
};
}

View File

@ -169,10 +169,11 @@ class OrderDetailResponse extends Entity {
@override
factory OrderDetailResponse.fromJson(Map<String, dynamic> json) {
final idRaw = json['orderId'] ?? json['id'];
return OrderDetailResponse(
orderId: json['orderId'] as String?,
orderId: idRaw == null ? null : idRaw.toString(),
status: json['status'] as String?,
amount: json['amount'] as String?,
amount: json['amount'] == null ? null : json['amount'].toString(),
);
}
@ -198,8 +199,9 @@ class GooglePayCallbackResponse extends Entity {
@override
factory GooglePayCallbackResponse.fromJson(Map<String, dynamic> json) {
final idRaw = json['orderId'] ?? json['id'];
return GooglePayCallbackResponse(
orderId: json['orderId'] as String?,
orderId: idRaw == null ? null : idRaw.toString(),
status: json['status'] as String?,
creditsAdded: json['creditsAdded'] as bool?,
);
@ -212,3 +214,84 @@ class GooglePayCallbackResponse extends Entity {
'creditsAdded': creditsAdded,
};
}
/// `getPaymentDetailList`
class PaymentOrderSummary extends Entity {
PaymentOrderSummary({
this.id,
this.status,
this.currency,
this.count,
this.activityId,
this.addCredits,
this.redirectUrl,
});
final String? id;
final String? status;
final String? currency;
final String? count;
final String? activityId;
final bool? addCredits;
final String? redirectUrl;
static String? _str(dynamic v) {
if (v == null) return null;
if (v is String) return v;
return v.toString();
}
@override
factory PaymentOrderSummary.fromJson(Map<String, dynamic> json) {
return PaymentOrderSummary(
id: _str(json['id']),
status: json['status'] as String?,
currency: json['currency'] as String?,
count: _str(json['count']),
activityId: _str(json['activityId']),
addCredits: json['addCredits'] is bool ? json['addCredits'] as bool? : null,
redirectUrl: json['redirectUrl'] as String?,
);
}
@override
Map<String, dynamic> toJson() => {
'id': id,
'status': status,
'currency': currency,
'count': count,
'activityId': activityId,
'addCredits': addCredits,
'redirectUrl': redirectUrl,
};
}
/// `/v1/payment/getPaymentDetailList` data
class PaymentOrderListResponse extends Entity {
PaymentOrderListResponse({required this.orders});
final List<PaymentOrderSummary> orders;
static PaymentOrderListResponse fromDataList(List<dynamic> list) {
return PaymentOrderListResponse(
orders: [
for (final e in list)
PaymentOrderSummary.fromJson(e as Map<String, dynamic>),
],
);
}
@override
factory PaymentOrderListResponse.fromJson(Map<String, dynamic> json) {
final raw = json['orders'] as List<dynamic>?;
if (raw == null) {
return PaymentOrderListResponse(orders: const []);
}
return PaymentOrderListResponse.fromDataList(raw);
}
@override
Map<String, dynamic> toJson() => {
'orders': orders.map((e) => e.toJson()).toList(),
};
}

View File

@ -290,3 +290,167 @@ class AccountResponse extends Entity {
'freeTimes': freeTimes,
};
}
/// `/v1/config/app-language` data
class AppLanguageConfigResponse extends Entity {
AppLanguageConfigResponse({this.config});
/// JSON
final String? config;
@override
factory AppLanguageConfigResponse.fromJson(Map<String, dynamic> json) {
return AppLanguageConfigResponse(
config: json['config'] as String?,
);
}
@override
Map<String, dynamic> toJson() => {'config': config};
}
/// `/v1/user/payments`
class UserPaymentRecord extends Entity {
UserPaymentRecord({
this.amount,
this.payTime,
this.payMethod,
this.currency,
this.payId,
});
final int? amount;
final int? payTime;
final String? payMethod;
final String? currency;
final String? payId;
static int? _toInt(dynamic v) {
if (v == null) return null;
if (v is int) return v;
if (v is num) return v.toInt();
if (v is String && v.isNotEmpty) return int.tryParse(v);
return null;
}
@override
factory UserPaymentRecord.fromJson(Map<String, dynamic> json) {
return UserPaymentRecord(
amount: _toInt(json['amount']),
payTime: _toInt(json['payTime']),
payMethod: json['payMethod'] as String?,
currency: json['currency'] as String?,
payId: json['payId'] as String?,
);
}
@override
Map<String, dynamic> toJson() => {
'amount': amount,
'payTime': payTime,
'payMethod': payMethod,
'currency': currency,
'payId': payId,
};
}
/// `/v1/user/payments`
class UserPaymentsListResponse extends Entity {
UserPaymentsListResponse({required this.items});
final List<UserPaymentRecord> items;
static UserPaymentsListResponse fromDataList(List<dynamic> list) {
return UserPaymentsListResponse(
items: [
for (final e in list)
UserPaymentRecord.fromJson(e as Map<String, dynamic>),
],
);
}
@override
factory UserPaymentsListResponse.fromJson(Map<String, dynamic> json) {
final raw = json['items'] as List<dynamic>?;
if (raw == null) {
return UserPaymentsListResponse(items: const []);
}
return UserPaymentsListResponse.fromDataList(raw);
}
@override
Map<String, dynamic> toJson() => {
'items': items.map((e) => e.toJson()).toList(),
};
}
///
class UnreadCountItem extends Entity {
UnreadCountItem({this.count, this.type});
final int? count;
final String? type;
static int? _toInt(dynamic v) {
if (v == null) return null;
if (v is int) return v;
if (v is num) return v.toInt();
if (v is String && v.isNotEmpty) return int.tryParse(v);
return null;
}
@override
factory UnreadCountItem.fromJson(Map<String, dynamic> json) {
return UnreadCountItem(
count: _toInt(json['count']),
type: json['type'] as String?,
);
}
@override
Map<String, dynamic> toJson() => {
'count': count,
'type': type,
};
}
/// `/v1/user/unread-message-count` data
class UnreadMessageCountResponse extends Entity {
UnreadMessageCountResponse({
this.unreadCountList,
this.totalUnreadCount,
this.lastUpdateTime,
});
final List<UnreadCountItem>? unreadCountList;
final int? totalUnreadCount;
final int? lastUpdateTime;
static int? _toInt(dynamic v) {
if (v == null) return null;
if (v is int) return v;
if (v is num) return v.toInt();
if (v is String && v.isNotEmpty) return int.tryParse(v);
return null;
}
@override
factory UnreadMessageCountResponse.fromJson(Map<String, dynamic> json) {
final raw = json['unreadCountList'] as List<dynamic>?;
return UnreadMessageCountResponse(
unreadCountList: raw
?.map((e) => UnreadCountItem.fromJson(e as Map<String, dynamic>))
.toList(),
totalUnreadCount: _toInt(json['totalUnreadCount']),
lastUpdateTime: _toInt(json['lastUpdateTime']),
);
}
@override
Map<String, dynamic> toJson() => {
'unreadCountList':
unreadCountList?.map((e) => e.toJson()).toList(),
'totalUnreadCount': totalUnreadCount,
'lastUpdateTime': lastUpdateTime,
};
}

View File

@ -201,6 +201,9 @@ abstract class FrameworkAuthService {
if (uid.isEmpty) return;
final config = ApiClient.instance.config;
final backendApp = defaultTargetPlatform == TargetPlatform.iOS
? config.backendAppTypeIOS
: config.backendAppTypeAndroid;
// Adjust
final adjustReferer = await AttributionService.getAdjustReferrer();
@ -210,7 +213,7 @@ abstract class FrameworkAuthService {
: 'android_adjust';
try {
final rAdjust = await UserApi.referrer(
app: config.appId,
app: backendApp,
userId: uid,
referer: adjustReferer,
deviceId: deviceId,
@ -232,7 +235,7 @@ abstract class FrameworkAuthService {
if (playReferrer != null && playReferrer.isNotEmpty) {
try {
final rGg = await UserApi.referrer(
app: config.appId,
app: backendApp,
userId: uid,
referer: playReferrer,
deviceId: deviceId,
@ -252,8 +255,10 @@ abstract class FrameworkAuthService {
//
try {
final commonRes = await UserApi.getCommonInfo(
app: config.appId,
app: backendApp,
pkg: config.packageName,
userId: uid,
deviceId: deviceId,
);
if (commonRes.isSuccess && commonRes.data != null) {
_callbacks?.onCommonInfoLoaded(commonRes.data!);

View File

@ -3,6 +3,8 @@ import '../api/proxy_client.dart';
import '../entities/feedback_entities.dart';
/// / API使
///
/// **Body**`submit``fileUrls``contentType``content`
abstract final class FeedbackApi {
static ProxyClient get _client => ApiClient.instance.proxy;
@ -31,8 +33,8 @@ abstract final class FeedbackApi {
entityFactory: SubmitFeedbackResponse.fromJson,
body: {
'fileUrls': fileUrls,
'content': content,
'contentType': contentType,
'content': content,
},
);
}

View File

@ -3,6 +3,8 @@ import '../api/proxy_client.dart';
import '../entities/image_entities.dart';
/// / API使
///
/// **** `pkg` `User_token` [ProxyClient.request]
abstract final class ImageApi {
static ProxyClient get _client => ApiClient.instance.proxy;
@ -47,13 +49,20 @@ abstract final class ImageApi {
}
///
///
/// **Body**`imgCount` 1`aspectRatio``prompt`
static Future<EntityResponse<CreateTaskResponse>> createTxt2Img({
required String app,
required String prompt,
String? ch,
String? userId,
int imgCount = 1,
String? aspectRatio,
/// [aspectRatio]
String? quest,
}) async {
final ratio = aspectRatio ?? quest;
return _client.requestEntity(
path: '/v1/image/txt2img_create',
method: 'POST',
@ -64,8 +73,8 @@ abstract final class ImageApi {
if (userId != null) 'userId': userId,
},
body: {
'declaration': 1,
if (quest != null) 'quest': quest,
'imgCount': imgCount,
if (ratio != null && ratio.isNotEmpty) 'aspectRatio': ratio,
'prompt': prompt,
},
);
@ -209,21 +218,27 @@ abstract final class ImageApi {
);
}
///
/// `UserApi.getCreditsPage` `GET /v1/user/credits-page`
///
/// [app][userId][ch]
static Future<EntityResponse<CreditsPageInfoResponse>> getCreditsPageInfo({
required String app,
String page = '1',
String size = '10',
String type = '1',
String? app,
String? userId,
String? ch,
}) async {
return _client.requestEntity(
path: '/v1/image/getCreditsPageInfo',
path: '/v1/user/credits-page',
method: 'GET',
entityFactory: CreditsPageInfoResponse.fromJson,
queryParams: {
'app': app,
if (userId != null) 'userId': userId,
if (ch != null) 'ch': ch,
'page': page,
'size': size,
'type': type,
},
);
}
}

View File

@ -3,53 +3,61 @@ import '../api/proxy_client.dart';
import '../entities/payment_entities.dart';
/// API使
///
/// **** `pkg` `User_token`
abstract final class PaymentApi {
static ProxyClient get _client => ApiClient.instance.proxy;
/// Google Android
///
/// `app` [AppConfig.backendAppTypeAndroid] [client][country]
static Future<EntityResponse<PaymentProductsResponse>>
getGooglePayActivities({
String? app,
String? shield,
String? client,
String? country,
String? pkg,
}) async {
final cfg = ApiClient.instance.config;
return _client.requestEntity(
path: '/v1/payment/getGooglePayActivities',
method: 'GET',
entityFactory: PaymentProductsResponse.fromJson,
queryParams: {
'app': app ?? ApiClient.instance.config.appId,
'pkg': pkg ?? ApiClient.instance.config.packageName,
if (shield != null) 'shield': shield,
if (country != null) 'country': country,
'app': app ?? cfg.backendAppTypeAndroid,
'pkg': pkg ?? cfg.packageName,
if (client != null && client.isNotEmpty) 'client': client,
if (country != null && country.isNotEmpty) 'country': country,
},
);
}
/// Apple iOS
///
/// `app` [AppConfig.backendAppTypeIOS]
static Future<EntityResponse<PaymentProductsResponse>> getApplePayActivities({
String? app,
String? shield,
String? client,
String? country,
String? pkg,
}) async {
final cfg = ApiClient.instance.config;
return _client.requestEntity(
path: '/v1/payment/getApplePayActivities',
method: 'GET',
entityFactory: PaymentProductsResponse.fromJson,
queryParams: {
'app': app ?? ApiClient.instance.config.backendAppTypeIOS,
'pkg': pkg ?? ApiClient.instance.config.packageName,
if (shield != null) 'shield': shield,
if (country != null) 'country': country,
'app': app ?? cfg.backendAppTypeIOS,
'pkg': pkg ?? cfg.packageName,
if (client != null && client.isNotEmpty) 'client': client,
if (country != null && country.isNotEmpty) 'country': country,
},
);
}
///
/// body [activityId] int
static Future<EntityResponse<PaymentMethodsResponse>> getPaymentMethods({
required String activityId,
required int activityId,
String? country,
}) async {
return _client.requestEntity(
@ -64,6 +72,13 @@ abstract final class PaymentApi {
}
///
///
/// **Query**`app``userId`
/// **Body** +
/// `lastName``country``expireMonth``accountName``userInfoType`
/// `automaticRenewal``channel``cvcCode``channelType``firstName`
/// `subPaymentMethod``phone``tgOrderId``tgId``name``expireYear`
/// `card``status` `lineage``armor` [FieldMapping]
static Future<EntityResponse<CreatePaymentResponse>> createPayment({
required String app,
required String userId,
@ -72,6 +87,24 @@ abstract final class PaymentApi {
String? paymentType,
String? lineage,
String? armor,
String? lastName,
String? country,
String? expireMonth,
String? accountName,
String? userInfoType,
bool? automaticRenewal,
String? channel,
String? cvcCode,
String? channelType,
String? firstName,
String? subPaymentMethod,
String? phone,
String? tgOrderId,
String? tgId,
String? name,
String? expireYear,
String? card,
String? status,
}) async {
return _client.requestEntity(
path: '/v1/payment/createPayment',
@ -85,13 +118,72 @@ abstract final class PaymentApi {
'paymentMethod': paymentMethod,
if (paymentType != null && paymentType.isNotEmpty)
'paymentType': paymentType,
if (lineage != null) 'lineage': lineage,
if (armor != null) 'armor': armor,
if (lineage != null && lineage.isNotEmpty) 'lineage': lineage,
if (armor != null && armor.isNotEmpty) 'armor': armor,
if (lastName != null && lastName.isNotEmpty) 'lastName': lastName,
if (country != null && country.isNotEmpty) 'country': country,
if (expireMonth != null && expireMonth.isNotEmpty)
'expireMonth': expireMonth,
if (accountName != null && accountName.isNotEmpty)
'accountName': accountName,
if (userInfoType != null && userInfoType.isNotEmpty)
'userInfoType': userInfoType,
if (automaticRenewal != null) 'automaticRenewal': automaticRenewal,
if (channel != null && channel.isNotEmpty) 'channel': channel,
if (cvcCode != null && cvcCode.isNotEmpty) 'cvcCode': cvcCode,
if (channelType != null && channelType.isNotEmpty)
'channelType': channelType,
if (firstName != null && firstName.isNotEmpty) 'firstName': firstName,
if (subPaymentMethod != null && subPaymentMethod.isNotEmpty)
'subPaymentMethod': subPaymentMethod,
if (phone != null && phone.isNotEmpty) 'phone': phone,
if (tgOrderId != null && tgOrderId.isNotEmpty) 'tgOrderId': tgOrderId,
if (tgId != null && tgId.isNotEmpty) 'tgId': tgId,
if (name != null && name.isNotEmpty) 'name': name,
if (expireYear != null && expireYear.isNotEmpty) 'expireYear': expireYear,
if (card != null && card.isNotEmpty) 'card': card,
if (status != null && status.isNotEmpty) 'status': status,
},
);
}
///
/// data
static Future<EntityResponse<PaymentOrderListResponse>>
getPaymentDetailList({
required String app,
String? userId,
String? paymentMethod,
String? filterStatus,
}) async {
final response = await _client.request(
path: '/v1/payment/getPaymentDetailList',
method: 'GET',
queryParams: {
'app': app,
if (userId != null && userId.isNotEmpty) 'userId': userId,
if (paymentMethod != null && paymentMethod.isNotEmpty)
'paymentMethod': paymentMethod,
if (filterStatus != null && filterStatus.isNotEmpty)
'filterStatus': filterStatus,
},
);
if (response.isSuccess && response.data is List) {
return EntityResponse<PaymentOrderListResponse>(
code: response.code,
msg: response.msg,
data: PaymentOrderListResponse.fromDataList(
response.data! as List<dynamic>,
),
);
}
return EntityResponse<PaymentOrderListResponse>(
code: response.code,
msg: response.msg,
data: null,
);
}
/// query 使 `id` / ID
static Future<EntityResponse<OrderDetailResponse>> getOrderDetail({
required String userId,
required String orderId,
@ -102,30 +194,35 @@ abstract final class PaymentApi {
entityFactory: OrderDetailResponse.fromJson,
queryParams: {
'userId': userId,
'orderId': orderId,
'id': orderId,
},
);
}
/// Google
///
/// **Query**`app``userId`
/// **Body**`signature``purchaseData``id``userId`
static Future<EntityResponse<GooglePayCallbackResponse>> googlepay({
required String signature,
required String purchaseData,
required String orderId,
required String userId,
String? app,
}) async {
final cfg = ApiClient.instance.config;
return _client.requestEntity(
path: '/v1/payment/googlepay',
method: 'POST',
entityFactory: GooglePayCallbackResponse.fromJson,
queryParams: {
'app': ApiClient.instance.config.appId,
'app': app ?? cfg.backendAppTypeAndroid,
'userId': userId,
},
body: {
'signature': signature,
'purchaseData': purchaseData,
'orderId': orderId,
'id': orderId,
'userId': userId,
},
);

View File

@ -1,26 +1,30 @@
import '../api/api_client.dart';
import '../api/api_response.dart';
import '../api/proxy_client.dart';
import '../entities/image_entities.dart';
import '../entities/user_entities.dart';
/// API使
///
/// **** [UserApi.fastLogin] [ProxyClient]
/// `pkg` `User_token` token fast_login `pkg` token
///
/// ****使**** `referer``deviceId`
abstract final class UserApi {
static ProxyClient get _client => ApiClient.instance.proxy;
///
/// [deviceId] ID ()
/// [sign] MD5(deviceId)32 ()
/// [referer]
/// [ch]
/// [type] referrer类型 (af/fb/gg/ios_adjust/android_adjust)
/// [app] (iOS: HIOS / Android: HAndroid)
///
/// **** `pkg` `User_token`
/// **Query**`app``type` `fb``pkg``ch`
/// **Body**`referer``sign``deviceId`
static Future<EntityResponse<FastLoginResponse>> fastLogin({
required String deviceId,
required String sign,
required String app,
String? referer,
String? ch,
String? type,
String? app,
}) async {
final config = ApiClient.instance.config;
return _client.requestEntity(
@ -28,20 +32,25 @@ abstract final class UserApi {
method: 'POST',
entityFactory: FastLoginResponse.fromJson,
queryParams: {
if (ch != null) 'ch': ch,
if (ch != null && ch.isNotEmpty) 'ch': ch,
'pkg': config.packageName,
if (type != null) 'type': type,
if (app != null) 'app': app,
'type': type ?? 'fb',
'app': app,
},
body: {
'referer': referer ?? '',
'sign': sign,
'deviceId': deviceId,
},
includeUserTokenInHeader: false,
);
}
///
///
/// ****`pkg``User_token`
/// **Query**`app``userId``type` `fb``pkg`
/// **Body**`referer``deviceId`
static Future<ApiResponse> referrer({
required String app,
required String userId,
@ -56,7 +65,7 @@ abstract final class UserApi {
queryParams: {
'app': app,
'userId': userId,
if (type != null) 'type': type,
'type': type ?? 'fb',
'pkg': pkg ?? ApiClient.instance.config.packageName,
},
body: {
@ -67,15 +76,20 @@ abstract final class UserApi {
}
///
///
/// query [AppConfig.fieldMapping]
/// - [app] iOS `HIOS` / Android `HAndroid` fast_login
/// - [pkg]
/// - [client][userId][ch][inviteBy][deviceId][clientId]
static Future<EntityResponse<CommonInfoResponse>> getCommonInfo({
required String app,
String? shield,
required String pkg,
String? client,
String? userId,
String? ch,
String? item,
String? inviteBy,
String? deviceId,
String? gauntlet,
String? pkg,
String? clientId,
}) async {
return _client.requestEntity(
path: '/v1/user/common_info',
@ -83,13 +97,29 @@ abstract final class UserApi {
entityFactory: CommonInfoResponse.fromJson,
queryParams: {
'app': app,
if (shield != null) 'shield': shield,
if (userId != null) 'userId': userId,
if (ch != null) 'ch': ch,
if (item != null) 'item': item,
if (deviceId != null) 'deviceId': deviceId,
if (gauntlet != null) 'gauntlet': gauntlet,
if (pkg != null) 'pkg': pkg,
'pkg': pkg,
if (client != null && client.isNotEmpty) 'client': client,
if (userId != null && userId.isNotEmpty) 'userId': userId,
if (ch != null && ch.isNotEmpty) 'ch': ch,
if (inviteBy != null && inviteBy.isNotEmpty) 'inviteBy': inviteBy,
if (deviceId != null && deviceId.isNotEmpty) 'deviceId': deviceId,
if (clientId != null && clientId.isNotEmpty) 'clientId': clientId,
},
);
}
/// App
static Future<EntityResponse<AppLanguageConfigResponse>> getAppLanguage({
required String pkg,
String? lang,
}) async {
return _client.requestEntity(
path: '/v1/config/app-language',
method: 'GET',
entityFactory: AppLanguageConfigResponse.fromJson,
queryParams: {
'pkg': pkg,
if (lang != null && lang.isNotEmpty) 'lang': lang,
},
);
}
@ -110,6 +140,68 @@ abstract final class UserApi {
);
}
/// `GET /v1/user/credits-page`
static Future<EntityResponse<CreditsPageInfoResponse>> getCreditsPage({
String page = '1',
String size = '10',
String type = '1',
}) async {
return _client.requestEntity(
path: '/v1/user/credits-page',
method: 'GET',
entityFactory: CreditsPageInfoResponse.fromJson,
queryParams: {
'page': page,
'size': size,
'type': type,
},
);
}
/// `GET /v1/user/payments`data
static Future<EntityResponse<UserPaymentsListResponse>> getUserPayments({
required String app,
String? userId,
}) async {
final response = await _client.request(
path: '/v1/user/payments',
method: 'GET',
queryParams: {
'app': app,
if (userId != null && userId.isNotEmpty) 'userId': userId,
},
);
if (response.isSuccess && response.data is List) {
return EntityResponse<UserPaymentsListResponse>(
code: response.code,
msg: response.msg,
data: UserPaymentsListResponse.fromDataList(
response.data! as List<dynamic>,
),
);
}
return EntityResponse<UserPaymentsListResponse>(
code: response.code,
msg: response.msg,
data: null,
);
}
/// `types`
static Future<EntityResponse<UnreadMessageCountResponse>>
getUnreadMessageCount({
String? types,
}) async {
return _client.requestEntity(
path: '/v1/user/unread-message-count',
method: 'GET',
entityFactory: UnreadMessageCountResponse.fromJson,
queryParams: {
if (types != null && types.isNotEmpty) 'types': types,
},
);
}
///
static Future<ApiResponse> deleteAccount({
required String app,