first commit

This commit is contained in:
2025-09-24 14:08:54 +08:00
commit 40784642cf
83 changed files with 37832 additions and 0 deletions

119
account/README.md Normal file
View File

@@ -0,0 +1,119 @@
# OneApp Account 账户模块文档
## 模块概述
`oneapp_account` 是 OneApp 的用户账户管理模块,负责用户认证、登录、注册、权限管理等核心功能。该模块包含两个主要子模块:
- **clr_account**: 账户服务 SDK提供账户相关的核心服务接口
- **jverify**: 极验验证 Flutter 插件,提供安全验证功能
## 真实项目结构
基于实际的 `oneapp_account` 项目结构:
```
oneapp_account/
├── lib/
│ ├── account.dart # 主要导出文件
│ ├── account_api.dart # API接口定义
│ ├── account_third_bind.dart # 第三方绑定
│ ├── module_constants.dart # 模块常量
│ ├── generated/ # 代码生成文件
│ ├── l10n/ # 国际化文件
│ └── src/ # 源代码目录
│ ├── account_dependency.dart # 依赖配置
│ ├── blocs/ # BLoC状态管理
│ │ ├── personal_center/ # 个人中心BLoC
│ │ ├── garage/ # 车库管理BLoC
│ │ ├── vehicle_info/ # 车辆信息BLoC
│ │ ├── phone_sign_in/ # 手机登录BLoC
│ │ ├── bind_vehicle_new/ # 绑车流程BLoC
│ │ ├── qr_hu_confirm/ # 二维码确认BLoC
│ │ └── ... # 其他业务BLoC
│ ├── pages/ # 页面组件
│ ├── model/ # 数据模型
│ ├── utils/ # 工具类
│ ├── constants/ # 常量定义
│ ├── route_dp.dart # 路由配置
│ └── route_export.dart # 路由导出
├── clr_account/ # 账户连接层服务
├── jverify/ # 极验验证插件
├── assets/ # 资源文件
└── pubspec.yaml # 依赖配置
```
## 子模块文档
- [CLR Account 账户服务 SDK](./clr_account.md)
- [JVerify 极验验证插件](./jverify.md)
## 主要功能
### 真实实现的功能模块
基于实际项目代码,账户模块包含以下已实现的功能:
#### 1. 用户认证和登录
- **手机号登录** (`phone_sign_in/`) - 支持手机号密码登录
- **验证码验证** (`verification_code_input/`) - 短信验证码确认
- **第三方登录** (`third_sign_in/`) - 第三方账户集成
- **二维码登录确认** (`qr_hu_confirm/`) - 车机登录确认功能
#### 2. 个人信息管理
- **个人中心** (`personal_center/`) - 用户信息展示和管理
- **个人资料** (`personal_intro/`) - 个人信息编辑
- **头像管理** - 用户头像上传和设置
- **手机号更新** (`update_phone/`) - 更换绑定手机号
#### 3. 车辆管理
- **车库管理** (`garage/`) - 车辆列表和管理
- **车辆信息** (`vehicle_info/`) - 车辆详细信息查看
- **绑车流程** (`bind_vehicle_new/`) - 新车绑定流程
- **车辆授权** (`vehicle_auth/`) - 车辆访问权限管理
- **车牌设置** (`plate_no_edit/`) - 车牌号码编辑
#### 4. 扫码功能
- **二维码扫描** (`qr_scan/`) - 通用二维码扫描
- **扫码登录** (`scan_login_hu/`) - 扫码登录车机功能
- **绑车二维码** - 车辆绑定二维码处理
#### 5. 账户安全
- **账户注销** (`cancel_account/`) - 用户账户注销流程
- **短信认证** (`sms_auth/`) - 安全操作短信验证
- **用户协议** (`agreement/`) - 用户协议和隐私政策
## 真实技术架构
### 模块依赖
基于实际 `pubspec.yaml` 的真实依赖:
```yaml
dependencies:
# 核心框架
basic_modular: ^0.2.3 # 模块化框架
basic_modular_route: ^0.2.1 # 路由管理
basic_network: ^0.2.3+4 # 网络请求
basic_storage: ^0.2.2 # 本地存储
# 业务依赖
clr_account: ^0.2.24 # 账户服务SDK (本地路径)
car_vehicle: ^0.6.4+1 # 车辆服务
app_consent: ^0.2.19 # 用户同意管理
# 工具依赖
dartz: ^0.10.1 # 函数式编程
freezed_annotation: ^2.2.0 # 不可变类生成
flutter_contacts: ^1.1.5 # 联系人服务
```
## 依赖关系
该模块被 `oneapp_main` 项目依赖,为整个应用提供用户账户相关的基础服务。
## 开发指南
### 环境要求
- Flutter >=3.0.0
- Dart >=3.0.0
### 集成使用
详细的集成使用方法请参考各子模块的具体文档。

512
account/clr_account.md Normal file
View File

@@ -0,0 +1,512 @@
# CLR Account 账户服务 SDK 文档
## 模块概述
`clr_account` 是 OneApp 账户系统的核心 SDK提供用户认证、登录、注册、权限管理等基础服务。该模块采用领域驱动设计DDD架构提供清晰的接口抽象和业务逻辑封装。
### 基本信息
- **模块名称**: clr_account
- **版本**: 0.2.24
- **仓库**: https://gitlab-rd0.maezia.com/dssomobile/oneapp/dssomobile-oneapp-clr-account
## 目录结构
```
clr_account/
├── lib/
│ ├── account.dart # 主要导出文件
│ ├── account_event.dart # 账户事件定义
│ ├── third_account.dart # 第三方账户集成
│ ├── generated/ # 代码生成文件
│ ├── l10n/ # 国际化文件
│ └── src/ # 源代码目录
│ ├── data/ # 数据层
│ ├── domain/ # 领域层
│ ├── presentation/ # 表示层
│ └── infrastructure/ # 基础设施层
├── pubspec.yaml # 依赖配置
└── README.md # 项目说明
```
## 核心功能模块
### 1. 账户认证 (Authentication)
#### 功能概述
- 用户登录/登出
- 密码认证
- 生物识别认证
- 多因素认证
#### 主要接口
```dart
// 基于实际项目的认证门面接口
abstract class IAuthFacade {
/// 当前登录状态
bool get isLogin;
/// 用户登出
Future<void> logout();
/// 撤销注销
Future<Either<AuthFailure, Unit>> undoSignOut(String refCode);
}
// 实际的认证异常类型
sealed class AuthFailure {
const AuthFailure();
}
class OtherError extends AuthFailure {
final dynamic error;
const OtherError(this.error);
}
```
### 2. 用户注册 (Registration)
#### 功能概述
- 新用户注册
- 手机号验证
- 邮箱验证
- 用户信息收集
#### 主要接口
```dart
// 基于实际项目的配置文件门面接口
abstract class IProfileFacade {
/// 获取本地用户配置文件
Either<ProfileFailure, UserProfile> getUserProfileLocal();
/// 从云端获取用户配置文件
Future<Either<ProfileFailure, UserProfile>> fetchUserProfile();
}
// 实际的配置文件异常类型
sealed class ProfileFailure {
const ProfileFailure();
}
// 实际的用户配置模型
class UserProfile {
final String id;
final String name;
final String email;
final String? avatar;
const UserProfile({
required this.id,
required this.name,
required this.email,
this.avatar,
});
}
```
### 3. 用户信息管理 (Profile)
#### 功能概述
- 个人信息查看和编辑
- 头像管理
- 偏好设置
- 隐私设置
#### 主要接口
```dart
// 基于实际项目的车库门面接口
abstract class IGarageFacade {
/// 获取车库绑车列表
/// [refresh]为 true 则强制从网络获取,并刷新本地数据
Future<Either<GarageFailure, List<VehicleDto>>> getEnrollmentVehicleList({
bool refresh = false,
bool local = false,
});
/// 获取默认车辆
Future<Either<GarageFailure, VehicleDto?>> getDefaultEnrolledVehicle({
bool refresh = false,
});
/// 快速获取默认车辆
VehicleDto? getDefaultVehicleLocal();
/// 设置车辆是否默认
Future<Either<GarageFailure, bool>> setVehicleDefault({
required String vin,
required bool isDefault,
});
/// 修改车牌号
Future<Either<GarageFailure, bool>> setVehiclePlateNo(
String plateNo,
String vin,
);
/// 扫码登录车机
Future<Either<GarageFailure, Unit>> signInHUWithQrCode({
required String uuid,
required int? timestamp,
required String? signature,
});
}
// 实际的车辆数据传输对象
class VehicleDto {
final String vin;
final String? plateNo;
final VehicleModel vehicleModel;
final String accountType;
const VehicleDto({
required this.vin,
this.plateNo,
required this.vehicleModel,
required this.accountType,
});
static const String accountTypeP = 'P'; // 主账户
static const String accountTypeS = 'S'; // 从账户
}
```
### 4. 权限管理 (Authorization)
#### 功能概述
- 角色权限管理
- 功能权限控制
- 资源访问控制
#### 主要接口
```dart
abstract class AuthorizationService {
Future<Result<bool>> hasPermission(String permission);
Future<Result<List<String>>> getUserRoles();
Future<Result<bool>> canAccessResource(String resource);
}
```
## 技术架构
### 分层架构
#### 1. 表示层 (Presentation Layer)
- **功能**: 用户界面相关的状态管理和事件处理
- **组件**:
- Widget 组件
- State 管理
- Event 处理器
#### 2. 领域层 (Domain Layer)
- **功能**: 业务逻辑和业务规则
- **组件**:
- Entity 实体
- Value Object 值对象
- Domain Service 领域服务
- Repository 接口
#### 3. 数据层 (Data Layer)
- **功能**: 数据访问和存储
- **组件**:
- Repository 实现
- Data Source 数据源
- Model 数据模型
#### 4. 基础设施层 (Infrastructure Layer)
- **功能**: 外部服务集成
- **组件**:
- 网络服务
- 存储服务
- 第三方 SDK 集成
### 状态管理
#### 事件驱动架构
基于 OneApp 事件总线系统,使用真实的账户事件处理机制。
```dart
// 实际项目中的事件处理示例(从 PersonalCenterBloc
class PersonalCenterBloc extends Bloc<PersonalCenterEvent, PersonalCenterState> {
PersonalCenterBloc(
this._signInFacade,
this._profileFacade,
this._garageFacade,
) : super(PersonalCenterState.initial()) {
// 监听推送事件
_eventListener = pushFacade.subscribeOn(
topics: [
userProfileChangedTopic,
logoutTopic,
loginSuccessTopic,
loginFailedTopic,
],
).listen((event) async {
// 当收到用户信息更变、登出事件、登录成功事件时,重新加载用户信息
if (event.topic == logoutTopic || event.topic == loginSuccessTopic) {
OneAppEventBus.fireEvent(UserLoginEvent(loginType: LoginOutType.all));
add(const PersonalCenterEvent.loadUserProfile());
add(const PersonalCenterEvent.loadSocialInfor());
}
});
// 监听积分变更事件
_pointsChageEvent = OneAppEventBus.addListen<PointsChangeEvent>((event) {
add(const PersonalCenterEvent.loadUserPoints());
});
}
}
// 实际的账户事件类型
abstract class AccountEvent {
const AccountEvent();
}
class UserLoginEvent extends AccountEvent {
final LoginOutType loginType;
const UserLoginEvent({required this.loginType});
}
enum LoginOutType { all }
```
### 数据持久化
#### 本地存储
- 基于 `basic_storage` 的统一存储接口
- 用户信息安全存储
- 登录凭证加密存储
#### 缓存策略
- 用户信息内存缓存
- 权限信息缓存
- 网络请求缓存
## 依赖关系
### 核心依赖
- `basic_network`: 网络请求服务
- `basic_storage`: 本地存储服务
- `basic_modular`: 模块化框架
- `basic_error`: 错误处理
- `basic_consent`: 用户同意管理
### 第三方集成
- `fluwx`: 微信 SDK 集成
- `dartz`: 函数式编程支持
- `freezed_annotation`: 不可变类生成
### 业务依赖
- `clr_setting`: 设置服务
- `basic_track`: 埋点追踪
- `basic_webview`: WebView 服务
## API 接口设计
### 认证接口
```dart
// 登录
POST /api/v1/auth/login
{
"username": "string",
"password": "string",
"deviceId": "string"
}
// 登出
POST /api/v1/auth/logout
{
"token": "string"
}
// 刷新令牌
POST /api/v1/auth/refresh
{
"refreshToken": "string"
}
```
### 用户信息接口
```dart
// 获取用户信息
GET /api/v1/user/profile
// 更新用户信息
PUT /api/v1/user/profile
{
"nickname": "string",
"avatar": "string",
"birthday": "string"
}
```
## 安全特性
### 数据安全
- 密码哈希存储
- 敏感信息加密
- 通信 HTTPS 加密
### 认证安全
- JWT 令牌机制
- 令牌过期机制
- 设备绑定验证
### 隐私保护
- 用户同意管理
- 数据最小化收集
- 隐私设置支持
## 错误处理
### 错误分类
- 网络错误
- 认证错误
- 业务逻辑错误
- 系统错误
### 错误处理策略
基于实际项目中的异常处理模式,使用 Functional Programming 的 Either 模式。
```dart
// 实际项目中的异常处理示例
sealed class AuthFailure {
const AuthFailure();
}
class OtherError extends AuthFailure {
final dynamic error;
const OtherError(this.error);
}
sealed class ProfileFailure {
const ProfileFailure();
}
sealed class GarageFailure {
const GarageFailure();
}
// 错误处理方法示例(来自 PersonalCenterBloc
void _onLoginFailed(LoginFailure failure) {
final authFailure = failure.cause;
if (authFailure is OtherError) {
// 其他异常
_handleOtherAuthFailure(authFailure.error);
}
}
void _handleOtherAuthFailure(dynamic error) {
if (error is ErrorGlobalBusiness) {
// 云端异常
final Map<String, dynamic> errorConfig = error.errorConfig;
final String? originalCode = errorConfig['originalCode'] as String?;
// 处理特定错误码
if (originalCode == '10444105') {
// 预注销状态处理
_showPreSignOutDialog(/*参数*/);
}
}
}
// 使用 Either 模式的接口返回值
Future<Either<ProfileFailure, UserProfile>> fetchUserProfile();
Future<Either<GarageFailure, List<VehicleDto>>> getEnrollmentVehicleList();
Future<Either<AuthFailure, Unit>> undoSignOut(String refCode);
```
## 国际化支持
### 支持语言
- 中文(简体)
- 英文
- 其他地区语言扩展
### 配置方式
- 基于 `basic_intl` 的国际化框架
- 动态语言切换
- 文本资源管理
## 测试策略
### 单元测试
- 领域逻辑测试
- 服务接口测试
- 工具类测试
### 集成测试
- API 接口测试
- 数据存储测试
- 第三方服务集成测试
### UI 测试
- 登录流程测试
- 注册流程测试
- 用户信息管理测试
## 性能优化
### 网络优化
- 请求缓存
- 批量请求
- 网络重试机制
### 内存优化
- 对象池管理
- 图片缓存优化
- 内存泄漏防护
### 启动优化
- 懒加载机制
- 预加载策略
- 冷启动优化
## 监控与统计
### 用户行为统计
- 登录成功率
- 注册转化率
- 功能使用统计
### 性能监控
- 接口响应时间
- 错误率统计
- 崩溃率监控
### 业务指标
- 活跃用户数
- 用户留存率
- 功能使用频次
## 开发指南
### 环境搭建
1. 安装 Flutter SDK >=2.10.5
2. 配置依赖项目路径
3. 运行 `flutter pub get`
### 代码规范
- 遵循 Dart 编码规范
- 使用 `analysis_options.yaml` 静态分析
- 提交前代码格式化
### 调试技巧
- 使用 `basic_logger` 记录日志
- 网络请求调试
- 状态变更追踪
## 版本历史
### v0.2.24 (当前版本)
- 支持微信登录集成
- 优化用户信息缓存机制
- 增强安全认证流程
### 后续规划
- 支持更多第三方登录
- 增强生物识别认证
- 优化性能和用户体验
## 总结
`clr_account` 作为 OneApp 的账户核心 SDK提供了完整的用户认证和管理功能。模块采用清晰的分层架构具有良好的可扩展性和可维护性为整个应用的用户体系提供了坚实的基础。

671
account/jverify.md Normal file
View File

@@ -0,0 +1,671 @@
# JVerify 极验验证插件文档
## 插件概述
`jverify` 是 OneApp 集成的极验验证 Flutter 插件,提供一键登录、短信验证等安全认证功能。该插件封装了极验验证的 Android 和 iOS SDK为 Flutter 应用提供统一的验证接口。
### 基本信息
- **插件名称**: jverify
- **类型**: Flutter Plugin
- **平台支持**: Android, iOS
- **功能**: 一键登录、短信验证、SDK 初始化
## 目录结构
```
jverify/
├── lib/
│ └── jverify.dart # Flutter 接口层
├── android/ # Android 原生实现
│ ├── src/main/
│ │ ├── AndroidManifest.xml # Android 清单文件
│ │ ├── java/ # Java/Kotlin 源码
│ │ └── libs/ # 第三方库文件
│ └── build.gradle # Android 构建配置
├── ios/ # iOS 原生实现
│ ├── Classes/ # Objective-C/Swift 源码
│ ├── Assets/ # iOS 资源文件
│ └── jverify.podspec # CocoaPods 配置
├── documents/ # 文档目录
├── pubspec.yaml # Flutter 插件配置
└── README.md # 项目说明
```
## Flutter 接口层 (lib/jverify.dart)
### 核心回调类型定义
#### 1. 事件监听器定义
```dart
// 自定义控件点击事件监听器
typedef JVClickWidgetEventListener = void Function(String widgetId);
// 授权页事件回调监听器
typedef JVAuthPageEventListener = void Function(JVAuthPageEvent event);
// 一键登录回调监听器
typedef JVLoginAuthCallBackListener = void Function(JVListenerEvent event);
// 短信登录回调监听器
typedef JVSMSListener = void Function(JVSMSEvent event);
// SDK 初始化回调监听器
typedef JVSDKSetupCallBackListener = void Function(JVSDKSetupEvent event);
```
#### 2. 事件数据模型
```dart
// 一键登录事件
class JVListenerEvent {
final int code; // 返回码6000成功6001失败
final String message; // 返回信息或loginToken
final String operator; // 运营商CM移动CU联通CT电信
}
// 短信验证事件
class JVSMSEvent {
final int code; // 返回码
final String message; // 返回信息
final String phone; // 手机号
}
// SDK 初始化事件
class JVSDKSetupEvent {
final int code; // 返回码8000成功
final String message; // 返回信息
}
// 授权页事件
class JVAuthPageEvent {
final String eventType; // 事件类型
final Map<String, dynamic> data; // 事件数据
}
```
### 主要接口方法
#### 1. SDK 初始化
```dart
class Jverify {
// 初始化 SDK
static Future<void> setup({
required String appKey,
required String channel,
bool isProduction = true,
JVSDKSetupCallBackListener? setupListener,
});
// 检查初始化状态
static Future<bool> isSetup();
}
```
#### 2. 一键登录
```dart
// 预初始化
static Future<void> preLogin({
int timeOut = 5000,
JVLoginAuthCallBackListener? preLoginListener,
});
// 判断网络环境是否支持
static Future<void> checkVerifyEnable({
JVLoginAuthCallBackListener? checkListener,
});
// 获取登录 Token
static Future<void> loginAuth({
bool autoDismiss = true,
int timeOut = 5000,
JVLoginAuthCallBackListener? loginListener,
});
// 自定义授权页面
static Future<void> setCustomAuthorizationView({
required Map<String, dynamic> config,
JVClickWidgetEventListener? clickListener,
JVAuthPageEventListener? authPageEventListener,
});
```
#### 3. 短信验证
```dart
// 获取短信验证码
static Future<void> getSMSCode({
required String phoneNumber,
String? signID,
String? tempID,
JVSMSListener? smsListener,
});
// 短信验证登录
static Future<void> smsAuth({
required String phoneNumber,
required String smsCode,
JVSMSListener? smsListener,
});
```
#### 4. 页面控制
```dart
// 关闭授权页面
static Future<void> dismissLoginAuth();
// 清除预取号缓存
static Future<void> clearPreLoginCache();
// 设置调试模式
static Future<void> setDebugMode(bool enable);
```
## Android 原生实现
### 项目结构
```
android/
├── src/main/
│ ├── AndroidManifest.xml # 权限和组件配置
│ ├── java/com/jverify/ # Java 实现代码
│ │ ├── JverifyPlugin.java # 插件主类
│ │ ├── JVerifyHelper.java # 辅助工具类
│ │ └── utils/ # 工具类
│ └── libs/ # 极验 SDK 库文件
│ ├── jverify-android-*.jar
│ └── jcore-android-*.jar
└── build.gradle # 构建配置
```
### 关键实现文件
#### 1. JverifyPlugin.java - 插件主类
```java
public class JverifyPlugin implements FlutterPlugin, MethodCallHandler {
// 方法通道
private MethodChannel channel;
// 极验 SDK API 接口
private JVerifyInterface jVerifyInterface;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
channel = new MethodChannel(binding.getBinaryMessenger(), "jverify");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
switch (call.method) {
case "setup":
initSDK(call, result);
break;
case "checkVerifyEnable":
checkVerifyEnable(call, result);
break;
case "preLogin":
preLogin(call, result);
break;
case "loginAuth":
loginAuth(call, result);
break;
case "getSMSCode":
getSMSCode(call, result);
break;
case "smsAuth":
smsAuth(call, result);
break;
case "dismissLoginAuth":
dismissLoginAuth(result);
break;
default:
result.notImplemented();
}
}
}
```
#### 2. 核心功能实现
```java
// SDK 初始化
private void initSDK(MethodCall call, Result result) {
String appKey = call.argument("appKey");
String channel = call.argument("channel");
boolean isProduction = call.argument("isProduction");
JVerifyInterface.init(getApplicationContext(), appKey, channel, isProduction);
JVerifyInterface.setDebugMode(true);
// 设置初始化回调
JVerifyInterface.setInitListener(new InitListener() {
@Override
public void onResult(int code, String message) {
// 回调到 Flutter
Map<String, Object> args = new HashMap<>();
args.put("code", code);
args.put("message", message);
channel.invokeMethod("onSDKSetup", args);
}
});
}
// 一键登录
private void loginAuth(MethodCall call, Result result) {
boolean autoDismiss = call.argument("autoDismiss");
int timeOut = call.argument("timeOut");
JVerifyInterface.loginAuth(getCurrentActivity(), autoDismiss, timeOut,
new LoginAuthListener() {
@Override
public void onResult(int code, String content, String operator) {
Map<String, Object> args = new HashMap<>();
args.put("code", code);
args.put("message", content);
args.put("operator", operator);
channel.invokeMethod("onLoginAuth", args);
}
});
}
```
### Android 配置
#### AndroidManifest.xml 权限配置
```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 电话权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- 其他权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application>
<!-- 极验服务配置 -->
<meta-data
android:name="JVERIFY_CHANNEL"
android:value="${JVERIFY_CHANNEL}" />
<meta-data
android:name="JVERIFY_APPKEY"
android:value="${JVERIFY_APPKEY}" />
</application>
</manifest>
```
#### build.gradle 配置
```gradle
android {
compileSdkVersion 33
defaultConfig {
minSdkVersion 19
targetSdkVersion 33
}
buildTypes {
release {
manifestPlaceholders = [
JVERIFY_APPKEY: project.hasProperty('JVERIFY_APPKEY') ? JVERIFY_APPKEY : '',
JVERIFY_CHANNEL: project.hasProperty('JVERIFY_CHANNEL') ? JVERIFY_CHANNEL : 'developer-default'
]
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
```
## iOS 原生实现
### 项目结构
```
ios/
├── Classes/
│ ├── JverifyPlugin.h # 插件头文件
│ ├── JverifyPlugin.m # 插件实现文件
│ └── JVerifyHelper.h/m # 辅助工具类
├── Assets/ # 资源文件
├── Frameworks/ # 极验 SDK 框架
│ └── JVERIFYService.framework
└── jverify.podspec # CocoaPods 配置
```
### 关键实现文件
#### 1. JverifyPlugin.h - 插件头文件
```objc
#import <Flutter/Flutter.h>
#import <JVERIFYService/JVERIFYService.h>
@interface JverifyPlugin : NSObject<FlutterPlugin>
@property (nonatomic, strong) FlutterMethodChannel *channel;
@end
```
#### 2. JverifyPlugin.m - 插件实现
```objc
@implementation JverifyPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"jverify"
binaryMessenger:[registrar messenger]];
JverifyPlugin* instance = [[JverifyPlugin alloc] init];
instance.channel = channel;
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"setup" isEqualToString:call.method]) {
[self initSDK:call result:result];
} else if ([@"checkVerifyEnable" isEqualToString:call.method]) {
[self checkVerifyEnable:call result:result];
} else if ([@"preLogin" isEqualToString:call.method]) {
[self preLogin:call result:result];
} else if ([@"loginAuth" isEqualToString:call.method]) {
[self loginAuth:call result:result];
} else if ([@"getSMSCode" isEqualToString:call.method]) {
[self getSMSCode:call result:result];
} else if ([@"smsAuth" isEqualToString:call.method]) {
[self smsAuth:call result:result];
} else if ([@"dismissLoginAuth" isEqualToString:call.method]) {
[self dismissLoginAuth:result];
} else {
result(FlutterMethodNotImplemented);
}
}
// SDK 初始化
- (void)initSDK:(FlutterMethodCall*)call result:(FlutterResult)result {
NSString *appKey = call.arguments[@"appKey"];
NSString *channel = call.arguments[@"channel"];
BOOL isProduction = [call.arguments[@"isProduction"] boolValue];
[JVERIFYService setupWithAppkey:appKey channel:channel apsForProduction:isProduction];
// 设置初始化回调
[JVERIFYService setInitHandler:^(JVInitResultModel *result) {
NSDictionary *args = @{
@"code": @(result.code),
@"message": result.message ?: @""
};
[self.channel invokeMethod:@"onSDKSetup" arguments:args];
}];
result(@(YES));
}
// 一键登录
- (void)loginAuth:(FlutterMethodCall*)call result:(FlutterResult)result {
BOOL autoDismiss = [call.arguments[@"autoDismiss"] boolValue];
NSTimeInterval timeOut = [call.arguments[@"timeOut"] doubleValue] / 1000.0;
[JVERIFYService getAuthorizationWithController:[self getCurrentViewController]
completion:^(JVAuthorizationResultModel *result) {
NSDictionary *args = @{
@"code": @(result.code),
@"message": result.content ?: @"",
@"operator": result.operator ?: @""
};
[self.channel invokeMethod:@"onLoginAuth" arguments:args];
}];
result(@(YES));
}
@end
```
### iOS 配置
#### jverify.podspec
```ruby
Pod::Spec.new do |s|
s.name = 'jverify'
s.version = '1.0.0'
s.summary = 'JVerify Flutter Plugin'
s.description = 'A Flutter plugin for JVerify SDK'
s.homepage = 'https://www.jiguang.cn'
s.license = { :file => '../LICENSE' }
s.author = { 'JiGuang' => 'support@jiguang.cn' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.dependency 'JVerify', '~> 2.8.0'
s.platform = :ios, '9.0'
s.ios.deployment_target = '9.0'
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
s.swift_version = '5.0'
end
```
#### Info.plist 配置
```xml
<dict>
<!-- 应用传输安全设置 -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<!-- 网络使用说明 -->
<key>NSPhotoLibraryUsageDescription</key>
<string>此应用需要访问相册来选择头像</string>
<!-- 电话权限说明 -->
<key>NSContactsUsageDescription</key>
<string>此应用需要访问通讯录进行一键登录</string>
</dict>
```
## 使用示例
### 基本集成
```dart
import 'package:jverify/jverify.dart';
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
@override
void initState() {
super.initState();
_initJVerify();
}
// 初始化 JVerify SDK
void _initJVerify() async {
await Jverify.setup(
appKey: "your_app_key",
channel: "developer-default",
isProduction: false,
setupListener: (JVSDKSetupEvent event) {
if (event.code == 8000) {
print("SDK 初始化成功");
_preLogin();
} else {
print("SDK 初始化失败: ${event.message}");
}
},
);
}
// 预登录
void _preLogin() async {
await Jverify.preLogin(
preLoginListener: (JVListenerEvent event) {
if (event.code == 6000) {
print("预登录成功");
}
},
);
}
// 一键登录
void _oneClickLogin() async {
await Jverify.loginAuth(
loginListener: (JVListenerEvent event) {
if (event.code == 6000) {
String loginToken = event.message;
// 使用 loginToken 进行后续验证
_verifyTokenWithServer(loginToken);
} else {
print("一键登录失败: ${event.message}");
}
},
);
}
// 短信登录
void _smsLogin(String phoneNumber, String smsCode) async {
await Jverify.smsAuth(
phoneNumber: phoneNumber,
smsCode: smsCode,
smsListener: (JVSMSEvent event) {
if (event.code == 6000) {
print("短信登录成功");
}
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
ElevatedButton(
onPressed: _oneClickLogin,
child: Text("一键登录"),
),
ElevatedButton(
onPressed: () => _getSMSCode("13800138000"),
child: Text("获取验证码"),
),
],
),
);
}
}
```
## 错误码说明
### 通用错误码
- **8000**: SDK 初始化成功
- **8001**: SDK 初始化失败
- **6000**: 登录获取 loginToken 成功
- **6001**: 登录获取 loginToken 失败
- **6002**: 网络连接失败
- **6003**: 请求超时
- **6004**: 运营商网络未知
### 一键登录错误码
- **6005**: 手机号不支持此运营商
- **6006**: 用户取消登录
- **6007**: 登录环境异常
- **6008**: 登录失败,未知异常
### 短信验证错误码
- **3000**: 短信验证码发送成功
- **3001**: 短信验证码发送失败
- **3002**: 短信验证码验证成功
- **3003**: 短信验证码验证失败
## 性能优化
### 网络优化
- 预登录机制减少用户等待时间
- 智能重试机制提高成功率
- 网络状态检测优化用户体验
### 内存优化
- 及时释放不用的资源
- 避免内存泄漏
- 合理管理生命周期
### 用户体验优化
- 自定义授权页面样式
- 加载状态指示
- 错误提示优化
## 安全特性
### 数据安全
- 通信数据加密传输
- 敏感信息本地加密存储
- 防止中间人攻击
### 业务安全
- 防刷机制
- 设备指纹验证
- 异常行为检测
## 测试指南
### 单元测试
- SDK 接口调用测试
- 错误处理测试
- 边界条件测试
### 集成测试
- 端到端登录流程测试
- 多平台兼容性测试
- 网络异常处理测试
### 性能测试
- 初始化耗时测试
- 内存使用测试
- 并发请求测试
## 故障排除
### 常见问题
1. **初始化失败**: 检查 AppKey 和渠道配置
2. **网络错误**: 检查网络权限和网络连接
3. **登录失败**: 检查运营商网络环境
4. **权限不足**: 检查必要权限的授权状态
### 调试技巧
- 开启调试模式查看详细日志
- 使用网络抓包工具分析请求
- 检查设备网络环境和运营商
## 版本更新
### 当前版本特性
- 支持三大运营商一键登录
- 支持短信验证码登录
- 支持自定义授权页面
- 完善的错误处理机制
### 后续规划
- 支持更多认证方式
- 优化用户体验
- 增强安全防护
## 总结
`jverify` 插件为 OneApp 提供了完整的极验验证解决方案,通过封装原生 SDK为 Flutter 应用提供了统一、便捷的验证接口。插件具有良好的跨平台兼容性和完善的错误处理机制,能够满足移动应用的各种验证场景需求。