add
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
import '../core/network/api_client.dart';
|
||||
import '../core/network/endpoints.dart';
|
||||
|
||||
/// 充值套餐档位(《03-接口文档》8.1,后台实时可配,前端不硬编码)
|
||||
class RechargePackage {
|
||||
const RechargePackage({
|
||||
required this.id,
|
||||
required this.amountYuan,
|
||||
required this.points,
|
||||
this.bonus = 0,
|
||||
});
|
||||
|
||||
final int id;
|
||||
final int amountYuan;
|
||||
final int points;
|
||||
|
||||
/// 赠送积分(角标「赠 x 积分」)
|
||||
final int bonus;
|
||||
|
||||
/// 到账总积分 = 基础 + 赠送
|
||||
int get totalPoints => points + bonus;
|
||||
|
||||
factory RechargePackage.fromJson(Map<String, dynamic> json) =>
|
||||
RechargePackage(
|
||||
id: (json['id'] as num).toInt(),
|
||||
amountYuan: (json['amount_yuan'] as num).toInt(),
|
||||
points: (json['points'] as num).toInt(),
|
||||
bonus: (json['bonus'] as num?)?.toInt() ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
/// 自定义金额配置
|
||||
class CustomRechargeConfig {
|
||||
const CustomRechargeConfig({
|
||||
this.enabled = false,
|
||||
this.minYuan = 1,
|
||||
this.maxYuan = 10000,
|
||||
this.pointsPerYuan = 10,
|
||||
});
|
||||
|
||||
final bool enabled;
|
||||
final int minYuan;
|
||||
final int maxYuan;
|
||||
final int pointsPerYuan;
|
||||
|
||||
bool inRange(int yuan) => yuan >= minYuan && yuan <= maxYuan;
|
||||
|
||||
factory CustomRechargeConfig.fromJson(Map<String, dynamic> json) =>
|
||||
CustomRechargeConfig(
|
||||
enabled: json['enabled'] as bool? ?? false,
|
||||
minYuan: (json['min_yuan'] as num?)?.toInt() ?? 1,
|
||||
maxYuan: (json['max_yuan'] as num?)?.toInt() ?? 10000,
|
||||
pointsPerYuan: (json['points_per_yuan'] as num?)?.toInt() ?? 10,
|
||||
);
|
||||
}
|
||||
|
||||
/// 支付方式(1支付宝 2微信 3USDT)
|
||||
class PayMethod {
|
||||
const PayMethod({required this.method, required this.name});
|
||||
|
||||
final int method;
|
||||
final String name;
|
||||
|
||||
bool get isUsdt => method == 3;
|
||||
|
||||
factory PayMethod.fromJson(Map<String, dynamic> json) => PayMethod(
|
||||
method: (json['method'] as num).toInt(),
|
||||
name: json['name'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
/// 8.1 套餐列表响应
|
||||
class PackagesResult {
|
||||
const PackagesResult({
|
||||
this.packages = const [],
|
||||
this.custom = const CustomRechargeConfig(),
|
||||
this.payMethods = const [],
|
||||
this.usdtRate = 0,
|
||||
});
|
||||
|
||||
final List<RechargePackage> packages;
|
||||
final CustomRechargeConfig custom;
|
||||
final List<PayMethod> payMethods;
|
||||
final double usdtRate;
|
||||
|
||||
factory PackagesResult.fromJson(Map<String, dynamic> json) => PackagesResult(
|
||||
packages: ((json['packages'] as List?) ?? const [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map(RechargePackage.fromJson)
|
||||
.toList(),
|
||||
custom: CustomRechargeConfig.fromJson(
|
||||
(json['custom'] as Map<String, dynamic>?) ?? const {},
|
||||
),
|
||||
payMethods: ((json['pay_methods'] as List?) ?? const [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map(PayMethod.fromJson)
|
||||
.toList(),
|
||||
usdtRate: (json['usdt_rate'] as num?)?.toDouble() ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
/// 8.2 创建充值订单响应
|
||||
/// 支付宝/微信:pay_params 供 SDK 调起;USDT:地址 + 金额(含尾差)+ 网络
|
||||
class RechargeOrderInfo {
|
||||
const RechargeOrderInfo({
|
||||
required this.orderNo,
|
||||
required this.payMethod,
|
||||
required this.amountYuan,
|
||||
required this.points,
|
||||
this.expireAt = '',
|
||||
this.payParams = const {},
|
||||
this.usdtRate,
|
||||
this.usdtAmount,
|
||||
this.receiveAddress,
|
||||
this.network,
|
||||
});
|
||||
|
||||
final String orderNo;
|
||||
final int payMethod;
|
||||
final int amountYuan;
|
||||
final int points;
|
||||
final String expireAt;
|
||||
|
||||
/// 支付宝 order_string / 微信 appid+prepayid 等
|
||||
final Map<String, dynamic> payParams;
|
||||
final double? usdtRate;
|
||||
final String? usdtAmount;
|
||||
final String? receiveAddress;
|
||||
final String? network;
|
||||
|
||||
bool get isUsdt => payMethod == 3;
|
||||
|
||||
factory RechargeOrderInfo.fromJson(Map<String, dynamic> json) =>
|
||||
RechargeOrderInfo(
|
||||
orderNo: json['order_no'] as String,
|
||||
payMethod: (json['pay_method'] as num).toInt(),
|
||||
amountYuan: (json['amount_yuan'] as num).toInt(),
|
||||
points: (json['points'] as num).toInt(),
|
||||
expireAt: (json['expire_at'] as String?) ?? '',
|
||||
payParams:
|
||||
(json['pay_params'] as Map<String, dynamic>?) ?? const {},
|
||||
usdtRate: (json['usdt_rate'] as num?)?.toDouble(),
|
||||
usdtAmount: json['usdt_amount'] as String?,
|
||||
receiveAddress: json['receive_address'] as String?,
|
||||
network: json['network'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
/// 8.3 查询订单响应(App 轮询用)
|
||||
class OrderStatusInfo {
|
||||
const OrderStatusInfo({
|
||||
required this.orderNo,
|
||||
required this.status,
|
||||
this.statusText = '',
|
||||
this.points = 0,
|
||||
this.paidAt,
|
||||
this.walletPoints = 0,
|
||||
});
|
||||
|
||||
final String orderNo;
|
||||
|
||||
/// 0待支付 1已支付 2已关闭 3已退款
|
||||
final int status;
|
||||
final String statusText;
|
||||
final int points;
|
||||
final String? paidAt;
|
||||
|
||||
/// 查单时服务端附带的当前钱包积分
|
||||
final int walletPoints;
|
||||
|
||||
bool get isPending => status == 0;
|
||||
bool get isPaid => status == 1;
|
||||
|
||||
factory OrderStatusInfo.fromJson(Map<String, dynamic> json) =>
|
||||
OrderStatusInfo(
|
||||
orderNo: json['order_no'] as String,
|
||||
status: (json['status'] as num).toInt(),
|
||||
statusText: (json['status_text'] as String?) ?? '',
|
||||
points: (json['points'] as num?)?.toInt() ?? 0,
|
||||
paidAt: json['paid_at'] as String?,
|
||||
walletPoints: (json['wallet_points'] as num?)?.toInt() ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
/// 支付服务(《03-接口文档》第 8 章,均需登录)
|
||||
class PaymentService {
|
||||
PaymentService._();
|
||||
|
||||
/// 8.1 充值套餐列表
|
||||
static Future<PackagesResult> fetchPackages() async {
|
||||
final data =
|
||||
await ApiClient.get<Map<String, dynamic>>(Endpoints.payPackages);
|
||||
return PackagesResult.fromJson(data);
|
||||
}
|
||||
|
||||
/// 8.2 创建充值订单
|
||||
/// 错误码:1001 金额不在可选档位
|
||||
static Future<RechargeOrderInfo> createRecharge({
|
||||
required int amountYuan,
|
||||
required int payMethod,
|
||||
}) async {
|
||||
final data = await ApiClient.post<Map<String, dynamic>>(
|
||||
Endpoints.recharge,
|
||||
data: {'amount_yuan': amountYuan, 'pay_method': payMethod},
|
||||
);
|
||||
return RechargeOrderInfo.fromJson(data);
|
||||
}
|
||||
|
||||
/// 8.3 查询订单状态
|
||||
/// 错误码:3001 订单不存在
|
||||
static Future<OrderStatusInfo> fetchOrder(String orderNo) async {
|
||||
final data = await ApiClient.get<Map<String, dynamic>>(
|
||||
Endpoints.orderDetail(orderNo),
|
||||
);
|
||||
return OrderStatusInfo.fromJson(data);
|
||||
}
|
||||
|
||||
/// 8.4 取消订单(仅待支付可取消)
|
||||
/// 错误码:3001 订单不存在,3002 订单状态异常
|
||||
static Future<void> cancelOrder(String orderNo) async {
|
||||
await ApiClient.post<Map<String, dynamic>>(
|
||||
Endpoints.orderCancel(orderNo),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user