Flutter Odoo数据交互插件odoo_repository的使用
Flutter Odoo数据交互插件odoo_repository的使用
简介
Odoo Models Repository
是一个用于与Odoo后端通信的抽象层。它帮助在Odoo和Dart客户端之间实现数据通信,并支持持久化和离线模式。
特性
- 静态类型:Odoo记录使用Dart类型表示。
- 离线模式:记录存储在本地缓存中。
- 调用队列:当网络恢复在线时,RPC调用将按顺序执行。
- 记录流:轻松集成数据更新到BLoC或FutureBuilder中。
描述
Odoo Repository
包使用 OdooRecord
作为基类来表示从远程Odoo实例获取的记录。记录具有以下属性:
- 存储数据的字段;
- 不可变;
- 可以与其他相同类型的记录进行比较;
- 可以转换为JSON格式。
基本的 res.partner
记录实现
import 'package:equatable/equatable.dart';
import 'package:odoo_repository/odoo_repository.dart';
class Partner extends Equatable implements OdooRecord {
const Partner(this.id, this.name);
@override
final int id;
final String name;
/// Converts Partner to JSON
@override
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
};
}
/// Creates [Partner] from JSON
static Partner fromJson(Map<String, dynamic> json) {
return Partner(
json['id'] as int,
json['name'] as String,
);
}
/// Equatable stuff to compare records
@override
List<Object> get props => [id, name];
/// List of fields we need to fetch from Odoo
static List<String> get oFields => ['id', 'name'];
@override
String toString() => 'User[$id]: $name';
}
定义 PartnerRepository
每个需要从Odoo获取的模型都需要有自己的 OdooRecord
和 OdooRepository
实现。定义 PartnerRepository
类,该类基于 OdooRepository
并配置为 Partner
类型。
import 'package:odoo_repository/odoo_repository.dart';
import 'package:odoo_rpc/odoo_rpc.dart';
import 'partner_record.dart';
class PartnerRepository extends OdooRepository<Partner> {
@override
final String modelName = 'res.partner';
PartnerRepository(OdooDatabase database) : super(database);
@override
Partner createRecordFromJson(Map<String, dynamic> json) {
return Partner.fromJson(json);
}
}
初始化 OdooEnvironment
首先需要实例化 OdooEnvironment
,它持有Odoo仓库列表并按顺序执行调用队列。
// Init cache storage implemented with Hive
final cache = OdooKvHive();
await cache.init();
// Try to recover session from storage
OdooSession? session = cache.get('cacheSessionKey', defaultValue: null);
const odooServerURL = 'https://my-odoo-instance.com';
final odooClient = OdooClient(odooServerURL, session);
final netConn = NetworkConnectivity();
const odooDbName = 'odoo';
final env = OdooEnvironment(odooClient, odooDbName, cache, netConn);
final partnerRepo = env.add(PartnerRepository(env));
env.add(UserRepository(env));
env.add(SaleOrderRepository(env));
env.add(SaleOrderLineRepository(env));
// and so on
// later we can access instance of PartnerRepository via
final saleOrderRepo = env.of<SaleOrderRepository>();
final saleOrderLineRepo = saleOrderRepo.env.of<SaleOrderLineRepository>();
实现 NetworkConnectivity
可以使用 connectivity
包来实现 NetConnState
。
import 'package:connectivity/connectivity.dart';
import 'package:odoo_repository/odoo_repository.dart'
show netConnState, NetConnState;
class NetworkConnectivity implements NetConnState {
static NetworkConnectivity? _singleton;
static late Connectivity _connectivity;
factory NetworkConnectivity() {
_singleton ??= NetworkConnectivity._();
return _singleton!;
}
NetworkConnectivity._() {
_connectivity = Connectivity();
}
@override
Future<netConnState> checkNetConn() async {
final connectivityResult = await (_connectivity.checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
return netConnState.online;
} else if (connectivityResult == ConnectivityResult.wifi) {
return netConnState.online;
}
return netConnState.offline;
}
@override
Stream<netConnState> get onNetConnChanged async* {
await for (var netState in _connectivity.onConnectivityChanged) {
if (netState == ConnectivityResult.mobile) {
// Went online now
yield netConnState.online;
} else if (netState == ConnectivityResult.wifi) {
// Went online now
yield netConnState.online;
} else if (netState == ConnectivityResult.none) {
// Went offline now
yield netConnState.offline;
}
}
}
}
示例代码
以下是一个完整的示例代码,展示了如何使用 odoo_repository
插件。
import 'dart:io';
import 'package:odoo_repository/odoo_repository.dart' show OdooEnvironment;
import 'package:odoo_rpc/odoo_rpc.dart';
import 'package:user_repository/user_repository.dart';
import 'config.dart';
import 'net_conn_impl.dart';
import 'odoo_kv_hive_impl.dart';
void main() async {
// Init cache storage implemented with Hive
final cache = OdooKvHive();
await cache.init();
// Try to recover session from storage
OdooSession? session = cache.get(cacheSessionKey, defaultValue: null);
// If session is still valid we will be logged in
final odooClient = OdooClient(odooServerURL, session);
// Catch session changes to store most recent one
final sessionChangedHandler = storeSesion(cache);
odooClient.sessionStream.listen(sessionChangedHandler);
// Network state tracker is needed by Repository
final netConn = NetworkConnectivity();
final env = OdooEnvironment(odooClient, odooDbName, cache, netConn);
// Alternative way to get instanciated user repo
// final userRepo = odooEnv.add((db) => UserRepository(db));
env.add(UserRepository(env));
final userRepo = env.of<UserRepository>();
var currentUser = userRepo.records[0];
print('Current user: ${currentUser.name}');
final userSub = userRepo.recordStream.listen((user) async {
if (user[0] != currentUser) {
if (currentUser.isPublic &&
!user[0].isPublic &&
user[0].login == 'admin') {
print('User changed to ${user[0]}');
currentUser = user[0];
// we are logged in
netConn.goOffline();
print(
'In offline mode we still can get record: ${userRepo.records[0]}');
print('scheduling a rpc call to create new user');
final newUser = await userRepo.create(User.publicUser()
.copyWith(login: 'newMe', name: 'New Me', lang: 'uk_UA'));
print('scheduling a rpc call to rename user that was created');
await userRepo.write(newUser.copyWith(name: 'New Me!'));
print('going online');
netConn.goOnline();
}
}
})
..onError((error) => print('User repo error: $error'));
ProcessSignal.sigint.watch().listen((signal) async {
print('Exiting...');
userRepo.logOutUser();
await userSub.cancel();
exit(0);
});
// Authentication will push new users list to userRepo.recordStream
await userRepo.authenticateUser(login: 'admin', password: 'admin');
print('Hit CTRL+c to exit');
// we need to wait unit async calls will finish
await Future.delayed(Duration(seconds: 100));
}
问题反馈
如果您遇到任何问题、错误或有功能请求,请在我们的 GitHub 页面上提交。
作者
Odoo Repository Library
由 ERP Ukraine 开发,Odoo Silver Partner。
更多关于Flutter Odoo数据交互插件odoo_repository的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter Odoo数据交互插件odoo_repository的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用odoo_repository
插件与Odoo进行数据交互的代码案例。odoo_repository
是一个用于与Odoo后端进行交互的Flutter插件。这个插件封装了一些常见的Odoo API调用,使得在Flutter应用中集成Odoo变得更加容易。
首先,确保你的Flutter项目中已经添加了odoo_repository
依赖。在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
odoo_repository: ^最新版本号 # 替换为最新的版本号
然后运行flutter pub get
来获取依赖。
接下来,你需要配置Odoo的连接信息。这通常在你的应用的主文件或配置文件中完成。
import 'package:odoo_repository/odoo_repository.dart';
final OdooRepository odoo = OdooRepository(
baseUrl: 'https://你的Odoo服务器地址',
db: '你的数据库名',
username: '你的Odoo用户名',
password: '你的Odoo密码',
);
现在,你可以使用odoo_repository
插件提供的方法来与Odoo进行交互。例如,获取Odoo中的某个模型的数据:
import 'package:flutter/material.dart';
import 'package:odoo_repository/odoo_repository.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Map<String, dynamic>> partners = [];
@override
void initState() {
super.initState();
_fetchPartners();
}
Future<void> _fetchPartners() async {
try {
final result = await odoo.searchRead(
model: 'res.partner',
domain: [], // 空域表示获取所有记录
fields: ['name', 'email'], // 只获取name和email字段
);
setState(() {
partners = result;
});
} catch (e) {
print('Error fetching partners: $e');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Odoo Partners'),
),
body: ListView.builder(
itemCount: partners.length,
itemBuilder: (context, index) {
final partner = partners[index];
return ListTile(
title: Text(partner['name']),
subtitle: Text(partner['email']),
);
},
),
),
);
}
}
在这个例子中,我们创建了一个Flutter应用,它使用odoo_repository
插件从Odoo的res.partner
模型中获取所有合作伙伴(通常代表联系人或客户)的姓名和电子邮件地址,并在列表中显示它们。
注意几点:
- 错误处理:在实际应用中,你应该添加更完善的错误处理机制。
- 安全性:不要在客户端代码中硬编码敏感信息(如用户名和密码)。考虑使用环境变量或安全的存储机制。
- 性能优化:对于大量数据,考虑分页加载或使用其他优化策略。
这个代码案例应该能够帮助你开始在Flutter应用中使用odoo_repository
插件与Odoo进行数据交互。如果你有更具体的需求或遇到问题,可以进一步探索odoo_repository
的文档和API。