feat: 源码提交
Build Windows / build (push) Has been cancelled

This commit is contained in:
2025-10-19 23:30:54 -07:00
parent 54e7df78db
commit 75d4c48e41
6076 changed files with 64655 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
/// 接口名称
abstract class Api {
/// 游客登录查看是否已经注册
static const String kr_isRegister = "/v1/app/auth/check";
/// 注册
static const String kr_register = "/v1/auth/register";
/// 验证验证码
static const String kr_checkVerificationCode = "/v1/auth/check-code";
/// 发送验证码(统一接口,支持邮箱和手机)
static const String kr_sendCode = "/v1/auth/send-code";
/// 登录接口
static const String kr_login = "/v1/auth/login";
/// 设备登录(游客登录)
/// 参考 OmnOem 项目 ppanel.json 配置
static const String kr_deviceLogin = "/v1/auth/login/device";
/// 删除账号
static const String kr_deleteAccount = "/v1/app/user/account";
/// 忘记密码-设置新密码
static const String kr_setNewPsdByForgetPsd = "/v1/app/auth/reset_password";
/// 节点信息(包含试用/付费标志)
static const String kr_nodeList = "/v1/public/subscribe/node/list";
/// 获取用户订阅流量日志
static const String kr_nodeGroupList = "/v1/app/node/rule_group_list";
/// 预下单
static const String kr_preOrder = "/v1/app/order/pre";
/// 获取下单zf方式
static const String kr_getPaymentMethods = "/v1/app/payment/methods";
/// 进行下单
static const String kr_purchase = "/v1/app/order/purchase";
/// 获取支付地址,跳转到付款地址
static const String kr_checkout = "/v1/app/order/checkout";
/// 获取可购买套餐
static const String kr_getPackageList = "/v1/public/subscribe/list";
/// 获取用户已订阅套餐(用于判断是否购买过)
static const String kr_getAlreadySubscribe =
"/v1/public/user/subscribe";
/// 获取用户可用订阅(与已订阅接口相同,OmnOem 项目中没有区分)
static const String kr_userAvailableSubscribe =
"/v1/public/user/subscribe";
/// 续费
static const String kr_renewal = "/v1/app/order/renewal";
/// 获取用户订阅流量日志
/// 通过该接口判断订单状态
static const String kr_orderDetail = "/v1/app/order/detail";
/// 获取消息列表
static const String kr_getMessageList = "/v1/public/announcement/list";
/// 获取邀请数据
// static const String kr_getInviteData = "/v1/public/invite/code";
/// 配置信息
static const String kr_config = "/v1/app/auth/config";
/// 获取用户在线时长统计
static const String kr_getUserOnlineTimeStatistics =
"/v1/app/user/online_time/statistics";
/// 获取用户邀请人数
static const String kr_getAffiliateCount = "/v1/public/user/affiliate/count";
/// 获取站点协议
static const String kr_getSiteTos = "/v1/common/site/tos";
/// 隐私政策
static const String kr_getSitePrivacy = "/v1/common/site/privacy";
/// 获取网页文本内容
static const String kr_getWebText = "/v1/common/site/text";
/// 重置订阅周期
static const String kr_resetSubscribePeriod =
"/v1/app/subscribe/reset/period";
/// 获取用户设备列表
static const String kr_getUserDevices = "/v1/public/user/devices";
/// 解绑用户设备
static const String kr_unbindUserDevice = "/v1/public/user/unbind_device";
/// 获取可用支付方式(公开接口)
static const String kr_getPublicPaymentMethods = "/v1/public/payment/methods";
}
+196
View File
@@ -0,0 +1,196 @@
import 'package:fpdart/fpdart.dart';
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
import 'dart:io' show Platform;
import '../../model/response/kr_config_data.dart';
import '../../model/response/kr_kr_affiliate_count.dart';
import '../../model/response/kr_message_list.dart';
import '../../model/response/kr_user_info.dart';
import '../../model/response/kr_user_online_duration.dart';
import '../../model/response/kr_web_text.dart';
import '../../network/base_response.dart';
import '../../network/http_error.dart';
import '../../network/http_util.dart';
import 'api.dart';
class KRUserApi {
// 创建一个单例实例
static final KRUserApi _instance = KRUserApi._internal();
factory KRUserApi() => _instance;
// 私有构造函数
KRUserApi._internal();
/// 获取当前系统的 user_agent
String _kr_getUserAgent() {
if (Platform.isAndroid) {
return 'android';
} else if (Platform.isIOS) {
return 'ios';
} else if (Platform.isMacOS) {
return 'mac';
} else if (Platform.isWindows) {
return 'windows';
} else if (Platform.isLinux) {
return 'linux';
} else if (Platform.isFuchsia) {
return 'harmony';
} else {
return 'unknown';
}
}
Future<Either<HttpError, KRMessageList>> kr_getMessageList(
int page, int size, {bool? popup}) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['page'] = page;
data['size'] = size;
if (popup != null) {
data['popup'] = popup;
}
BaseResponse<dynamic> baseResponse =
await HttpUtil.getInstance().request<KRMessageList>(
Api.kr_getMessageList,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model);
}
Future<Either<HttpError, KRUserOnlineDurationResponse>> kr_getUserOnlineTimeStatistics(
) async {
final Map<String, dynamic> data = <String, dynamic>{};
BaseResponse<KRUserOnlineDurationResponse> baseResponse =
await HttpUtil.getInstance().request<KRUserOnlineDurationResponse>(
Api.kr_getUserOnlineTimeStatistics,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
KRLogUtil.kr_i('获取用户在线时长统计: ${baseResponse.model}');
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model);
}
// ⚠️ 已废弃:新版本后端不再提供此接口
// Future<Either<HttpError, KRUserInfo>> kr_getUserInfo() async {
// final Map<String, dynamic> data = <String, dynamic>{};
// BaseResponse<KRUserInfo> baseResponse =
// await HttpUtil.getInstance().request<KRUserInfo>(
// Api.kr_getUserInfo,
// data,
// method: HttpMethod.GET,
// isShowLoading: false,
// );
// if (!baseResponse.isSuccess) {
// return left(
// HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
// }
// return right(baseResponse.model);
// }
Future<Either<HttpError, KRAffiliateCount>> kr_getAffiliateCount() async {
final Map<String, dynamic> data = <String, dynamic>{};
BaseResponse<dynamic> baseResponse =
await HttpUtil.getInstance().request<KRAffiliateCount>(
Api.kr_getAffiliateCount,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model);
}
Future<Either<HttpError, KRConfigData>> kr_config() async {
final Map<String, dynamic> data = <String, dynamic>{};
data['user_agent'] = _kr_getUserAgent();
BaseResponse<KRConfigData> baseResponse =
await HttpUtil.getInstance().request<KRConfigData>(
Api.kr_config,
data,
method: HttpMethod.POST,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model);
}
/// 获取用户设备列表
Future<Either<HttpError, List<Map<String, dynamic>>>> kr_getUserDevices() async {
final Map<String, dynamic> data = <String, dynamic>{};
BaseResponse<dynamic> baseResponse =
await HttpUtil.getInstance().request<dynamic>(
Api.kr_getUserDevices,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
// 返回设备列表数据
try {
// 响应格式: { data: { list: [...], total: N } }
final responseData = baseResponse.model;
final List<Map<String, dynamic>> devices =
(responseData['list'] as List)
.map((item) => item as Map<String, dynamic>)
.toList();
return right(devices);
} catch (e) {
KRLogUtil.kr_e('解析设备列表失败: $e', tag: 'KRUserApi');
return left(HttpError(msg: '数据解析失败', code: -1));
}
}
/// 解绑用户设备
Future<Either<HttpError, void>> kr_unbindUserDevice(String deviceId) async {
final Map<String, dynamic> data = <String, dynamic>{};
// 将字符串 ID 转换为整数
try {
data['id'] = int.parse(deviceId);
} catch (e) {
KRLogUtil.kr_e('设备ID格式错误: $deviceId', tag: 'KRUserApi');
return left(HttpError(msg: '设备ID格式错误', code: -1));
}
BaseResponse<dynamic> baseResponse =
await HttpUtil.getInstance().request<dynamic>(
Api.kr_unbindUserDevice,
data,
method: HttpMethod.PUT,
isShowLoading: true,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(null);
}
}
+333
View File
@@ -0,0 +1,333 @@
import 'dart:io';
import 'dart:math';
import 'dart:convert';
import 'package:fpdart/fpdart.dart';
import 'package:get/get.dart';
import 'package:kaer_with_panels/app/mixins/kr_app_bar_opacity_mixin.dart';
import 'package:kaer_with_panels/app/services/api_service/api.dart';
import 'package:kaer_with_panels/app/model/enum/kr_request_type.dart';
import 'package:kaer_with_panels/app/model/response/kr_is_register.dart';
import 'package:kaer_with_panels/app/model/response/kr_login_data.dart';
import 'package:kaer_with_panels/app/network/base_response.dart';
import 'package:kaer_with_panels/app/network/http_error.dart';
import 'package:kaer_with_panels/app/network/http_util.dart';
import 'package:kaer_with_panels/app/utils/kr_device_util.dart';
import '../../utils/kr_common_util.dart';
import '../../utils/kr_log_util.dart';
import '../../utils/kr_aes_util.dart';
import '../kr_device_info_service.dart';
import '../kr_site_config_service.dart';
import '../../common/app_config.dart';
import 'package:dio/dio.dart' as dio;
class KRAuthApi {
/// 检查账号是否已注册(仅支持邮箱)
Future<Either<HttpError, bool>> kr_isRegister(String email) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['email'] = email;
final deviceId = await KRDeviceUtil().kr_getDeviceId();
KRLogUtil.kr_i('设备ID: $deviceId', tag: 'KRAuthApi');
data["identifier"] = deviceId;
BaseResponse<KRIsRegister> baseResponse = await HttpUtil.getInstance()
.request<KRIsRegister>(Api.kr_isRegister, data,
method: HttpMethod.POST, isShowLoading: true);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.kr_isRegister);
}
/// 注册(仅支持邮箱+密码,验证码和邀请码可选)
Future<Either<HttpError, String>> kr_register(
String email,
String password,
{String? code,
String? inviteCode}) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['email'] = email;
data['password'] = password;
data["identifier"] = await KRDeviceUtil().kr_getDeviceId();
// 验证码是可选的,只有在提供时才发送
if (code != null && code.isNotEmpty) {
data["code"] = code;
}
// 邀请码是可选的
if (inviteCode != null && inviteCode.isNotEmpty) {
data["invite"] = inviteCode;
}
BaseResponse<KRLoginData> baseResponse = await HttpUtil.getInstance()
.request<KRLoginData>(Api.kr_register, data,
method: HttpMethod.POST, isShowLoading: true);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.kr_token.toString());
}
/// 验证验证码(仅支持邮箱)
Future<Either<HttpError, bool>> kr_checkVerificationCode(
String email, String code, int type) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['email'] = email;
data['code'] = code;
data['type'] = type;
BaseResponse<KRIsRegister> baseResponse = await HttpUtil.getInstance()
.request<KRIsRegister>(Api.kr_checkVerificationCode, data,
method: HttpMethod.POST, isShowLoading: true);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
if (baseResponse.model.kr_isRegister) {
return right(true);
} else {
return left(HttpError(msg: "error.70001".tr, code: 70001));
}
}
/// 登录(仅支持邮箱+密码)
Future<Either<HttpError, String>> kr_login(
String email, String password) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['email'] = email;
data['password'] = password;
final deviceId = await KRDeviceUtil().kr_getDeviceId();
KRLogUtil.kr_i('设备ID: $deviceId', tag: 'KRAuthApi');
data["identifier"] = deviceId;
BaseResponse<KRLoginData> baseResponse = await HttpUtil.getInstance()
.request<KRLoginData>(Api.kr_login, data,
method: HttpMethod.POST, isShowLoading: true);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.kr_token.toString());
}
/// 发送验证码(仅支持邮箱)
/// type: 1=登录, 2=注册, 3=重置密码
Future<Either<HttpError, bool>> kr_sendCode(String email, int type) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['email'] = email;
data['type'] = type;
BaseResponse<dynamic> baseResponse = await HttpUtil.getInstance()
.request<dynamic>(Api.kr_sendCode, data,
method: HttpMethod.POST, isShowLoading: true);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(true);
}
/// 删除账号
Future<Either<HttpError, String>> kr_deleteAccount(String code) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['code'] = code;
BaseResponse<dynamic> baseResponse = await HttpUtil.getInstance()
.request<dynamic>(Api.kr_deleteAccount, data,
method: HttpMethod.DELETE, isShowLoading: true);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right("");
}
/// 忘记密码-设置新密码(仅支持邮箱)
Future<Either<HttpError, String>> kr_setNewPsdByForgetPsd(
String email, String code, String password) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['email'] = email;
data['password'] = password;
data["code"] = code;
data["identifier"] = await KRDeviceUtil().kr_getDeviceId();
BaseResponse<KRLoginData> baseResponse = await HttpUtil.getInstance()
.request<KRLoginData>(Api.kr_setNewPsdByForgetPsd, data,
method: HttpMethod.POST, isShowLoading: true);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.kr_token.toString());
}
/// 设备登录(游客登录)
Future<Either<HttpError, String>> kr_deviceLogin() async {
try {
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('🔐 开始设备登录(游客模式)');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('🔐 开始设备登录(游客模式)', tag: 'KRAuthApi');
// 获取设备信息
final deviceInfoService = KRDeviceInfoService();
final deviceId = deviceInfoService.deviceId;
final userAgent = deviceInfoService.getUserAgent();
if (deviceId == null) {
print('❌ 设备ID为空,无法登录');
return left(HttpError(msg: '设备ID获取失败', code: -1));
}
print('📱 设备ID: $deviceId');
print('📱 User-Agent: $userAgent');
KRLogUtil.kr_i('📱 设备ID: $deviceId', tag: 'KRAuthApi');
KRLogUtil.kr_i('📱 User-Agent: $userAgent', tag: 'KRAuthApi');
// 构建请求数据
Map<String, dynamic> data = {
'identifier': deviceId,
'user_agent': userAgent,
};
print('📤 原始请求数据: $data');
// 检查是否需要加密
final siteConfigService = KRSiteConfigService();
final needEncryption = siteConfigService.isDeviceSecurityEnabled();
print('🔒 是否需要加密: $needEncryption');
KRLogUtil.kr_i('🔒 是否需要加密: $needEncryption', tag: 'KRAuthApi');
String? requestBody;
if (needEncryption) {
// 加密请求数据
print('🔐 加密请求数据...');
final encrypted = KRAesUtil.encryptJson(data, AppConfig.kr_encryptionKey);
requestBody = '{"data":"${encrypted['data']}","time":"${encrypted['time']}"}';
print('🔐 加密后请求体: $requestBody');
KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi');
} else {
// 使用明文
requestBody = jsonEncode(data);
print('📝 明文请求体: $requestBody');
}
// 使用 Dio 直接发送请求(因为需要特殊的加密处理)
final dioInstance = dio.Dio();
final baseUrl = AppConfig.getInstance().baseUrl;
final url = '$baseUrl${Api.kr_deviceLogin}';
print('📤 请求URL: $url');
KRLogUtil.kr_i('📤 请求URL: $url', tag: 'KRAuthApi');
// 设置请求头
final headers = <String, String>{
'Content-Type': 'application/json',
};
if (needEncryption) {
headers['Login-Type'] = 'device';
}
print('📤 请求头: $headers');
// 配置Dio实例的超时设置
dioInstance.options.connectTimeout = const Duration(seconds: 10);
dioInstance.options.sendTimeout = const Duration(seconds: 10);
dioInstance.options.receiveTimeout = const Duration(seconds: 10);
final response = await dioInstance.post(
url,
data: requestBody,
options: dio.Options(
headers: headers,
),
);
print('📥 响应状态码: ${response.statusCode}');
print('📥 响应数据: ${response.data}');
KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi');
KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi');
if (response.statusCode == 200) {
Map<String, dynamic> responseData = response.data as Map<String, dynamic>;
// 检查是否需要解密响应
if (needEncryption && responseData.containsKey('data')) {
final dataField = responseData['data'];
if (dataField is Map<String, dynamic> &&
dataField.containsKey('data') &&
dataField.containsKey('time')) {
print('🔓 解密响应数据...');
final decrypted = KRAesUtil.decryptJson(
dataField['data'] as String,
dataField['time'] as String,
AppConfig.kr_encryptionKey,
);
responseData['data'] = decrypted;
print('🔓 解密后数据: ${responseData['data']}');
KRLogUtil.kr_i('🔓 解密成功', tag: 'KRAuthApi');
}
}
if (responseData['code'] == 200) {
final token = responseData['data']['token'] as String;
print('✅ 设备登录成功');
print('🎫 Token: ${token.substring(0, min(20, token.length))}...');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('✅ 设备登录成功', tag: 'KRAuthApi');
return right(token);
} else {
final msg = responseData['msg'] ?? '登录失败';
print('❌ 登录失败: $msg');
return left(HttpError(msg: msg, code: responseData['code']));
}
} else {
print('❌ HTTP错误: ${response.statusCode}');
return left(HttpError(msg: 'HTTP错误', code: response.statusCode ?? -1));
}
} on dio.DioException catch (e) {
print('❌ Dio异常: ${e.type}');
print('❌ 错误信息: ${e.message}');
KRLogUtil.kr_e('❌ 设备登录Dio异常: ${e.message}', tag: 'KRAuthApi');
return left(HttpError(msg: '网络请求失败: ${e.message}', code: -1));
} catch (e, stackTrace) {
print('❌ 设备登录异常: $e');
print('📚 堆栈跟踪: $stackTrace');
KRLogUtil.kr_e('❌ 设备登录异常: $e', tag: 'KRAuthApi');
return left(HttpError(msg: '设备登录失败: $e', code: -1));
}
}
String _kr_getUserAgent() {
if (Platform.isAndroid) {
return 'android';
} else if (Platform.isIOS) {
return 'ios';
} else if (Platform.isMacOS) {
return 'mac';
} else if (Platform.isWindows) {
return 'windows';
} else if (Platform.isLinux) {
return 'linux';
} else if (Platform.isFuchsia) {
return 'harmony';
} else {
return 'unknown';
}
}
}
+293
View File
@@ -0,0 +1,293 @@
import 'dart:ffi';
import 'package:fpdart/fpdart.dart';
import 'package:kaer_with_panels/app/common/app_config.dart';
import 'package:kaer_with_panels/app/services/api_service/api.dart';
import 'package:kaer_with_panels/app/model/response/kr_login_data.dart';
import 'package:kaer_with_panels/app/model/response/kr_node_list.dart';
import 'package:kaer_with_panels/app/model/response/kr_package_list.dart';
import 'package:kaer_with_panels/app/network/base_response.dart';
import 'package:kaer_with_panels/app/network/http_error.dart';
import 'package:kaer_with_panels/app/network/http_util.dart';
import '../../model/response/kr_already_subscribe.dart';
import '../../model/response/kr_node_group_list.dart';
import '../../model/response/kr_order_status.dart';
import '../../model/response/kr_payment_methods.dart';
import '../../model/response/kr_purchase_order_no.dart';
import '../../model/response/kr_status.dart';
import '../../model/response/kr_user_available_subscribe.dart';
/// 订阅相关
class KRSubscribeApi {
/// 获取可购买套餐
Future<Either<HttpError, KRPackageList>> kr_getPackageListList() async {
final Map<String, dynamic> data = <String, dynamic>{};
BaseResponse<KRPackageList> baseResponse =
await HttpUtil.getInstance().request<KRPackageList>(
Api.kr_getPackageList,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model);
}
/// 获取节点列表
Future<Either<HttpError, KRNodeList>> kr_nodeList(int id) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
BaseResponse<KRNodeList> baseResponse =
await HttpUtil.getInstance().request<KRNodeList>(
Api.kr_nodeList,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model);
}
/// 获取用户可用订阅
Future<Either<HttpError, List<KRUserAvailableSubscribeItem>>>
kr_userAvailableSubscribe({bool containsNodes = false}) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['contains_nodes'] = containsNodes;
BaseResponse<KRUserAvailableSubscribeList> baseResponse =
await HttpUtil.getInstance().request<KRUserAvailableSubscribeList>(
Api.kr_userAvailableSubscribe,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.list);
}
/// 获取分组节点
Future<Either<HttpError, List<KRNodeGroupListItem>>>
kr_nodeGroupList() async {
final Map<String, dynamic> data = <String, dynamic>{};
BaseResponse<KRNodeGroupList> baseResponse =
await HttpUtil.getInstance().request<KRNodeGroupList>(
Api.kr_nodeGroupList,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.list);
}
/// 通过该接口判断订单状态
Future<Either<HttpError, KROrderStatus>> kr_orderDetail(
String orderId) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['order_no'] = orderId;
BaseResponse<KROrderStatus> baseResponse =
await HttpUtil.getInstance().request<KROrderStatus>(
Api.kr_orderDetail,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model);
}
/// 获取支付方式
Future<Either<HttpError, List<KRPaymentMethod>>>
kr_getPaymentMethods() async {
final Map<String, dynamic> data = <String, dynamic>{};
BaseResponse<KRPaymentMethods> baseResponse =
await HttpUtil.getInstance().request<KRPaymentMethods>(
Api.kr_getPaymentMethods,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.list);
}
/// 进行下单
Future<Either<HttpError, String>> kr_purchase(
int planId, int quantity, int payment, String coupon) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['subscribe_id'] = planId;
data['quantity'] = quantity;
data['payment'] = payment;
data['coupon'] = "";
BaseResponse<KRPurchaseOrderNo> baseResponse =
await HttpUtil.getInstance().request<KRPurchaseOrderNo>(
Api.kr_purchase,
data,
method: HttpMethod.POST,
isShowLoading: true,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.orderNo);
}
/// 续费
Future<Either<HttpError, String>> kr_renewal(
int planId, int quantity, int payment, String coupon) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['user_subscribe_id'] = planId;
data['quantity'] = quantity;
data['payment'] = payment;
data['coupon'] = "";
BaseResponse<KRPurchaseOrderNo> baseResponse =
await HttpUtil.getInstance().request<KRPurchaseOrderNo>(
Api.kr_renewal,
data,
method: HttpMethod.POST,
isShowLoading: true,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.orderNo);
}
/// 获取用户已订阅套餐
Future<Either<HttpError, List<KRAlreadySubscribe>>>
kr_getAlreadySubscribe() async {
final Map<String, dynamic> data = <String, dynamic>{};
BaseResponse<KRAlreadySubscribeList> baseResponse =
await HttpUtil.getInstance().request<KRAlreadySubscribeList>(
Api.kr_getAlreadySubscribe,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.list);
}
Future<Either<HttpError, String>> kr_prePurchase(
int planId, int quantity, String payment, String coupon) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['subscribe_id'] = planId;
data['quantity'] = quantity;
data['payment'] = payment;
data['coupon'] = "";
BaseResponse<KRPurchaseOrderNo> baseResponse =
await HttpUtil.getInstance().request<KRPurchaseOrderNo>(
Api.kr_preOrder,
data,
method: HttpMethod.POST,
isShowLoading: true,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.orderNo);
}
/// 获取支付地址,跳转到付款地址
Future<Either<HttpError, String>> kr_checkout(String orderId) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['orderNo'] = orderId;
data['returnUrl'] = AppConfig.getInstance().baseUrl;
BaseResponse<KRPurchaseOrderUrl> baseResponse =
await HttpUtil.getInstance().request<KRPurchaseOrderUrl>(
Api.kr_checkout,
data,
method: HttpMethod.POST,
isShowLoading: true,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.url);
}
/// 重置订阅周期
Future<Either<HttpError, bool>> kr_resetSubscribePeriod(
int userSubscribeId) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['user_subscribe_id'] = userSubscribeId;
BaseResponse<KRStatus> baseResponse =
await HttpUtil.getInstance().request<KRStatus>(
Api.kr_resetSubscribePeriod,
data,
method: HttpMethod.POST,
isShowLoading: true,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model.kr_bl);
}
/// 获取公开的支付方式列表
Future<Either<HttpError, dynamic>> kr_getPublicPaymentMethods() async {
final Map<String, dynamic> data = <String, dynamic>{};
BaseResponse<dynamic> baseResponse =
await HttpUtil.getInstance().request<dynamic>(
Api.kr_getPublicPaymentMethods,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
return right(baseResponse.model);
}
}
+56
View File
@@ -0,0 +1,56 @@
import 'package:fpdart/fpdart.dart';
import 'package:kaer_with_panels/app/services/api_service/api.dart';
import 'package:kaer_with_panels/app/model/response/kr_web_text.dart';
import 'package:kaer_with_panels/app/network/base_response.dart';
import 'package:kaer_with_panels/app/network/http_error.dart';
import 'package:kaer_with_panels/app/network/http_util.dart';
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
/// 网页相关 API
class KRWebApi {
/// 获取网页文本内容
Future<Either<HttpError, String>> kr_getWebText(String url) async {
final Map<String, dynamic> data = <String, dynamic>{};
data['url'] = url;
BaseResponse<KRWebText> baseResponse = await HttpUtil.getInstance().request<KRWebText>(
url,
data,
method: HttpMethod.GET,
isShowLoading: false,
);
if (!baseResponse.isSuccess) {
return left(HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
}
// 根据 URL 返回对应的内容
if (url.contains(Api.kr_getSitePrivacy)) {
return right(baseResponse.model.privacyPolicy);
} else if (url.contains(Api.kr_getSiteTos)) {
return right(baseResponse.model.tosContent);
} else {
return right(baseResponse.model.privacyPolicy); // 默认返回隐私政策
}
}
/// 获取网页内容
// Future<Either<String, String>> kr_getWebContent() async {
// try {
// // ... 其他代码 ...
// } catch (e) {
// KRLogUtil.kr_e('获取网页内容失败: $e', tag: 'WebApi');
// return Left('获取网页内容失败: $e');
// }
// }
// /// 获取网页内容
// Future<Either<String, String>> kr_getWebContentWithRetry() async {
// try {
// // ... 其他代码 ...
// } catch (e) {
// KRLogUtil.kr_e('获取网页内容失败: $e', tag: 'WebApi');
// return Left('获取网页内容失败: $e');
// }
// }
}