init
This commit is contained in:
commit
295b4058be
243 files changed
+19832
No files matched your search
@@ -0,0 +1,59 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
abstract class SyncConfigTool {
|
||||
static const _tag = "sync配置工具";
|
||||
|
||||
// 自动同步设备信息导本地缓存
|
||||
static Future<void> autoSyncSysInfo() async {
|
||||
final login = await AppUserTool.isLogin();
|
||||
if (!login) return;
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
logger.i("|$_tag|开始同步设备信息 sysInfo:|${json.encode(sysSetting)}|");
|
||||
if (ObjectUtil.isEmpty(sysSetting)) return;
|
||||
if (ObjectUtil.isEmpty(sysSetting.serviceId)) return;
|
||||
final serviceId = sysSetting.serviceId;
|
||||
final pa = {"id": serviceId};
|
||||
final res = await HardApi.get(pa);
|
||||
if (res.code != 0) {
|
||||
logger.e("|$_tag|同步设备信息错误serviceId:|$serviceId|;res:$res;");
|
||||
return;
|
||||
}
|
||||
final data = res.data as ServiceHardware;
|
||||
// 基本信息
|
||||
await AppSettingTool.updateSysInfoByService(data);
|
||||
// 人脸sdk
|
||||
await autoSyncFaceSdk(detail: data, sysInfo: sysSetting);
|
||||
logger.i("|$_tag|结束同步设备信息 sysInfo:|${json.encode(sysSetting)}|");
|
||||
}
|
||||
|
||||
// 自动同步设备信息导本地缓存-同步人脸sdk
|
||||
static Future<void> autoSyncFaceSdk({
|
||||
required ServiceHardware detail,
|
||||
required SysSetting sysInfo,
|
||||
}) async {
|
||||
final appId = detail.faceAppId;
|
||||
final sdkKey = detail.faceSdkKey;
|
||||
final activeKey = detail.faceActiveKey;
|
||||
bool isUpdate = false;
|
||||
if (appId != sysInfo.faceAppId) {
|
||||
sysInfo.faceAppId = appId;
|
||||
isUpdate = true;
|
||||
}
|
||||
if (sdkKey != sysInfo.faceSdkKey) {
|
||||
sysInfo.faceSdkKey = sdkKey;
|
||||
isUpdate = true;
|
||||
}
|
||||
if (activeKey != sysInfo.faceActiveKey) {
|
||||
sysInfo.faceActiveKey = activeKey;
|
||||
isUpdate = true;
|
||||
}
|
||||
if (!isUpdate) return;
|
||||
final activeSdk = await AppFaceTool.isActiveSdk();
|
||||
await AppSettingTool.setSysSetting(sysInfo);
|
||||
logger.i("|$_tag||同步人脸sdk参数自动激活${activeSdk ? '成功' : '失败'}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
class SyncFaceTool {
|
||||
static const _tag = "sync人脸工具";
|
||||
|
||||
static Future<bool> syncGroupFace({
|
||||
required int pageNo,
|
||||
required String merchantDeptId,
|
||||
required String storagePath,
|
||||
String? userId,
|
||||
bool? isGlobalFace,
|
||||
}) async {
|
||||
final app = Get.find<AppControl>();
|
||||
final faceDao = app.dataBase.getFaceDao;
|
||||
const size = 20;
|
||||
var pa = {
|
||||
"current": pageNo,
|
||||
"size": size,
|
||||
"userId": userId,
|
||||
"merchantDeptId": merchantDeptId,
|
||||
};
|
||||
if (isGlobalFace != null && isGlobalFace) pa["merchantDeptId"] = null;
|
||||
logger.i("|$_tag|同步人脸api参数:|$pa|");
|
||||
try {
|
||||
final res = await UserApi.getFaceList(pa);
|
||||
if (res.code != 0 || res.data == null) throw Error();
|
||||
final data = res.data as List<ServiceAsyncFace>;
|
||||
if (ObjectUtil.isEmptyList(data)) {
|
||||
if (ObjectUtil.isEmpty(userId)) return false;
|
||||
// 删除人脸图片
|
||||
final faceList = await faceDao.findByUserId(userId!);
|
||||
if (!ObjectUtil.isEmptyList(faceList)) {
|
||||
for (final v in faceList!) {
|
||||
if (ObjectUtil.isNotEmpty(v.path)) {
|
||||
await delFaceByStorage(filePath: v.path!);
|
||||
await AppFaceTool.removeFace(sampleId: v.sampleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 删除数据库
|
||||
await faceDao.delByUserId(userId);
|
||||
return false;
|
||||
}
|
||||
if (isGlobalFace != null && !isGlobalFace) return false;
|
||||
if (userId != null) {
|
||||
final dbUserList = await faceDao.findByUserId(userId);
|
||||
if (!ObjectUtil.isEmptyList(dbUserList)) {
|
||||
for (final v in dbUserList!) {
|
||||
final target = data.firstWhereOrNull((i) => i.id == v.sampleId);
|
||||
if (target == null) {
|
||||
if (ObjectUtil.isNotEmpty(v.path)) {
|
||||
await delFaceByStorage(filePath: v.path!);
|
||||
await AppFaceTool.removeFace(sampleId: v.sampleId);
|
||||
}
|
||||
await faceDao.delById(v.id!);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final v in data) {
|
||||
final faceEntity = await faceDao.findBySampleId(v.autoCode!);
|
||||
if (faceEntity == null) {
|
||||
final add = FaceEntity(
|
||||
userId: v.userId!,
|
||||
sampleId: v.autoCode!,
|
||||
userName: v.username ?? "",
|
||||
deptId: v.deptId!,
|
||||
deptName: v.deptName ?? "",
|
||||
imagePath: v.faceImg ?? "",
|
||||
createTime: DateTime.now(),
|
||||
);
|
||||
final addId = await faceDao.save(add);
|
||||
if (addId != null) {
|
||||
String? fileName = generateFaceFileName(
|
||||
userId: add.userId,
|
||||
sampleId: add.sampleId,
|
||||
username: add.userName,
|
||||
facePath: add.imagePath,
|
||||
);
|
||||
final filePath = await writeFaceByStorage(
|
||||
storagePath: storagePath,
|
||||
fileName: fileName,
|
||||
facePath: add.imagePath,
|
||||
);
|
||||
if (ObjectUtil.isNotEmpty(filePath)) {
|
||||
add.id = addId;
|
||||
add.updateTime = DateTime.now();
|
||||
add.path = filePath;
|
||||
await faceDao.edit(add);
|
||||
}
|
||||
// 重新生成人脸模型
|
||||
await AppFaceTool.removeFace(sampleId: add.sampleId);
|
||||
await AppFaceTool.faceRegister(
|
||||
userId: add.userId.toString(),
|
||||
forceRegister: true,
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
final edit = FaceEntity(
|
||||
id: faceEntity.id!,
|
||||
userId: v.userId!,
|
||||
sampleId: v.autoCode!,
|
||||
userName: v.username ?? "",
|
||||
deptId: v.deptId!,
|
||||
deptName: v.deptName ?? "",
|
||||
imagePath: v.faceImg ?? "",
|
||||
createTime: DateTime.now(),
|
||||
);
|
||||
if (edit == faceEntity) {
|
||||
continue;
|
||||
}
|
||||
String? fileName = generateFaceFileName(
|
||||
userId: edit.userId,
|
||||
sampleId: edit.sampleId,
|
||||
username: edit.userName,
|
||||
facePath: edit.imagePath,
|
||||
);
|
||||
final filePath = await writeFaceByStorage(
|
||||
storagePath: storagePath,
|
||||
facePath: edit.imagePath,
|
||||
fileName: fileName,
|
||||
);
|
||||
if (ObjectUtil.isNotEmpty(filePath)) {
|
||||
if (ObjectUtil.isNotEmpty(edit.path)) {
|
||||
await delFaceByStorage(filePath: edit.path!);
|
||||
}
|
||||
edit.path = filePath;
|
||||
}
|
||||
await faceDao.edit(edit);
|
||||
// 重新生成人脸模型
|
||||
await AppFaceTool.removeFace(sampleId: edit.sampleId);
|
||||
await AppFaceTool.faceRegister(
|
||||
userId: edit.userId.toString(),
|
||||
forceRegister: true,
|
||||
);
|
||||
}
|
||||
if (data.length >= size) return true;
|
||||
} catch (e, stack) {
|
||||
logger.e("|$_tag|同步人脸意外的错误error:|$e|stack:|$stack|");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 删除人脸图片
|
||||
static Future<void> delFaceByStorage({
|
||||
required String filePath,
|
||||
}) async {
|
||||
try {
|
||||
final file = File(filePath);
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
}
|
||||
} catch (e) {
|
||||
logger.e("|$_tag|删除人脸图片意外的错误error:|$e|");
|
||||
}
|
||||
}
|
||||
|
||||
static String? generateFaceFileName({
|
||||
required String userId,
|
||||
required String sampleId,
|
||||
required String username,
|
||||
required String facePath,
|
||||
}) {
|
||||
if (ObjectUtil.isEmpty(facePath)) return null;
|
||||
return "${userId}_${sampleId}_$username$facePath";
|
||||
}
|
||||
|
||||
/// 写入人脸头像到本地磁盘
|
||||
static Future<String?> writeFaceByStorage({
|
||||
required String storagePath,
|
||||
required String? fileName,
|
||||
required String facePath,
|
||||
}) async {
|
||||
if (ObjectUtil.isEmpty(fileName)) return null;
|
||||
final storageDirectory = Directory(storagePath);
|
||||
final file = File('${storageDirectory.path}/$fileName');
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
}
|
||||
final bytesImg = await AppNetworkTool.downloadImage(facePath);
|
||||
if (bytesImg == null) return null;
|
||||
final writeFile = await file.writeAsBytes(bytesImg);
|
||||
if (await writeFile.exists()) {
|
||||
return file.path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
abstract class SyncOrderTool {
|
||||
static const _tag = "sync订单工具";
|
||||
|
||||
// 同步离线订单
|
||||
static Future<void> syncOfflineOrder() async {
|
||||
final app = Get.find<AppControl>();
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
final sysType = sysSetting.sysType.name;
|
||||
|
||||
final orderDao = app.dataBase.getOrderDao;
|
||||
|
||||
// 查询离线订单
|
||||
final startDate = DateTime.now().subtract(const Duration(days: 30));
|
||||
final endDate = DateTime.now().add(const Duration(days: 1));
|
||||
final list = await orderDao.findOffline(
|
||||
sysType,
|
||||
startDate,
|
||||
endDate,
|
||||
);
|
||||
if (ObjectUtil.isEmptyList(list)) {
|
||||
logger.i("|$_tag|错误,没有需要同步的离线订单");
|
||||
return;
|
||||
}
|
||||
final chunkList = chunkArray(list, 5);
|
||||
for (var v in chunkList) {
|
||||
await _syncOfflineGroupOrder(v);
|
||||
}
|
||||
// 更新同步时间
|
||||
sysSetting.offlineOrderSyncTime = DateTime.now();
|
||||
await AppSettingTool.setSysSetting(sysSetting);
|
||||
}
|
||||
|
||||
// 同步一组离线订单
|
||||
static Future<void> _syncOfflineGroupOrder(List<OrderEntity> list) async {
|
||||
final app = Get.find<AppControl>();
|
||||
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
final serviceId = sysSetting.serviceId;
|
||||
final serviceMerchantId = sysSetting.serviceMerchantId;
|
||||
|
||||
final shopCardDao = app.dataBase.getShopCardDao;
|
||||
List<Map<String, dynamic>> uploadList = [];
|
||||
for (final OrderEntity v in list) {
|
||||
Map<String, dynamic> item = v.toJson();
|
||||
if (v.id != null) {
|
||||
final carList = await shopCardDao.findByOrderId(v.id!);
|
||||
if (!ObjectUtil.isEmptyList(carList)) {
|
||||
item["carList"] = carList.map((i) => i.toJson()).toList();
|
||||
}
|
||||
}
|
||||
uploadList.add(item);
|
||||
}
|
||||
final pa = {
|
||||
"list": uploadList,
|
||||
"hardwareId": serviceId,
|
||||
"merchantId": serviceMerchantId!,
|
||||
};
|
||||
logger.i("|$_tag|同步参数:|$pa|");
|
||||
try {
|
||||
final res = await HardApi.syncOfflineOrder(pa);
|
||||
if (res.code != 0 || res.data == null) throw Error();
|
||||
final data = res.data as List<dynamic>;
|
||||
final batchEditCount = await handEditOfflineStatus(data);
|
||||
logger.i("|$_tag|同步成功的数量为:|$batchEditCount|ids为:|$data|");
|
||||
} catch (e) {
|
||||
logger.e("|$_tag|同步一组离线订单意外的错误error:$e");
|
||||
}
|
||||
}
|
||||
|
||||
static Future<int> handEditOfflineStatus(List<dynamic> codes) async {
|
||||
final app = Get.find<AppControl>();
|
||||
final placeholders = List.generate(codes.length, (index) => '?').join(', ');
|
||||
final sql = '''
|
||||
UPDATE order_record SET status = ? WHERE uniqueCode IN ($placeholders)
|
||||
''';
|
||||
final database = app.dataBase.database;
|
||||
return await database.rawUpdate(sql, [OrderStatus.pay.name, ...codes]);
|
||||
}
|
||||
|
||||
// 切割数组
|
||||
static List<List<T>> chunkArray<T>(List<T> array, int chunkSize) {
|
||||
if (chunkSize <= 0) return [];
|
||||
List<List<T>> chunks = [];
|
||||
for (var i = 0; i < array.length; i += chunkSize) {
|
||||
int end = (i + chunkSize < array.length) ? i + chunkSize : array.length;
|
||||
chunks.add(array.sublist(i, end));
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
abstract class SyncPrintTool {
|
||||
static const _tag = "sync打印工具";
|
||||
|
||||
static bool _isPrint = false;
|
||||
|
||||
static Future<void> addTask({
|
||||
required String orderId,
|
||||
required String androidOrderId,
|
||||
required String historyId,
|
||||
required String pic,
|
||||
}) async {
|
||||
final app = Get.find<AppControl>();
|
||||
final printHistoryDao = app.dataBase.getPrintHistoryDao;
|
||||
final saveObj = PrintHistoryEntity(
|
||||
orderId: androidOrderId,
|
||||
serviceOrderId: orderId,
|
||||
servicePrintId: historyId,
|
||||
invoiceUrl: pic,
|
||||
status: PrintStatus.none,
|
||||
createTime: DateTime.now(),
|
||||
);
|
||||
await printHistoryDao.save(saveObj);
|
||||
logger.i("|$_tag|添加到打印记录到本地数据库,json:|${saveObj.toJson()}|");
|
||||
await SyncPrintTool.doCheckPrint();
|
||||
}
|
||||
|
||||
// 检查打印
|
||||
static Future<void> doCheckPrint() async {
|
||||
if (_isPrint) {
|
||||
logger.i("|$_tag|检查打印,正在打印中");
|
||||
return;
|
||||
}
|
||||
final app = Get.find<AppControl>();
|
||||
final printHistoryDao = app.dataBase.getPrintHistoryDao;
|
||||
final printFacility = app.printManage;
|
||||
try {
|
||||
// 检查有没有需要打印的
|
||||
final list = await printHistoryDao.getAll(PrintStatus.none.name);
|
||||
if (ObjectUtil.isEmptyList(list)) {
|
||||
_isPrint = false;
|
||||
logger.i("|$_tag|检查打印,没有需要打印的发票");
|
||||
return;
|
||||
}
|
||||
final isOpen = await printFacility.open();
|
||||
if (!isOpen) {
|
||||
_isPrint = false;
|
||||
logger.e("|$_tag|检查打印,打开打印机失败");
|
||||
return;
|
||||
}
|
||||
for (final v in list) {
|
||||
await doPrint(v);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.e("|$_tag|检查打印,打印错误,error:|$e|");
|
||||
} finally {
|
||||
_isPrint = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行打印
|
||||
static Future<void> doPrint(PrintHistoryEntity v) async {
|
||||
final app = Get.find<AppControl>();
|
||||
final printHistoryDao = app.dataBase.getPrintHistoryDao;
|
||||
final printFacility = app.printManage;
|
||||
try {
|
||||
final isPrint = await printFacility.printImg(v.invoiceUrl);
|
||||
if (!isPrint) {
|
||||
v.status = PrintStatus.error;
|
||||
await printHistoryDao.edit(v);
|
||||
throw Error();
|
||||
}
|
||||
// 更新本地数据库
|
||||
v.status = PrintStatus.success;
|
||||
v.printTime = DateUtil.formatDate(DateTime.now());
|
||||
await printHistoryDao.edit(v);
|
||||
// 同步到服务端
|
||||
final printPa = {
|
||||
"orderId": v.serviceOrderId,
|
||||
"historyId": v.servicePrintId,
|
||||
};
|
||||
await HardApi.printInvoice(printPa);
|
||||
v.status = PrintStatus.sync;
|
||||
v.syncTime = DateTime.now();
|
||||
await printHistoryDao.edit(v);
|
||||
} catch (e) {
|
||||
logger.i("|$_tag|执行打印,打印错误,error:|$e|");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
abstract class SyncProductTool {
|
||||
static const _tag = "sync商品工具";
|
||||
|
||||
static Future<void> updateDatabase() async {
|
||||
final isNetwork = AppNetworkTool.isAutoNetwork();
|
||||
if (!isNetwork) return;
|
||||
EasyLoading.show(
|
||||
status: '初始化资源...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
await syncClassify();
|
||||
await syncProduct();
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
|
||||
/// 同步商品分类
|
||||
static Future<void> syncClassify() async {
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
final sysType = sysSetting.sysType;
|
||||
try {
|
||||
List<ServiceClassify>? apiList;
|
||||
if (sysType == SysType.canteen) {
|
||||
apiList = await ProductApi.cookbookClassify(null);
|
||||
} else if (sysType == SysType.supermarket) {
|
||||
apiList = await ProductApi.supermarketClassify(null);
|
||||
}
|
||||
if (apiList == null) return;
|
||||
if (ObjectUtil.isEmptyList(apiList)) {
|
||||
return;
|
||||
}
|
||||
await _batchUpdateClassify(list: apiList, sysType: sysSetting.sysType);
|
||||
// 更新同步时间
|
||||
if (sysType == SysType.canteen) {
|
||||
sysSetting.canteenClassifySyncTime = DateTime.now();
|
||||
}
|
||||
if (sysType == SysType.supermarket) {
|
||||
sysSetting.supermarketClassifySyncTime = DateTime.now();
|
||||
}
|
||||
await AppSettingTool.setSysSetting(sysSetting);
|
||||
} catch (e, stack) {
|
||||
logger.e("|$_tag|同步|${sysType.title}|分类信息意外的错误error:|$e|,stack:|$stack|");
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _batchUpdateClassify({
|
||||
required List<ServiceClassify> list,
|
||||
required SysType sysType,
|
||||
}) async {
|
||||
final app = Get.find<AppControl>();
|
||||
final dataBase = app.dataBase;
|
||||
final classifyDao = dataBase.getClassifyDao;
|
||||
final classifyList = await classifyDao.getAll(sysType.name, "-1");
|
||||
if (ObjectUtil.isEmpty(classifyList)) {
|
||||
await _batchAddOrUpdateClassify(
|
||||
list: list,
|
||||
sysType: sysType,
|
||||
isUpdate: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
final apiServiceCodes = list.map((e) => e.id.toString()).toSet();
|
||||
final dbServiceCodes = classifyList.map((e) => e.serviceUniqueCode).toSet();
|
||||
|
||||
final addCodes = apiServiceCodes.difference(dbServiceCodes).toList();
|
||||
final deleteCodes = dbServiceCodes.difference(apiServiceCodes).toList();
|
||||
final updateCodes = apiServiceCodes.intersection(dbServiceCodes).toList();
|
||||
|
||||
if (ObjectUtil.isNotEmpty(addCodes)) {
|
||||
await _batchAddOrUpdateClassify(
|
||||
list: _filterClassifyListByCodes(list, addCodes),
|
||||
sysType: sysType,
|
||||
isUpdate: false,
|
||||
);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(deleteCodes)) {
|
||||
await classifyDao.delByIds(deleteCodes);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(updateCodes)) {
|
||||
await _batchAddOrUpdateClassify(
|
||||
list: _filterClassifyListByCodes(list, updateCodes),
|
||||
sysType: sysType,
|
||||
isUpdate: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _batchAddOrUpdateClassify({
|
||||
required List<ServiceClassify> list,
|
||||
required SysType sysType,
|
||||
required bool isUpdate,
|
||||
}) async {
|
||||
if (ObjectUtil.isEmpty(list)) return;
|
||||
final app = Get.find<AppControl>();
|
||||
final dataBase = app.dataBase;
|
||||
final classifyDao = dataBase.getClassifyDao;
|
||||
List<ClassifyEntity> changeList = [];
|
||||
for (final v in list) {
|
||||
ClassifyEntity item = ClassifyEntity(
|
||||
serviceUniqueCode: v.id.toString(),
|
||||
sysType: sysType,
|
||||
name: v.name!,
|
||||
categoryType: v.categoryType ?? "-1",
|
||||
sort: v.sort ?? 999,
|
||||
createTime: DateTime.now(),
|
||||
updateTime: DateTime.now(),
|
||||
delFlag: false,
|
||||
);
|
||||
if (isUpdate) {
|
||||
final detail = await classifyDao.getByCode(item.serviceUniqueCode);
|
||||
if (ObjectUtil.isEmpty(detail)) continue;
|
||||
if (detail == item) continue;
|
||||
item.id = detail?.id;
|
||||
}
|
||||
changeList.add(item);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(changeList)) {
|
||||
isUpdate
|
||||
? await classifyDao.batchEdit(changeList)
|
||||
: await classifyDao.batchSave(changeList);
|
||||
}
|
||||
}
|
||||
|
||||
static List<ServiceClassify> _filterClassifyListByCodes(
|
||||
List<ServiceClassify> sourceList,
|
||||
List<String> addCodes,
|
||||
) {
|
||||
return sourceList
|
||||
.where((item) => addCodes.contains(item.id.toString()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// 同步商品
|
||||
static Future<void> syncProduct() async {
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
final sysType = sysSetting.sysType;
|
||||
try {
|
||||
List<ServiceProduct>? apiList;
|
||||
if (sysType == SysType.canteen) {
|
||||
final day = DateUtil.formatDate(
|
||||
DateTime.now(),
|
||||
format: DateFormats.y_mo_d,
|
||||
);
|
||||
final pa = {
|
||||
"day": day,
|
||||
"hourType": null,
|
||||
"categoryId": null,
|
||||
"merchantId": sysSetting.serviceMerchantId,
|
||||
};
|
||||
apiList = await ProductApi.canteenProduct(pa);
|
||||
} else if (sysType == SysType.supermarket) {
|
||||
apiList = await ProductApi.supermarketProduct(null);
|
||||
}
|
||||
if (apiList == null) return;
|
||||
if (ObjectUtil.isEmptyList(apiList)) {
|
||||
return;
|
||||
}
|
||||
// 更新数据
|
||||
await _batchUpdateProduct(list: apiList, sysType: sysSetting.sysType);
|
||||
// 更新同步时间
|
||||
if (sysType == SysType.canteen) {
|
||||
sysSetting.canteenProductSyncTime = DateTime.now();
|
||||
}
|
||||
if (sysType == SysType.supermarket) {
|
||||
sysSetting.supermarketProductSyncTime = DateTime.now();
|
||||
}
|
||||
await AppSettingTool.setSysSetting(sysSetting);
|
||||
} catch (e, stack) {
|
||||
logger.e("|$_tag|同步|${sysType.title}|商品信息意外的错误error:|$e|,stack:|$stack|");
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _batchUpdateProduct({
|
||||
required List<ServiceProduct> list,
|
||||
required SysType sysType,
|
||||
}) async {
|
||||
final app = Get.find<AppControl>();
|
||||
final dataBase = app.dataBase;
|
||||
final productDao = dataBase.getProductDao;
|
||||
final productList = await productDao.getAll(
|
||||
"-1",
|
||||
"-1",
|
||||
"-1",
|
||||
);
|
||||
if (ObjectUtil.isEmpty(productList)) {
|
||||
await _batchAddOrUpdateProduct(
|
||||
list: list,
|
||||
sysType: sysType,
|
||||
isUpdate: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
final apiServiceCodes = list.map((e) => e.spuId.toString()).toSet();
|
||||
final dbServiceCodes = productList.map((e) => e.serviceUniqueCode).toSet();
|
||||
|
||||
final addCodes = apiServiceCodes.difference(dbServiceCodes).toList();
|
||||
final deleteCodes = dbServiceCodes.difference(apiServiceCodes).toList();
|
||||
final updateCodes = apiServiceCodes.intersection(dbServiceCodes).toList();
|
||||
if (ObjectUtil.isNotEmpty(addCodes)) {
|
||||
await _batchAddOrUpdateProduct(
|
||||
list: _filterProductListByCodes(list, addCodes),
|
||||
sysType: sysType,
|
||||
isUpdate: false,
|
||||
);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(deleteCodes)) {
|
||||
await productDao.delByIds(deleteCodes);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(updateCodes)) {
|
||||
await _batchAddOrUpdateProduct(
|
||||
list: _filterProductListByCodes(list, updateCodes),
|
||||
sysType: sysType,
|
||||
isUpdate: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _batchAddOrUpdateProduct({
|
||||
required List<ServiceProduct> list,
|
||||
required SysType sysType,
|
||||
required bool isUpdate,
|
||||
}) async {
|
||||
if (ObjectUtil.isEmpty(list)) return;
|
||||
final app = Get.find<AppControl>();
|
||||
final dataBase = app.dataBase;
|
||||
final productDao = dataBase.getProductDao;
|
||||
List<ProductEntity> changeList = [];
|
||||
for (final v in list) {
|
||||
ProductEntity item = ProductEntity(
|
||||
serviceUniqueCode: sysType == SysType.canteen
|
||||
? v.spuId.toString()
|
||||
: v.spuId.toString(),
|
||||
sysType: sysType,
|
||||
classifyServiceUniqueCode:
|
||||
v.categoryId != null ? v.categoryId.toString() : "-1",
|
||||
name: v.name!,
|
||||
price: v.price ?? 0,
|
||||
image: v.picUrl,
|
||||
status: 1,
|
||||
sort: v.sort ?? 999,
|
||||
createTime: DateTime.now(),
|
||||
updateTime: DateTime.now(),
|
||||
hourType: ProductHourType.values.fromCode(v.hourType),
|
||||
isDefault: false,
|
||||
delFlag: false,
|
||||
);
|
||||
if (isUpdate) {
|
||||
final detail = await productDao.getByCode(item.serviceUniqueCode);
|
||||
if (ObjectUtil.isEmpty(detail)) continue;
|
||||
if (detail == item) continue;
|
||||
item.id = detail?.id;
|
||||
}
|
||||
changeList.add(item);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(changeList)) {
|
||||
isUpdate
|
||||
? await productDao.batchEdit(changeList)
|
||||
: await productDao.batchSave(changeList);
|
||||
}
|
||||
}
|
||||
|
||||
static List<ServiceProduct> _filterProductListByCodes(
|
||||
List<ServiceProduct> sourceList,
|
||||
List<String> codes,
|
||||
) {
|
||||
return sourceList
|
||||
.where((item) => codes.contains(item.spuId.toString()))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
abstract class SyncUserTool {
|
||||
static const _tag = "sync商品工具";
|
||||
|
||||
// 获取存储用户
|
||||
static Future<UserEntity?> storageUserByCarNumber(String cardNumber) async {
|
||||
final app = Get.find<AppControl>();
|
||||
final userDao = app.dataBase.getUserDao;
|
||||
return await userDao.findByCardNumber(cardNumber);
|
||||
}
|
||||
|
||||
// 获取存储用户
|
||||
static Future<UserEntity?> storageUserByUserId(String userId) async {
|
||||
final app = Get.find<AppControl>();
|
||||
final userDao = app.dataBase.getUserDao;
|
||||
return await userDao.findByUserId(userId);
|
||||
}
|
||||
|
||||
/// 存储用户
|
||||
static Future<void> storageUser({required ServiceUser user}) async {
|
||||
try {
|
||||
final app = Get.find<AppControl>();
|
||||
final userDao = app.dataBase.getUserDao;
|
||||
final detail = await userDao.findByUserId(user.userId!);
|
||||
if (detail == null) {
|
||||
final obj = _parseStorageUser(user: user, createDate: true);
|
||||
await userDao.save(obj);
|
||||
logger.i("|$_tag|,存储用户,新增成功|${obj.toJson()}|");
|
||||
} else {
|
||||
final obj = _parseStorageUser(user: user, updateDate: true);
|
||||
obj.id = detail.id;
|
||||
await userDao.edit(obj);
|
||||
logger.i("|$_tag|,存储用户,修改成功|${obj.toJson()}|");
|
||||
}
|
||||
} catch (e, stack) {
|
||||
logger.e("|$_tag|,存储用户失败意外的错误error:|$e|stack:|$stack|");
|
||||
}
|
||||
}
|
||||
|
||||
static ServiceUser parsePayUser({
|
||||
required UserEntity user,
|
||||
}) {
|
||||
return ServiceUser(
|
||||
userId: user.userId,
|
||||
username: user.nickname,
|
||||
deptId: null,
|
||||
userMobile: user.mobile,
|
||||
userAvatar: user.avatar,
|
||||
walletId: user.walletId,
|
||||
walletTypeId: user.walletTypeId,
|
||||
walletBalance: user.walletBalance,
|
||||
walletIsFreeze: false,
|
||||
walletCardNumber: user.walletCardNumber,
|
||||
);
|
||||
}
|
||||
|
||||
static UserEntity _parseStorageUser({
|
||||
required ServiceUser user,
|
||||
bool createDate = false,
|
||||
bool updateDate = false,
|
||||
}) {
|
||||
final userEntity = UserEntity(
|
||||
userId: user.userId ?? "-1",
|
||||
nickname: user.username ?? "未知",
|
||||
mobile: user.userMobile,
|
||||
avatar: user.userAvatar,
|
||||
walletCardNumber: user.walletCardNumber,
|
||||
walletId: user.walletId,
|
||||
walletTypeId: user.walletTypeId,
|
||||
walletBalance: user.walletBalance,
|
||||
);
|
||||
if (createDate) {
|
||||
userEntity.createTime = DateTime.now();
|
||||
}
|
||||
if (updateDate) {
|
||||
userEntity.updateTime = DateTime.now();
|
||||
}
|
||||
return userEntity;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user