Files
biz_xfj_cloud/lib/common/api/hard_api.dart
T
2026-09-04 13:15:55 +08:00

438 lines
15 KiB
Dart

import 'dart:io';
import 'package:dio/dio.dart' as dio;
import 'package:pj_supermarket_cloud/common/index.dart';
abstract class HardApi {
/// 按终端订单号或服务端订单 ID 对账识别证据状态;后台任务失败不弹业务 Toast。
static Future<ServiceOrderEvidenceResolve?> resolveOrderEvidence({
required String hardId,
String? androidOrderCode,
String? orderId,
}) async {
final res = await HttpManage().dio.get(
'/hard/hard-order-evidence/ad/resolve',
queryParameters: {
if (androidOrderCode != null) 'androidOrderCode': androidOrderCode,
if (orderId != null) 'orderId': orderId,
},
options: dio.Options(
headers: {'DEVICE-ID': hardId},
extra: {HttpManage.silentRequestKey: true},
),
);
if (res.data == null) return null;
return ServiceOrderEvidenceResolve.fromJson(res.data);
}
/// 提交识别元数据、触发参考图复制或报告本地图片永久缺失。
static Future<ServiceOrderEvidenceUploadResult?> submitOrderEvidence({
required String hardId,
required OrderEvidenceRequest request,
}) async {
final res = await HttpManage().dio.post(
'/hard/hard-order-evidence/ad/submit',
data: request.toJson(),
options: dio.Options(
headers: {'DEVICE-ID': hardId},
extra: {HttpManage.silentRequestKey: true},
),
);
if (res.data == null) return null;
return ServiceOrderEvidenceUploadResult.fromJson(res.data);
}
/// 使用统一 Dio 鉴权和租户头上传现场图片,multipart 文件名不包含终端完整路径。
static Future<ServiceOrderEvidenceUploadResult?> uploadOrderEvidence({
required String hardId,
required OrderEvidenceRequest request,
required String filePath,
}) async {
final file = File(filePath);
final fileName = file.uri.pathSegments.last;
final form = dio.FormData.fromMap({
...request.toJson(),
'file': await dio.MultipartFile.fromFile(filePath, filename: fileName),
});
final res = await HttpManage().dio.post(
'/hard/hard-order-evidence/ad/upload',
data: form,
options: dio.Options(
headers: {'DEVICE-ID': hardId},
contentType: 'multipart/form-data',
extra: {HttpManage.silentRequestKey: true},
),
);
if (res.data == null) return null;
return ServiceOrderEvidenceUploadResult.fromJson(res.data);
}
/// 静默上报食堂、超市 Android 终端最新运行状态;后台失败不得弹出业务 Toast。
static Future<void> terminalHeartbeat({
required String hardId,
required Map<String, dynamic> data,
}) async {
await HttpManage().dio.post(
'/hard/hard-api/ad/terminal-heartbeat',
data: data,
options: dio.Options(
headers: {'DEVICE-ID': hardId},
extra: {HttpManage.silentRequestKey: true},
),
);
}
/// 获取硬件配置信息
static Future<ServiceHardware?> bind(dynamic pa) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/bind",
data: pa,
);
if (res.data == null) return null;
return ServiceHardware.fromJson(res.data);
}
/// 获取硬件配置信息
static Future<ServiceHardware?> get(dynamic pa) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/get",
queryParameters: pa,
);
if (res.data == null) return null;
return ServiceHardware.fromJson(res.data);
}
/// 获取用户信息
static Future<ServiceUser?> getUserInfoById(
dynamic formData,
) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/get-user",
queryParameters: formData,
);
if (res.data == null) return null;
return ServiceUser.fromJson(res.data);
}
/// 获取用户信息
static Future<ServiceUser?> getUserByCard(
dynamic formData,
) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/get-user-by-card",
queryParameters: formData,
);
if (res.data == null) return null;
return ServiceUser.fromJson(res.data);
}
/// 仅按当前终端和识别身份查询本人预约,调用方不得补充商户或其他用户参数。
static Future<ServiceReservationMenuQuery?> queryReservationMenu(
ReservationMenuQueryRequest request,
) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/reservation-menu/query",
data: request.toJson(),
);
if (res.data == null) return null;
return ServiceReservationMenuQuery.fromJson(res.data);
}
/// 只按查询结果中的订单 ID 核销一笔预约订单。
static Future<bool> cancelReservationOrder({
required int orderId,
}) async {
final setting = await AppSettingTool.getSysSetting();
final res = await HttpManage().dio.post(
'/hard/hard-api/ad/reservation-menu/cancel',
data: {'orderId': orderId},
options: dio.Options(
headers: {
if (setting.serviceId != null) 'DEVICE-ID': setting.serviceId,
},
),
);
return res.data == true;
}
/// 分页查询当前设备的预约核销记录,设备范围由服务端再次校验。
static Future<ServiceVerificationRecordPage?> verificationRecordPage({
required int current,
required int size,
required VerificationRecordQueryRequest request,
}) async {
final res = await HttpManage().dio.post(
'/hard/hard-api/ad/verification-record/page',
queryParameters: {'current': current, 'size': size},
data: request.toJson(),
options: dio.Options(headers: {'DEVICE-ID': request.hardId}),
);
if (res.data == null) return null;
return ServiceVerificationRecordPage.fromJson(res.data);
}
/// 创建硬件订单
static Future<String?> createHardwareOrder(dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/create-order",
data: formData,
options: dio.Options(
extra: {HttpManage.rejectBusinessErrorKey: true},
),
);
if (res.data == null) return null;
return res.data;
}
/// 创建硬件订单
static Future<ServiceHardCreateHardQrCodeScanOrder?>
createHardQrCodeScanOrder(dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/create-hard-qr-code-order",
data: formData,
options: dio.Options(
extra: {HttpManage.rejectBusinessErrorKey: true},
),
);
if (res.data == null) return null;
return ServiceHardCreateHardQrCodeScanOrder.fromJson(res.data);
}
/// 创建与 Hardware 业务订单绑定的支付宝、微信聚合订单码。
static Future<ServiceHardAggregateOrderCodePay?> createAggregateOrderCodePay(
dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/create-aggregate-order-code-pay",
data: formData,
options: dio.Options(
extra: {HttpManage.rejectBusinessErrorKey: true},
),
);
if (res.data == null) return null;
return ServiceHardAggregateOrderCodePay.fromJson(res.data);
}
/// 查询聚合支付状态;成功响应表示 Hardware 业务订单已同步完成结算。
static Future<ServiceHardAggregateOrderCodePayStatus?>
getAggregateOrderCodePayStatus({
required String orderId,
required String aggregateNo,
}) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/aggregate-order-code-pay/status",
queryParameters: {
"orderId": orderId,
"aggregateNo": aggregateNo,
},
);
if (res.data == null) return null;
return ServiceHardAggregateOrderCodePayStatus.fromJson(res.data);
}
/// 根据订单id,获取订单详情
static Future<ServiceHardOrder?> getOrder(dynamic formData) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/get-order",
queryParameters: formData,
);
if (res.data == null) return null;
return ServiceHardOrder.fromJson(res.data);
}
/// 获取订单购物车
static Future<List<ServiceCar>?> getCarByOrderId(
dynamic formData,
) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/get-by-order-id",
queryParameters: formData,
);
if (res.data == null) return null;
return res.data?.map<ServiceCar>((e) => ServiceCar.fromJson(e)).toList();
}
/// 核销订单
static Future<bool> cancelQrCode(dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/cancel-code",
data: formData,
);
if (res.data == null) return false;
return true;
}
/// 核销活动订单
static Future<bool> cancelActQrCode(dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/cancel-act-code",
data: formData,
);
if (res.data == null) return false;
return true;
}
/// 生成发票
static Future<ServiceGenerateInvoice?> generateInvoice(
dynamic formData,
) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/generate-invoice",
queryParameters: formData,
);
if (res.data == null) return null;
return ServiceGenerateInvoice.fromJson(res.data);
}
/// 业务终端按 DEVICE-ID 创建打印任务,目标打印机只由服务端绑定关系决定。
static Future<bool> createPrinterTask({
required String orderId,
String printType = '1',
}) async {
final setting = await AppSettingTool.getSysSetting();
final hardId = setting.serviceId;
if (hardId == null || hardId.isEmpty) throw StateError('当前业务终端尚未绑定');
final res = await HttpManage().dio.post(
'/hard/hard-api/ad/printer/task',
data: {
'orderId': int.parse(orderId),
'printType': printType,
},
options: dio.Options(headers: {'DEVICE-ID': hardId}),
);
return res.data != null;
}
/// 打印成功
static Future<bool> printInvoice(dynamic formData) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/print-invoice",
queryParameters: formData,
);
if (res.data == null) return false;
return true;
}
/// 读取当前 EY_PRINT 的服务端绑定和 USB/ESC-POS 参数。
static Future<Map<String, dynamic>> getPrinterBootstrap() async {
final setting = await AppSettingTool.getSysSetting();
final hardId = setting.serviceId;
if (hardId == null || hardId.isEmpty) throw StateError('打印终端尚未绑定设备 ID');
final res = await HttpManage().dio.get(
'/hard/hard-api/ad/printer/bootstrap',
options: dio.Options(headers: {'DEVICE-ID': hardId}),
);
if (res.data is! Map) throw const FormatException('打印终端启动配置格式错误');
return Map<String, dynamic>.from(res.data as Map);
}
/// 拉取当前打印终端未完成任务,补偿 MQTT 离线窗口。
static Future<List<MqttInvoiceMsg>> getPrinterTasks() async {
final setting = await AppSettingTool.getSysSetting();
final hardId = setting.serviceId;
if (hardId == null || hardId.isEmpty) return const <MqttInvoiceMsg>[];
final res = await HttpManage().dio.get(
'/hard/hard-api/ad/printer/tasks',
options: dio.Options(
headers: {'DEVICE-ID': hardId},
extra: {HttpManage.silentRequestKey: true},
),
);
if (res.data is! List) return const <MqttInvoiceMsg>[];
return (res.data as List).whereType<Map>().map((item) {
final json = Map<String, dynamic>.from(item);
json['historyId'] ??= json['id'];
return MqttInvoiceMsg.fromJson(json);
}).toList(growable: false);
}
/// 上报完整 USB 写入结果;请求失败由本地队列保留并在网络恢复后补报。
static Future<bool> reportPrinterResult({
required String taskId,
required String orderId,
required int retryVersion,
required bool success,
required int attemptCount,
String? errorMessage,
}) async {
final setting = await AppSettingTool.getSysSetting();
final hardId = setting.serviceId;
if (hardId == null || hardId.isEmpty) throw StateError('打印终端设备 ID 缺失');
final res = await HttpManage().dio.post(
'/hard/hard-api/ad/printer/result',
data: {
'taskId': int.parse(taskId),
'orderId': int.parse(orderId),
'retryVersion': retryVersion,
'success': success,
'attemptCount': attemptCount,
if (errorMessage != null && errorMessage.isNotEmpty)
'errorMessage': errorMessage,
},
options: dio.Options(
headers: {'DEVICE-ID': hardId},
extra: {HttpManage.silentRequestKey: true},
),
);
return res.data == true;
}
/// 离线同步
static Future<List<String>?> syncOfflineOrder(dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/sync-offline-order",
data: formData,
);
if (res.data == null) return null;
return res.data?.map<String>((e) => e.toString()).toList();
}
/// 统计每天、每周、每月、每年的交易人数和次数
static Future<ServiceChartLatitude?> chartLatitude(
dynamic formData,
) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/chart-latitude",
queryParameters: formData,
);
if (res.data == null) return null;
return ServiceChartLatitude.fromJson(res.data);
}
/// android查询今日的广播
static Future<ServiceBroadcastTodayPage?> broadcastToday(
dynamic formData,
) async {
final res = await HttpManage().dio.get(
"/hard/hard-broadcast/ad/today",
queryParameters: formData,
data: {"hardId": formData["hardId"]},
);
if (res.data == null) return null;
return ServiceBroadcastTodayPage.fromJson(res.data);
}
/// android完成一轮广播
static Future<ServiceBroadcastTodayPage?> broadcast(
dynamic formData,
) async {
final res = await HttpManage()
.dio
.post("/hard/hard-broadcast/ad/broadcast", data: formData);
if (res.data == null) return null;
return ServiceBroadcastTodayPage.fromJson(res.data);
}
/// 消费机限时退款
static Future<bool> timeLimitRefund(
dynamic formData,
) async {
final res = await HttpManage().dio.get(
"/hard/hard-after-sale/ad/time-limit-refund",
queryParameters: formData,
);
if (res.data == null) return false;
return true;
}
}