Commit 32ab6569 authored by hywang's avatar hywang

1.增加性能测定页面

parent eed126e2
......@@ -25,6 +25,8 @@ public class ConnectManger {
public static String SERIAL_VERSION = "";
public static String VERSION = "";
public static boolean isSucc = false;
/**
* 从给定的上下文中获取 ConnectManger
*
......@@ -60,9 +62,11 @@ public class ConnectManger {
Log.e("lei", "getRm70xxVersion: "+String.format("设备连接:%s" + "\n软件版本:%s" + "\n硬件版本:%s" + "\n设备软件版本:%s" + "\n设备硬件版本:%s", "蓝牙已连接",
RM70XX_VERSION, RM70XX_SERIAL_VERSION, VERSION, SERIAL_VERSION));
if (!RM70XX_VERSION.equals("-2") && !RM70XX_SERIAL_VERSION.equals("-2") && !VERSION.equals("-1") && !SERIAL_VERSION.equals("-1")) {
isSucc = true;
return String.format("设备连接:%s" + "\n软件版本:%s" + "\n硬件版本:%s" + "\n设备软件版本:%s" + "\n设备硬件版本:%s", "蓝牙已连接",
RM70XX_VERSION, RM70XX_SERIAL_VERSION, VERSION, SERIAL_VERSION);
} else {
isSucc = false;
return "设备连接失败";
}
}
......
......@@ -95,6 +95,8 @@ public class RfidPlugin implements FlutterPlugin, MethodChannel.MethodCallHandle
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
getLinkage().setOnInventoryListener(this);
mContext = binding.getApplicationContext();
bleManagers = BleManagers.from(mContext);
connectManger = ConnectManger.from(getLinkage());
......@@ -120,13 +122,20 @@ public class RfidPlugin implements FlutterPlugin, MethodChannel.MethodCallHandle
public void run() {
String rm70xxVersion = connectManger.getRm70xxVersion();
Log.e("lei", "getVersion: " + rm70xxVersion);
Map<String, String> rm70xx_version = new HashMap<>();
rm70xx_version.put("key", "get_version");
rm70xx_version.put("value_RM70XX_VERSION", ConnectManger.RM70XX_VERSION);
rm70xx_version.put("value_RM70XX_SERIAL_VERSION", ConnectManger.RM70XX_SERIAL_VERSION);
rm70xx_version.put("value_VERSION", ConnectManger.VERSION);
rm70xx_version.put("value_SERIAL_VERSION", ConnectManger.SERIAL_VERSION);
_eventSink.success(rm70xxVersion);
handler.post(new Runnable() {
@Override
public void run() {
Map<String, String> rm70xx_version = new HashMap<>();
rm70xx_version.put("key", "get_version");
rm70xx_version.put("get_version_status", ConnectManger.isSucc?"0":"-1");
rm70xx_version.put("value_RM70XX_VERSION", ConnectManger.RM70XX_VERSION);
rm70xx_version.put("value_RM70XX_SERIAL_VERSION", ConnectManger.RM70XX_SERIAL_VERSION);
rm70xx_version.put("value_VERSION", ConnectManger.VERSION);
rm70xx_version.put("value_SERIAL_VERSION", ConnectManger.SERIAL_VERSION);
_eventSink.success(rm70xx_version);
}
});
}
}).start();
}
......@@ -154,12 +163,13 @@ public class RfidPlugin implements FlutterPlugin, MethodChannel.MethodCallHandle
} else if (call.method.equals("disconnect_device")) {
bleManagers.disConnectBLE(device);
} else if (call.method.equals("start_inventory")) {
// getLinkage().setOnInventoryListener(this);
isFirst = false;
InventoryParams inventoryParams = new InventoryParams();
inventoryParams.address = 0;
inventoryParams.inventoryArea = 1;
inventoryParams.len = 6;
getLinkage().Radio_SetInventoryParams(inventoryParams);
// InventoryParams inventoryParams = new InventoryParams();
// inventoryParams.address = 0;
// inventoryParams.inventoryArea = 1;
// inventoryParams.len = 6;
// getLinkage().Radio_SetInventoryParams(inventoryParams);
//TODO 无效果,加延时
getLinkage().startInventory(1, 0);
map.clear();
......@@ -187,21 +197,25 @@ public class RfidPlugin implements FlutterPlugin, MethodChannel.MethodCallHandle
@Override
public void getInventoryData(InventoryData inventoryData) {
Log.e("why:inventoryData:", inventoryData.toString());
if (inventoryData == null) return;
Map<String, String> result = new HashMap<>();
String epc = TextUtil.byteToHexString(inventoryData.getEPC_Data(), inventoryData.getEpcLength()).substring(1);
String tid = TextUtil.byteToHexString(inventoryData.getData(), inventoryData.getDataLength());
String tag = epc + tid;
Log.e("why:tag:", tag);
if (!map.containsKey(tag)) {
map.put(tag, epc);
dataList.add(inventoryData);
}
if (!isFirst) {
Log.e("why:isFirst:", isFirst+"");
getLinkage().stopInventory();
isFirst = true;
handler.post(new Runnable() {
@Override
public void run() {
Log.e("why:android:InventoryData:", TextUtil.byteToHexString(dataList.get(0).getEPC_Data(), dataList.get(0).getEpcLength()));
result.put("key", "InventoryData");
result.put("value", TextUtil.byteToHexString(dataList.get(0).getEPC_Data(), dataList.get(0).getEpcLength()));
_eventSink.success(result);
......@@ -242,7 +256,9 @@ public class RfidPlugin implements FlutterPlugin, MethodChannel.MethodCallHandle
ConnectionState connectionState = device.getConnectionState();
if (connectionState == ConnectionState.SCANNING_FOR_RECONNECTION) {
} else if (connectionState == ConnectionState.DISCONNECTED) {
//TODO
Map<String, String> BleDevices = new HashMap<>();
BleDevices.put("key", "DISCONNECTED");
_eventSink.success(BleDevices);
} else if (connectionState == ConnectionState.CONNECTING) {
} else if (connectionState == ConnectionState.CONNECTED) {
//TODO
......@@ -336,4 +352,6 @@ public class RfidPlugin implements FlutterPlugin, MethodChannel.MethodCallHandle
}
}
}
}
package com.phlx.anchor_collect_flutter.ble;
import java.util.UUID;
public class Configs {
public static UUID uuid_service;
public static UUID uuid_write;
public static UUID uuid_notify;
public static UUID uuid_indicate;
}
package com.phlx.anchor_collect_flutter.ble;
import cn.wandersnail.ble.Device;
public interface OnBleSearchListener {
/**
* 在搜索设备之前回调
*/
void onStartDiscovery();
/**
* 搜索到新设备
*
* @param device 新设备
*/
void onBleDeviceFound(Device device);
void onBleError(String e);
}
......@@ -18,7 +18,12 @@ class APIS{
///基础信息
static const download_cattle_list = "/api/flutter/cattleresume/list";
static const download_cattle_list_sync = "/api/flutter/cattleresume/sync/add";
static const upload_Cattle_List = "/api/flutter/cattleresume/add";
static const upload_cattle_List = "/api/flutter/cattleresume/add";
///性能测定
static const download_performance_list = "/api/flutter/performance/list";
static const download_performance_list_sync = "/api/flutter/performance/sync/add";
static const upload_performance_List = "/api/flutter/performance/add";
///消息
static const get_message_count = "/api/flutter/msg/index";
......
......@@ -12,6 +12,9 @@ class Config {
static bool isOnLine = false;
//是否连接蓝牙设备
static bool isConnect = false;
// 定义一个全局的相机列表
static List<CameraDescription> cameras = [];
......@@ -26,78 +29,50 @@ class Config {
static String SP_DEPT_ID = 'sp_dept_id';
static String SP_DEPT_NAME = 'sp_dept_name';
static String SP_CATTLERESUME_UPDATE_TIME = 'sp_cattleresume_update_time';
}
class IconFont {
static const _fontFamily = 'myIcon';
///banner下方牛只数据
static const IconData breeding_count =
IconData(0xe61e, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData obsolete_count =
IconData(0xe659, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData dead_count =
IconData(0xe60b, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData sell_count =
IconData(0xe69c, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData breeding_count = IconData(0xe61e, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData obsolete_count = IconData(0xe659, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData dead_count = IconData(0xe60b, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData sell_count = IconData(0xe69c, fontFamily: _fontFamily, matchTextDirection: true);
///首页功能
static const IconData cattle_resume =
IconData(0xe9aa, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData performance =
IconData(0xe697, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData medical_record =
IconData(0xe601, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData breeding_record =
IconData(0xe76b, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData immune =
IconData(0xe616, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData weight =
IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData cattle_resume = IconData(0xe9aa, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData performance = IconData(0xe697, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData medical_record = IconData(0xe601, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData breeding_record = IconData(0xe76b, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData immune = IconData(0xe616, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData weight = IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
///tab
static const IconData home =
IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData message =
IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData sync =
IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData mine =
IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData home = IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData message = IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData sync = IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData mine = IconData(0xe9fb, fontFamily: _fontFamily, matchTextDirection: true);
///消息
static const IconData parturition_warn =
IconData(0xe6b1, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData weaning_warn =
IconData(0xe600, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData breeding_warn =
IconData(0xe697, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData bull_breeding_warn =
IconData(0xe640, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData postpartum_breeding_warn =
IconData(0xe62f, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData postpartum_check_warn =
IconData(0xe76b, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData parturition_warn = IconData(0xe6b1, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData weaning_warn = IconData(0xe600, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData breeding_warn = IconData(0xe697, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData bull_breeding_warn = IconData(0xe640, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData postpartum_breeding_warn = IconData(0xe62f, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData postpartum_check_warn = IconData(0xe76b, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData gravidity_initial_check_warn =
IconData(0xe65a, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData gravidity_recheck_warn =
IconData(0xe65b, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData cow_estrus_warn =
IconData(0xe632, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData prenatally_warn =
IconData(0xe624, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData over_time_warn =
IconData(0xe784, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData anestrus_warn =
IconData(0xe6ea, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData cow_weed_out_count_warn =
IconData(0xe6ba, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData gravidity_recheck_warn = IconData(0xe65b, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData cow_estrus_warn = IconData(0xe632, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData prenatally_warn = IconData(0xe624, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData over_time_warn = IconData(0xe784, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData anestrus_warn = IconData(0xe6ea, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData cow_weed_out_count_warn = IconData(0xe6ba, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData cow_weed_out_moom_age_warn =
IconData(0xe7b8, fontFamily: _fontFamily, matchTextDirection: true);
static const IconData bull_weed_out_moom_age_warn =
......
......@@ -140,15 +140,15 @@ class BleService extends GetxService {
_notifyCharacteristic = c;
c.setNotifyValue(true);
_valueReceivedSubscription =
c.onValueReceived.listen((value) async {
_valueReceivedSubscription = c.onValueReceived.listen((value) async {
if (value.isNotEmpty) {
if (!isFirst) {
isFirst = true;
RfidPlugin.getVersion().then((value) {
Config.version=value;
print('Version: $value');
});
getVersion();
// RfidPlugin.getVersion().then((value) {
// Config.version=value;
// print('Version: $value');
// });
}
}
if (value.isEmpty) return;
......@@ -177,6 +177,10 @@ class BleService extends GetxService {
});
}
getVersion(){
RfidPlugin.getVersion();
}
// 写入数据
Future<void> writeData(List<int> data) async {
await _writeCharacteristic.write(data);
......
......@@ -5,6 +5,7 @@ import 'package:isar/isar.dart';
import '../models/cattle_resume_entity.dart';
import '../models/dict_entity.dart';
import '../models/performance.dart';
import '../models/user_model.dart';
/// 全局状态管理
......@@ -21,6 +22,7 @@ class GlobalService extends GetxService {
UserModelDeptSchema,
UserModelRolesSchema,
CattleResumeEntitySchema,
PerformanceEntitySchema,
DictEntitySchema,
], inspector: true);
......
......@@ -9,6 +9,7 @@ import 'package:anchor_collect_flutter/models/cattle_resume_entity.dart';
import 'package:anchor_collect_flutter/models/dict_entity.dart';
import 'package:anchor_collect_flutter/models/login_entity.dart';
import 'package:anchor_collect_flutter/models/message.dart';
import 'package:anchor_collect_flutter/models/performance.dart';
import 'package:anchor_collect_flutter/models/user_model.dart';
JsonConvert jsonConvert = JsonConvert();
......@@ -146,6 +147,9 @@ class JsonConvert {
if (<MessageModel>[] is M) {
return data.map<MessageModel>((Map<String, dynamic> e) => MessageModel.fromJson(e)).toList() as M;
}
if (<PerformanceEntity>[] is M) {
return data.map<PerformanceEntity>((Map<String, dynamic> e) => PerformanceEntity.fromJson(e)).toList() as M;
}
if (<UserModel>[] is M) {
return data.map<UserModel>((Map<String, dynamic> e) => UserModel.fromJson(e)).toList() as M;
}
......@@ -190,6 +194,7 @@ class JsonConvertClassCollection {
(DictEntity).toString(): DictEntity.fromJson,
(LoginEntity).toString(): LoginEntity.fromJson,
(MessageModel).toString(): MessageModel.fromJson,
(PerformanceEntity).toString(): PerformanceEntity.fromJson,
(UserModel).toString(): UserModel.fromJson,
(UserModelParams).toString(): UserModelParams.fromJson,
(UserModelDept).toString(): UserModelDept.fromJson,
......
import 'package:anchor_collect_flutter/generated/json/base/json_convert_content.dart';
import 'package:anchor_collect_flutter/models/performance.dart';
import 'package:isar/isar.dart';
PerformanceEntity $PerformanceEntityFromJson(Map<String, dynamic> json) {
final PerformanceEntity performanceEntity = PerformanceEntity();
final Id? id = jsonConvert.convert<Id>(json['id']);
if (id != null) {
performanceEntity.id = id;
}
final String? unid = jsonConvert.convert<String>(json['unid']);
if (unid != null) {
performanceEntity.unid = unid;
}
final String? cattleresumeId = jsonConvert.convert<String>(json['cattleresumeId']);
if (cattleresumeId != null) {
performanceEntity.cattleresumeId = cattleresumeId;
}
final String? age = jsonConvert.convert<String>(json['age']);
if (age != null) {
performanceEntity.age = age;
}
final String? measureDate = jsonConvert.convert<String>(json['measureDate']);
if (measureDate != null) {
performanceEntity.measureDate = measureDate;
}
final double? height = jsonConvert.convert<double>(json['height']);
if (height != null) {
performanceEntity.height = height;
}
final double? length = jsonConvert.convert<double>(json['length']);
if (length != null) {
performanceEntity.length = length;
}
final double? bust = jsonConvert.convert<double>(json['bust']);
if (bust != null) {
performanceEntity.bust = bust;
}
final double? weight = jsonConvert.convert<double>(json['weight']);
if (weight != null) {
performanceEntity.weight = weight;
}
final double? chestWidth = jsonConvert.convert<double>(json['chestWidth']);
if (chestWidth != null) {
performanceEntity.chestWidth = chestWidth;
}
final double? chestDeep = jsonConvert.convert<double>(json['chestDeep']);
if (chestDeep != null) {
performanceEntity.chestDeep = chestDeep;
}
final double? waistWidth = jsonConvert.convert<double>(json['waistWidth']);
if (waistWidth != null) {
performanceEntity.waistWidth = waistWidth;
}
final double? crossWidth = jsonConvert.convert<double>(json['crossWidth']);
if (crossWidth != null) {
performanceEntity.crossWidth = crossWidth;
}
final double? guanWei = jsonConvert.convert<double>(json['guanWei']);
if (guanWei != null) {
performanceEntity.guanWei = guanWei;
}
final double? eyeMuscleArea = jsonConvert.convert<double>(json['eyeMuscleArea']);
if (eyeMuscleArea != null) {
performanceEntity.eyeMuscleArea = eyeMuscleArea;
}
final String? grade = jsonConvert.convert<String>(json['grade']);
if (grade != null) {
performanceEntity.grade = grade;
}
final double? hairLength = jsonConvert.convert<double>(json['hairLength']);
if (hairLength != null) {
performanceEntity.hairLength = hairLength;
}
final double? hairFineness = jsonConvert.convert<double>(json['hairFineness']);
if (hairFineness != null) {
performanceEntity.hairFineness = hairFineness;
}
final double? shearing = jsonConvert.convert<double>(json['shearing']);
if (shearing != null) {
performanceEntity.shearing = shearing;
}
final double? backWidth = jsonConvert.convert<double>(json['backWidth']);
if (backWidth != null) {
performanceEntity.backWidth = backWidth;
}
final String? breedRes = jsonConvert.convert<String>(json['breedRes']);
if (breedRes != null) {
performanceEntity.breedRes = breedRes;
}
final String? health = jsonConvert.convert<String>(json['health']);
if (health != null) {
performanceEntity.health = health;
}
final String? immune = jsonConvert.convert<String>(json['immune']);
if (immune != null) {
performanceEntity.immune = immune;
}
final String? uploadStatus = jsonConvert.convert<String>(json['uploadStatus']);
if (uploadStatus != null) {
performanceEntity.uploadStatus = uploadStatus;
}
final String? deptId = jsonConvert.convert<String>(json['deptId']);
if (deptId != null) {
performanceEntity.deptId = deptId;
}
final String? searchValue = jsonConvert.convert<String>(json['searchValue']);
if (searchValue != null) {
performanceEntity.searchValue = searchValue;
}
final String? createBy = jsonConvert.convert<String>(json['createBy']);
if (createBy != null) {
performanceEntity.createBy = createBy;
}
final String? createTime = jsonConvert.convert<String>(json['createTime']);
if (createTime != null) {
performanceEntity.createTime = createTime;
}
final String? updateBy = jsonConvert.convert<String>(json['updateBy']);
if (updateBy != null) {
performanceEntity.updateBy = updateBy;
}
final String? updateTime = jsonConvert.convert<String>(json['updateTime']);
if (updateTime != null) {
performanceEntity.updateTime = updateTime;
}
final String? remark = jsonConvert.convert<String>(json['remark']);
if (remark != null) {
performanceEntity.remark = remark;
}
return performanceEntity;
}
Map<String, dynamic> $PerformanceEntityToJson(PerformanceEntity entity) {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = entity.id;
data['unid'] = entity.unid;
data['cattleresumeId'] = entity.cattleresumeId;
data['age'] = entity.age;
data['measureDate'] = entity.measureDate;
data['height'] = entity.height;
data['length'] = entity.length;
data['bust'] = entity.bust;
data['weight'] = entity.weight;
data['chestWidth'] = entity.chestWidth;
data['chestDeep'] = entity.chestDeep;
data['waistWidth'] = entity.waistWidth;
data['crossWidth'] = entity.crossWidth;
data['guanWei'] = entity.guanWei;
data['eyeMuscleArea'] = entity.eyeMuscleArea;
data['grade'] = entity.grade;
data['hairLength'] = entity.hairLength;
data['hairFineness'] = entity.hairFineness;
data['shearing'] = entity.shearing;
data['backWidth'] = entity.backWidth;
data['breedRes'] = entity.breedRes;
data['health'] = entity.health;
data['immune'] = entity.immune;
data['uploadStatus'] = entity.uploadStatus;
data['deptId'] = entity.deptId;
data['searchValue'] = entity.searchValue;
data['createBy'] = entity.createBy;
data['createTime'] = entity.createTime;
data['updateBy'] = entity.updateBy;
data['updateTime'] = entity.updateTime;
data['remark'] = entity.remark;
return data;
}
extension PerformanceEntityExtension on PerformanceEntity {
PerformanceEntity copyWith({
Id? id,
String? unid,
String? cattleresumeId,
String? age,
String? measureDate,
double? height,
double? length,
double? bust,
double? weight,
double? chestWidth,
double? chestDeep,
double? waistWidth,
double? crossWidth,
double? guanWei,
double? eyeMuscleArea,
String? grade,
double? hairLength,
double? hairFineness,
double? shearing,
double? backWidth,
String? breedRes,
String? health,
String? immune,
String? uploadStatus,
String? deptId,
String? searchValue,
String? createBy,
String? createTime,
String? updateBy,
String? updateTime,
String? remark,
}) {
return PerformanceEntity()
..id = id ?? this.id
..unid = unid ?? this.unid
..cattleresumeId = cattleresumeId ?? this.cattleresumeId
..age = age ?? this.age
..measureDate = measureDate ?? this.measureDate
..height = height ?? this.height
..length = length ?? this.length
..bust = bust ?? this.bust
..weight = weight ?? this.weight
..chestWidth = chestWidth ?? this.chestWidth
..chestDeep = chestDeep ?? this.chestDeep
..waistWidth = waistWidth ?? this.waistWidth
..crossWidth = crossWidth ?? this.crossWidth
..guanWei = guanWei ?? this.guanWei
..eyeMuscleArea = eyeMuscleArea ?? this.eyeMuscleArea
..grade = grade ?? this.grade
..hairLength = hairLength ?? this.hairLength
..hairFineness = hairFineness ?? this.hairFineness
..shearing = shearing ?? this.shearing
..backWidth = backWidth ?? this.backWidth
..breedRes = breedRes ?? this.breedRes
..health = health ?? this.health
..immune = immune ?? this.immune
..uploadStatus = uploadStatus ?? this.uploadStatus
..deptId = deptId ?? this.deptId
..searchValue = searchValue ?? this.searchValue
..createBy = createBy ?? this.createBy
..createTime = createTime ?? this.createTime
..updateBy = updateBy ?? this.updateBy
..updateTime = updateTime ?? this.updateTime
..remark = remark ?? this.remark;
}
}
\ No newline at end of file
......@@ -43,11 +43,11 @@ Future<void> initServices() async {
///这里是你放get_storage、hive、shared_pref初始化的地方。
///或者moor连接,或者其他什么异步的东西。
await Get.putAsync(() => GlobalService().init());
await Get.putAsync(() => BleService().init());
// await Get.putAsync(() => BleService().init());
RfidPlugin();
RfidPlugin.initRfid();
RfidPlugin.initRfid();
print('All services started...');
}
......
import 'dart:convert';
import 'package:isar/isar.dart';
import '../generated/json/base/json_field.dart';
import '../generated/json/performance.g.dart';
part 'performance.g.dart';
@JsonSerializable()
@collection
class Performance{
class PerformanceEntity{
Id id = Isar.autoIncrement;
......@@ -84,12 +90,12 @@ class Performance{
String? grade;
/**
* 毛长度(cm)
* 毛长度(cm)
*/
double? hairLength;
/**
* 毛细度(微米)
* 毛细度(微米)
*/
double? hairFineness;
......@@ -143,6 +149,17 @@ class Performance{
/** 备注 */
String? remark;
PerformanceEntity();
factory PerformanceEntity.fromJson(Map<String, dynamic> json) =>
$PerformanceEntityFromJson(json);
Map<String, dynamic> toJson() => $PerformanceEntityToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -9,6 +9,8 @@ import 'package:isar/isar.dart';
import 'package:uuid/uuid.dart';
import '../../models/cattle_resume_entity.dart';
import '../../rfid/rfid_plugin.dart';
import '../../routes/routes.dart';
import '../../utils/compress_util.dart';
import '../../utils/dict_utils.dart';
import 'cattle_resume_state.dart';
......@@ -61,6 +63,22 @@ class CattleResumeLogic extends GetxController {
update();
}
///扫描高频耳标
scanRfid() {
if(!Config.isConnect){
Get.toNamed(AppRoute.SETTING);
return;
}
print('why:RfidPlugin.isInventory:${RfidPlugin.isInventory}');
if (!RfidPlugin.isInventory) {
RfidPlugin.startInventory((epc, agrs1) {
RfidPlugin.stopInventory();
print('why:epc:$epc');
state.entity.registrationNo = epc;
});
}
}
save() async {
if (await checkRequiredFields()) {
return;
......@@ -105,7 +123,7 @@ class CattleResumeLogic extends GetxController {
DialogUtils.showToast('必须填写可视耳标');
return true;
}
if (!EmptyUtils.isStrNotEmpty(state.entity.photoPath)&&!EmptyUtils.isStrNotEmpty(state.photoPath)) {
if (!EmptyUtils.isStrNotEmpty(state.entity.photoPath) && !EmptyUtils.isStrNotEmpty(state.photoPath)) {
DialogUtils.showToast('必须上传牛只拍照');
return true;
}
......@@ -125,7 +143,7 @@ class CattleResumeLogic extends GetxController {
DialogUtils.showToast('必须选择出生日期');
return true;
}
if (state.entity.birthHeavy==null||state.entity.birthHeavy==0) {
if (state.entity.birthHeavy == null || state.entity.birthHeavy == 0) {
DialogUtils.showToast('必须填写出生重量');
return true;
}
......@@ -142,14 +160,26 @@ class CattleResumeLogic extends GetxController {
// return true;
// }
if(await GlobalService.to.isar.cattleResumeEntitys.filter().not().unidEqualTo(state.entity.unid)
.and().registrationNoEqualTo(state.entity.registrationNo).count() >0){
if (await GlobalService.to.isar.cattleResumeEntitys
.filter()
.not()
.unidEqualTo(state.entity.unid)
.and()
.registrationNoEqualTo(state.entity.registrationNo)
.count() >
0) {
DialogUtils.showToast('高频耳标已使用');
return true;
}
if(await GlobalService.to.isar.cattleResumeEntitys.filter().not().unidEqualTo(state.entity.unid)
.and().individualNoEqualTo(state.entity.individualNo).count() >0){
if (await GlobalService.to.isar.cattleResumeEntitys
.filter()
.not()
.unidEqualTo(state.entity.unid)
.and()
.individualNoEqualTo(state.entity.individualNo)
.count() >
0) {
DialogUtils.showToast('可视耳标已使用');
return true;
}
......
......@@ -58,7 +58,9 @@ class CattleResumePage extends StatelessWidget {
const SizedBox(
width: 10,
),
getItemView('高频耳标', state.entity.registrationNo ?? '', () => {}),
getItemView('高频耳标', state.entity.registrationNo ?? '', () => {
logic.scanRfid(),
}),
const SizedBox(
width: 10,
),
......
import 'package:anchor_collect_flutter/models/performance.dart';
import 'package:get/get.dart';
import 'package:isar/isar.dart';
import 'package:uuid/uuid.dart';
import '../../congifs.dart';
import '../../controllers/global_service.dart';
import '../../utils/dialog_utils.dart';
import '../../utils/dict_utils.dart';
import '../../utils/empty_utils.dart';
import '../../utils/sp_helper.dart';
import 'performance_state.dart';
class PerformanceLogic extends GetxController {
final PerformanceState state = PerformanceState();
// 创建一个Uuid实例
var uuid = Uuid();
@override
void onReady() {
var entity = Get.arguments;
state.unid = uuid.v4();
if (entity != null) {
state.entity = entity;
state.isModify = true;
state.unid = state.entity.unid!;
refreshDictData();
}
}
///初始化字典项
refreshDictData() async {
state.age = await DictUtils.getDictName('zxgl_performance_age', state.entity.age ?? '');
state.grade = await DictUtils.getDictName('zxgl_cattleresume_grade', state.entity.grade ?? '');
update();
}
save() async {
if (await checkRequiredFields()) {
return;
}
DialogUtils.showLoadingDialog('保存中。。。');
if (state.isModify) {
state.entity.updateTime = DateTime.now().toString();
state.entity.updateBy = SpHelper.getStorage(Config.SP_DEPT_ID);
} else {
state.entity.unid = state.unid;
state.entity.createTime = DateTime.now().toString();
state.entity.createBy = SpHelper.getStorage(Config.SP_DEPT_ID);
}
state.entity.uploadStatus = '0';
///保存性能测定
await GlobalService.to.isar.writeTxn(() async => {
await GlobalService.to.isar.performanceEntitys.put(state.entity),
DialogUtils.showToast('保存性能测定成功'),
DialogUtils.dismissDialog(),
Get.back(),
});
}
Future<bool> checkRequiredFields() async {
// if (!EmptyUtils.isStrNotEmpty(state.entity.registrationNo)) {
// DialogUtils.showToast('必须扫描高频耳标');
// return true;
// }
// if (!EmptyUtils.isStrNotEmpty(state.entity.individualNo)) {
// DialogUtils.showToast('必须填写可视耳标');
// return true;
// }
// if (!EmptyUtils.isStrNotEmpty(state.entity.photoPath) && !EmptyUtils.isStrNotEmpty(state.photoPath)) {
// DialogUtils.showToast('必须上传牛只拍照');
// return true;
// }
// if (!EmptyUtils.isStrNotEmpty(state.entity.circleNo)) {
// DialogUtils.showToast('必须选择圈舍');
// return true;
// }
// if (!EmptyUtils.isStrNotEmpty(state.entity.raiseType)) {
// DialogUtils.showToast('必须选择饲养类型');
// return true;
// }
if (!EmptyUtils.isStrNotEmpty(state.entity.age)) {
DialogUtils.showToast('必须选择年龄');
return true;
}
if (!EmptyUtils.isStrNotEmpty(state.entity.measureDate)) {
DialogUtils.showToast('必须选择测量日期');
return true;
}
// if (state.entity.birthHeavy == null || state.entity.birthHeavy == 0) {
// DialogUtils.showToast('必须填写出生重量');
// return true;
// }
// if (!EmptyUtils.isStrNotEmpty(state.entity.sex)) {
// DialogUtils.showToast('必须选择性别');
// return true;
// }
// if (!EmptyUtils.isStrNotEmpty(state.entity.status)) {
// DialogUtils.showToast('必须选择状态');
// return true;
// }
// if (!EmptyUtils.isStrNotEmpty(state.entity.colour)) {
// DialogUtils.showToast('必须填写犊牛毛色');
// return true;
// }
return false;
}
///是否有此年龄记录检查
Future<bool> checkAge() async {
List<PerformanceEntity> performanceEntitys = await GlobalService.to.isar.performanceEntitys
.filter()
.cattleresumeIdEqualTo(state.entity.cattleresumeId)
.and()
.ageEqualTo(state.entity.age).findAll();
if (performanceEntitys.isNotEmpty) {
return true;
}else {
return false;
}
}
}
import '../../models/performance.dart';
class PerformanceState {
late PerformanceEntity entity = PerformanceEntity();
/** 电子耳标 */
String? registrationNo;
/** 可视耳标 */
String? individualNo;
late String unid;
bool isModify = false;
late String age='';
late String grade='';
PerformanceState() {
///Initialize variables
}
......
import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:get/get.dart';
import '../../congifs.dart';
import '../../utils/dialog_utils.dart';
import '../../utils/dict_utils.dart';
import '../../utils/empty_utils.dart';
import 'performance_logic.dart';
class PerformancePage extends StatelessWidget {
const PerformancePage({Key? key}) : super(key: key);
PerformancePage({Key? key}) : super(key: key);
final logic = Get.find<PerformanceLogic>();
final state = Get.find<PerformanceLogic>().state;
@override
Widget build(BuildContext context) {
final logic = Get.find<PerformanceLogic>();
final state = Get.find<PerformanceLogic>().state;
return Scaffold(
appBar: AppBar(
title: const Text('性能测定'),
backgroundColor: Colors.blue,
centerTitle: true,
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: GetBuilder<PerformanceLogic>(builder: (logic) {
return ListView(
children: [
Row(
children: [
const SizedBox(
width: 10,
),
getItemView('高频耳标', state.registrationNo ?? '', () => {}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView('可视耳标', state.individualNo ?? '', () => {}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'年龄',
state.age ?? '',
() async => {
DialogUtils.showSingleListDialog(await DictUtils.getDictList('zxgl_raiseType'),
onPositive: (selectReslut) => {
state.age = selectReslut.key,
state.entity.age = selectReslut.value,
logic.update(),
}),
}),
getItemView(
'测量日期',
state.entity.measureDate ?? '',
() => {
DialogUtils.showTimeDialog(
context,
isTime: false,
title: '请选择测量日期',
onPositive: (date) => {
state.entity.measureDate = date,
logic.update(),
},
),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'体高(cm)',
(state.entity.height ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只体高',
isNum: true,
onPositive: (text) => {
state.entity.height = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
getItemView(
'体长(cm)',
(state.entity.length ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只体长',
isNum: true,
onPositive: (text) => {
state.entity.length = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'胸围(cm)',
(state.entity.bust ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只胸围',
isNum: true,
onPositive: (text) => {
state.entity.bust = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
getItemView(
'体重',
(state.entity.weight ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只体重',
isNum: true,
onPositive: (text) => {
state.entity.weight = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'胸宽(cm)',
(state.entity.chestWidth ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只胸宽',
isNum: true,
onPositive: (text) => {
state.entity.chestWidth = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
getItemView(
'胸深(cm)',
(state.entity.chestDeep ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只胸深',
isNum: true,
onPositive: (text) => {
state.entity.chestDeep = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'腰角宽(cm)',
(state.entity.waistWidth ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只腰角宽',
isNum: true,
onPositive: (text) => {
state.entity.waistWidth = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
getItemView(
'十字部宽(cm)',
(state.entity.crossWidth ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只十字部宽',
isNum: true,
onPositive: (text) => {
state.entity.crossWidth = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'管维(cm)',
(state.entity.guanWei ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只管维',
isNum: true,
onPositive: (text) => {
state.entity.guanWei = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
getItemView(
'眼肌面积',
(state.entity.eyeMuscleArea ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只眼肌面积',
isNum: true,
onPositive: (text) => {
state.entity.eyeMuscleArea = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'等级',
state.grade ?? '',
() async => {
DialogUtils.showSingleListDialog(await DictUtils.getDictList('zxgl_raiseType'),
onPositive: (selectReslut) => {
state.grade = selectReslut.key,
state.entity.grade = selectReslut.value,
logic.update(),
}),
}),
getItemView(
'毛长度(cm)',
(state.entity.hairLength ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只毛长度',
isNum: true,
onPositive: (text) => {
state.entity.hairLength = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'毛细度(微米)',
(state.entity.hairFineness ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只毛细度',
isNum: true,
onPositive: (text) => {
state.entity.hairFineness = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
getItemView(
'剪毛量(kg)',
(state.entity.shearing ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只剪毛量',
isNum: true,
onPositive: (text) => {
state.entity.shearing = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'背腰宽',
(state.entity.backWidth ?? '').toString(),
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只背腰宽',
isNum: true,
onPositive: (text) => {
state.entity.backWidth = double.tryParse(text ?? '0'),
logic.update(),
}),
}),
getItemView(
'繁殖成绩',
state.entity.breedRes ?? '',
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只繁殖成绩',
onPositive: (text) => {
state.entity.breedRes = text ?? '',
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
getItemView(
'健康状况',
state.entity.health ?? '',
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只健康状况',
onPositive: (text) => {
state.entity.health = text ?? '',
logic.update(),
}),
}),
getItemView(
'免疫情况',
state.entity.immune ?? '',
() => {
DialogUtils.showInputDialog(
hintText: '输入牛只免疫情况',
onPositive: (text) => {
state.entity.immune = text ?? '',
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
Row(
children: [
const SizedBox(
width: 10,
),
// getItemView(
// '状态',
// state.status ?? '',
// () async => {
// DialogUtils.showSingleListDialog(
// await DictUtils.getDictList('zxgl_cattleresume_status'),
// onPositive: (selectReslut) => {
// state.status = selectReslut.key,
// state.entity.status = selectReslut.value,
// logic.update(),
// }),
// }),
getItemView(
'备注',
state.entity.remark ?? '',
() => {
DialogUtils.showInputDialog(
hintText: '输入备注',
onPositive: (text) => {
state.entity.remark = text,
logic.update(),
}),
}),
const SizedBox(
width: 10,
),
],
),
],
);
}),
),
// Row(children: [
// Expanded(
// child:
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor: MaterialStateProperty.all(Colors.white),
padding: MaterialStateProperty.all(const EdgeInsets.all(10)),
),
onPressed: () => {
logic.save(),
},
child: const Text("保存"),
),
// ),
// ]),
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: Padding(
padding: const EdgeInsets.only(right: 20.0, bottom: 80.0),
child: SpeedDial(
icon: Icons.add,
activeIcon: Icons.close,
spacing: 3,
// openCloseDial: ValueNotifier.value,
childPadding: const EdgeInsets.all(5),
buttonSize: const Size(40, 40),
elevation: 8.0,
children: [
SpeedDialChild(
child: const Icon(IconFont.cattle_resume),
backgroundColor: Colors.black,
foregroundColor: Colors.white,
label: '基础信息',
onTap: () {
DialogUtils.showToast('toast...');
},
onLongPress: () => debugPrint('FIRST CHILD LONG PRESS'),
),
SpeedDialChild(
child: const Icon(IconFont.performance),
backgroundColor: const Color.fromARGB(255, 104, 152, 218),
foregroundColor: Colors.white,
label: '性能测定',
onTap: () => {
DialogUtils.showLoadingDialog('加载中...'),
},
),
SpeedDialChild(
child: const Icon(IconFont.medical_record),
backgroundColor: const Color.fromARGB(255, 220, 128, 70),
foregroundColor: Colors.white,
label: '诊疗记录',
visible: true,
onTap: () => DialogUtils.showInputDialog(onPositive: (inputStr) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(inputStr)));
}),
onLongPress: () => debugPrint('THIRD CHILD LONG PRESS'),
),
SpeedDialChild(
child: const Icon(IconFont.breeding_record),
backgroundColor: const Color.fromARGB(255, 210, 76, 154),
foregroundColor: Colors.white,
label: '配种记录',
onTap: () => {DialogUtils.showWarningDialog('配种记录!!')},
onLongPress: () => debugPrint('FIRST CHILD LONG PRESS'),
),
SpeedDialChild(
child: const Icon(IconFont.immune),
backgroundColor: const Color.fromARGB(255, 116, 154, 110),
foregroundColor: Colors.white,
label: '免疫记录',
onTap: () => {},
),
SpeedDialChild(
child: const Icon(IconFont.weight),
backgroundColor: const Color.fromARGB(255, 150, 114, 89),
foregroundColor: Colors.white,
label: '称重记录',
visible: true,
onTap: () => DialogUtils.showMultipleListDialog(['aaa', 'bbb', 'ccc'], ['111', '222', '333'],
onPositive: (result) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(result)));
}),
// onLongPress: () => ,
),
],
),
),
);
}
return Container();
getItemView(String title, String context, Function() onClick) {
return Expanded(
child: InkWell(
onTap: onClick,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 2,
),
],
),
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 10,
),
Text(
title,
style: const TextStyle(
color: Colors.blue,
fontSize: 14,
),
),
const SizedBox(
height: 10,
),
SizedBox(
height: 1,
child: Container(
color: Colors.black12,
height: 1,
),
),
const SizedBox(
height: 10,
),
Text(
context,
style: const TextStyle(
color: Colors.black,
fontSize: 14,
),
),
const SizedBox(
height: 10,
),
],
),
),
),
);
}
}
......@@ -7,6 +7,7 @@ import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../congifs.dart';
import '../../rfid/rfid_plugin.dart';
import 'setting_state.dart';
......@@ -20,26 +21,30 @@ class SettingLogic extends GetxController {
}
refreshBle() {
if (BleService.to.isScanning.value) {
if (state.isScanning.value) {
DialogUtils.showToast('停止扫描');
RfidPlugin.stopScanDevice();
} else {
BleService.to.scanResults.clear();
state.scanResults.clear();
DialogUtils.showToast('开始扫描');
RfidPlugin.startScanDevice((args, args2) {
state.scanResults.add(args);
});
}
BleService.to.toggleScan();
}
connectBle(BuildContext context, int index) {
if (BleService.to.isConnect) {
BleService.to.stopScan();
if (Config.isConnect) {
RfidPlugin.disConnectDevice();
}
BleService.to.connectToDevice(index, (args) async {
BleService.to.isConnect = true;
//DialogUtils.showToast('蓝牙设备连接成功:$versionStr');
// DialogUtils.dismissDialog();
RfidPlugin.stopScanDevice();
state.isScanning.value = false;
RfidPlugin.connectDevice(state.scanResults[index], (args, args1) {
print('event:进入callback');
DialogUtils.showToast('设备连接成功');
Get.back();
});
Config.isConnect = true;
}
// 检查权限
......
......@@ -6,7 +6,8 @@ class SettingState {
bool isBleOn = false;
RxList<String> scanResults = <String>[].obs;
RxBool isScanning = false.obs;
SettingState() {
///Initialize variables
......
......@@ -29,11 +29,11 @@ class SettingPage extends StatelessWidget {
Obx(() {
return Expanded(
child: ListView.separated(
itemCount: BleService.to.scanResults.length,
itemCount: state.scanResults.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(BleService.to.scanResults[index].device.remoteId.toString()),
subtitle: Text(BleService.to.scanResults[index].device.platformName),
title: Text(state.scanResults[index]),
// subtitle: Text(state.scanResults[index]),
onTap: ()=>{
logic.connectBle(context,index),
},
......@@ -64,7 +64,7 @@ class SettingPage extends StatelessWidget {
},
child: Obx(() {
return Text(
BleService.to.isScanning.value ? '停止' : '刷新',
state.isScanning.value ? '停止' : '刷新',
style: TextStyle(
fontSize: 20,
),
......@@ -82,7 +82,7 @@ class SettingPage extends StatelessWidget {
// ),
TextButton(
onPressed: () => {
BleService.to.scanResults.clear(),
state.scanResults.clear(),
},
child: const Text(
'清空',
......
......@@ -157,7 +157,7 @@ class SyncLogic extends GetxController {
if (entityList.isNotEmpty) {
HttpUtils<void>()
..post()
..setUrl(APIS.upload_Cattle_List)
..setUrl(APIS.upload_cattle_List)
..showLoading()
..setmListParam(entityList)
..onResponse((response) async {
......
......@@ -2,6 +2,8 @@ import 'dart:async';
import 'dart:isolate';
import 'dart:ui';
import 'package:anchor_collect_flutter/congifs.dart';
import 'package:anchor_collect_flutter/utils/dialog_utils.dart';
import 'package:anchor_collect_flutter/utils/empty_utils.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
......@@ -11,16 +13,51 @@ import '../controllers/ble_service.dart';
typedef void EventCallback(args, args2);
// 这个SendPort是前面主线程的
createNewIsolateContext(SendPort sendPort) async {
print("子线程开始");
/// 子线程的ReceivePort创建
ReceivePort subThreadPort = ReceivePort();
/// 这是把子线程的ReceivePort的sendPort给了主线程 用于通信
sendPort.send(subThreadPort.sendPort);
subThreadPort.listen((message) async {
print("子线程收到的消息 $message");
if (message is String) {
/// 收到主线程让关闭接口的消息 就关闭 正确的话后面是在接受不到消息了
if (message == "close receiveport") {
sendPort.send('closed');
subThreadPort.close();
}
} else if (message is List<int>) {
print('message is List<int>');
await BleService.to.writeData(message);
}
});
///
//第4步: 注意callback这个函数执行环境就会变为newIsolate, 所以创建的是一个newIsolateReceivePort
// ReceivePort newIsolateReceivePort = ReceivePort();
// //第5步: 获取newIsolateSendPort, 有人可能疑问这里为啥不是直接让全局newIsolateSendPort赋值,注意这里执行环境不是rootIsolate
// SendPort newIsolateSendPort = newIsolateReceivePort.sendPort;
// //第6步: 特别需要注意这里,这里是利用rootIsolateSendPort向rootIsolate发送消息,只不过发送消息是newIsolate的SendPort, 这样rootIsolate就能拿到newIsolate的SendPort
// rootIsolateSendPort.send(['connect success from new isolate', newIsolateSendPort]);
}
class RfidPlugin {
static const MethodChannel _methodChannel = MethodChannel('flutter_rfid_plugin');
static const EventChannel _eventChannel = EventChannel('flutter_rfid_plugin/event');
static EventCallback? _callback;
static EventCallback? scanCallback, connectCallback, inventoryCallback;
late StreamSubscription<dynamic> _streamSubscription;
static String rfidTagTemp = '';
static bool isInventory = false;
late Isolate _isolat;
late ReceivePort rootIsolateReceivePort;
......@@ -32,23 +69,64 @@ class RfidPlugin {
late SendPort rootIsolateSendPort;
RfidPlugin() {
establishConn();
// establishConn();
_streamSubscription = _eventChannel.receiveBroadcastStream().listen((event) async {
final Map<dynamic, dynamic> map = event;
switch (map['key']) {
case 'BluetoothData':
if (map['value'] != null) {
List<int> bluetoothData = map['value'];
if (kDebugMode) {
print('Received Byte List: $bluetoothData');
if (kDebugMode) {
print('event:${event.toString()}');
}
if (event is String) {
} else if (event is Map<dynamic, dynamic>) {
final Map<dynamic, dynamic> map = event;
switch (map['key']) {
case 'DISCONNECTED':
Config.isConnect = false;
DialogUtils.showToast('蓝牙已断开');
break;
case 'Device':
///返回扫描的设备名
if (map['value'] != null) {
String bluetoothName = map['value'];
if (kDebugMode) {
print('Received Device name: $bluetoothName');
}
if (scanCallback != null) {
scanCallback!(bluetoothName, '');
} else {
DialogUtils.showToast('缺少扫描设备回调');
}
// rootIsolateSendPort.send(bluetoothData);
// await BleService.to.writeData(bluetoothData);
}
break;
case 'InventoryData':
print('why:InventoryData:${map['value']}');
if (inventoryCallback != null) {
print('why:inventoryCallback');
inventoryCallback!(map['value'], '');
} else {
DialogUtils.showToast('缺少盘点回调');
}
break;
case 'get_version':
if (map['get_version_status'] == '0') {
// map['value_RM70XX_VERSION'];
// map['value_RM70XX_SERIAL_VERSION'];
// map['value_VERSION'];
if(map['value_SERIAL_VERSION']=='-2'){
Config.isConnect = false;
DialogUtils.showToast('蓝牙连接失败');
}else{
if(connectCallback!=null) {
connectCallback!('','');
}
}
} else {
DialogUtils.showWarningDialog('连接蓝牙失败');
}
rootIsolateSendPort.send(bluetoothData);
// await BleService.to.writeData(bluetoothData);
}
break;
case 'InventoryData':
checkInventory(map['value'].toString());
break;
break;
}
}
}, onError: errorEventListen, onDone: doneEventListen);
}
......@@ -83,40 +161,6 @@ class RfidPlugin {
// newIsolateSendPort = messageList[1] as SendPort;
}
// 这个SendPort是前面主线程的
createNewIsolateContext(SendPort sendPort) async {
print("子线程开始");
/// 子线程的ReceivePort创建
ReceivePort subThreadPort = ReceivePort();
/// 这是把子线程的ReceivePort的sendPort给了主线程 用于通信
sendPort.send(subThreadPort.sendPort);
subThreadPort.listen((message) async {
print("子线程收到的消息 $message");
if (message is String) {
/// 收到主线程让关闭接口的消息 就关闭 正确的话后面是在接受不到消息了
if (message == "close receiveport") {
sendPort.send('closed');
subThreadPort.close();
}
}else if(message is List<int>){
print('message is List<int>');
await BleService.to.writeData(message);
}
});
///
//第4步: 注意callback这个函数执行环境就会变为newIsolate, 所以创建的是一个newIsolateReceivePort
// ReceivePort newIsolateReceivePort = ReceivePort();
// //第5步: 获取newIsolateSendPort, 有人可能疑问这里为啥不是直接让全局newIsolateSendPort赋值,注意这里执行环境不是rootIsolate
// SendPort newIsolateSendPort = newIsolateReceivePort.sendPort;
// //第6步: 特别需要注意这里,这里是利用rootIsolateSendPort向rootIsolate发送消息,只不过发送消息是newIsolate的SendPort, 这样rootIsolate就能拿到newIsolate的SendPort
// rootIsolateSendPort.send(['connect success from new isolate', newIsolateSendPort]);
}
static Future<void> initRfid() async {
await _methodChannel.invokeMethod('init_rfid');
}
......@@ -126,13 +170,35 @@ class RfidPlugin {
return version;
}
static Future<void> startInventory(EventCallback callback) async {
_callback = callback;
rfidTagTemp = '';
static startScanDevice(EventCallback callback) async {
scanCallback = callback;
await _methodChannel.invokeMethod('scan_device');
}
static stopScanDevice() async {
await _methodChannel.invokeMethod('scan_stop');
}
static connectDevice(String deviceName, EventCallback callback) async {
connectCallback = callback;
Map params = {
"name": deviceName,
};
await _methodChannel.invokeMethod('connect_device', params);
}
static disConnectDevice() async {
await _methodChannel.invokeMethod('disconnect_device');
}
static startInventory(EventCallback callback) async {
print('why:开始盘点');
inventoryCallback = callback;
isInventory = true;
await _methodChannel.invokeMethod('start_inventory');
}
static Future<void> stopInventory() async {
static stopInventory() async {
await _methodChannel.invokeMethod('stop_inventory');
}
......@@ -162,7 +228,7 @@ class RfidPlugin {
if (!EmptyUtils.isStrNotEmpty(rfidTagTemp)) {
rfidTagTemp = rfidTag;
List<String> rfids = rfidTag.split(',');
_callback!(rfids[0] ?? "", rfids[1] ?? "");
inventoryCallback!(rfids[0] ?? "", rfids[1] ?? "");
}
}
}
......@@ -4,6 +4,7 @@ import 'package:anchor_collect_flutter/pages/message/message_binding.dart';
import 'package:anchor_collect_flutter/pages/message/message_view.dart';
import 'package:anchor_collect_flutter/pages/mine/mine_binding.dart';
import 'package:anchor_collect_flutter/pages/mine/mine_view.dart';
import 'package:anchor_collect_flutter/pages/performance/performance_list/performance_list_view.dart';
import 'package:anchor_collect_flutter/pages/setting/setting_binding.dart';
import 'package:anchor_collect_flutter/pages/setting/setting_view.dart';
import 'package:anchor_collect_flutter/pages/sync/sync_binding.dart';
......@@ -23,6 +24,9 @@ import '../pages/message/message_detail/message_detail_binding.dart';
import '../pages/message/message_detail/message_detail_view.dart';
import '../pages/message/message_list/message_list_binding.dart';
import '../pages/message/message_list/message_list_view.dart';
import '../pages/performance/performance_binding.dart';
import '../pages/performance/performance_list/performance_list_binding.dart';
import '../pages/performance/performance_view.dart';
import 'routes.dart';
abstract class AppPages {
......@@ -77,6 +81,16 @@ abstract class AppPages {
page: () => CattleResumePage(),
binding: CattleResumeBinding(),
),
GetPage(
name: AppRoute.PERFORMANCE_LIST,
page: () => PerformanceListPage(),
binding: PerformanceListBinding(),
),
GetPage(
name: AppRoute.PERFORMANCE,
page: () => PerformancePage(),
binding: PerformanceBinding(),
),
GetPage(
name: AppRoute.CAMERA,
page: () => CameraPage(),
......
......@@ -29,6 +29,12 @@ abstract class AppRoute {
/// 基础信息
static const CATTLE_RESUME = '/cattle/resume';
/// 性能测定列表
static const PERFORMANCE_LIST = '/performance/list';
/// 性能测定
static const PERFORMANCE = '/performance';
/// 照相机
static const CAMERA = '/camera';
......
......@@ -93,6 +93,7 @@ class DialogUtils {
String buttonOk = '确定',
String buttonCancel = '取消',
int maxLength = 50,
bool isNum = false,
bool backDismiss = true,
bool clickMaskDismiss = false,
void Function(String)? onPositive,
......@@ -133,7 +134,8 @@ class DialogUtils {
constraints: const BoxConstraints(maxHeight: 500),
child: TextField(
controller: textEditingController,
maxLength: maxLength,
maxLength: isNum ? 9 : maxLength,
keyboardType: isNum ? TextInputType.number : TextInputType.text,
decoration: InputDecoration(
border: const OutlineInputBorder(),
hintText: hintText,
......@@ -393,13 +395,13 @@ class DialogUtils {
firstDate: DateTime(2020, 5, 1), //最小可以选日期
lastDate: DateTime(2030, 5, 1), //最大可选日期
);
if(selectDayTime!=null) {
if (selectDayTime != null) {
final dateFormatter = DateFormat('yyyy-MM-dd');
final dateString = dateFormatter.format(selectDayTime);
if (kDebugMode) {
print('why:select_day_time$dateString');
}
onPositive?.call(dateString);
if (kDebugMode) {
print('why:select_day_time$dateString');
}
onPositive?.call(dateString);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment