Files
dzc aa4eb7b86e feat:优化下单速度
feat:处理读卡密码
2026-10-14 13:51:12 +08:00

1453 lines
38 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:json_annotation/json_annotation.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
part 'hard_api_models.g.dart';
/// 终端提交订单识别证据元数据和现场图片时共用的强类型请求。
@JsonSerializable(includeIfNull: false)
class OrderEvidenceRequest {
/// 创建一条与服务端证据位置协议一致的请求。
const OrderEvidenceRequest({
this.androidOrderCode,
this.orderId,
required this.evidenceType,
required this.evidenceRole,
required this.sequenceNo,
required this.userId,
this.faceSampleId,
this.referenceImageUrl,
this.referenceImageVersion,
this.similarity,
this.similarityThreshold,
required this.capturedAt,
this.imageHash,
this.imageSize,
this.imageWidth,
this.imageHeight,
this.status,
this.failureReason,
required this.appVersion,
});
/// 终端稳定订单号,用于服务端按设备对账现场创建的订单;预约核销证据允许为空。
final String? androidOrderCode;
/// 已由当前设备核销的服务端预约订单 ID;现场创建的订单证据允许为空。
final String? orderId;
/// 证据业务类型,使用 `OrderEvidenceType.code`。
final String evidenceType;
/// 图片角色,使用 `OrderEvidenceRole.code`。
final String evidenceRole;
/// 同一订单、类型和角色下从 0 开始的序号。
final int sequenceNo;
/// 识别用户主键,服务端会再次校验与订单用户一致。
final String userId;
/// 虹软样本编号;人脸证据必填,其他类型允许为空。
final String? faceSampleId;
/// 识别时记录的后台参考人脸地址,仅参考图角色提交。
final String? referenceImageUrl;
/// 识别时本地人脸快照对应的后台更新时间,用于识别相同地址上的内容替换。
final DateTime? referenceImageVersion;
/// 人脸比对相似度快照,范围 0 到 1。
final double? similarity;
/// 人脸比对成功阈值快照,范围 0 到 1。
final double? similarityThreshold;
/// 真正比对成功帧的终端采集时间。
final DateTime capturedAt;
/// 图片 SHA-256;现场图片必填,参考图内容未知时允许为空。
final String? imageHash;
/// 图片大小,单位字节。
final int? imageSize;
/// 图片宽度,单位像素。
final int? imageWidth;
/// 图片高度,单位像素。
final int? imageHeight;
/// 元数据提交目标状态,仅允许服务端协议的 PENDING 或 UNAVAILABLE。
final String? status;
/// 永久缺失的单行摘要,不得包含终端完整文件路径。
final String? failureReason;
/// 产生证据的终端应用版本快照。
final String appVersion;
/// 从 JSON 响应或测试夹具恢复请求对象。
factory OrderEvidenceRequest.fromJson(Map<String, dynamic> json) =>
_$OrderEvidenceRequestFromJson(json);
/// 转换为统一 Dio 可提交的 JSON 或 multipart 字段 Map。
Map<String, dynamic> toJson() => _$OrderEvidenceRequestToJson(this);
}
/// 服务端单条订单识别证据状态,用于终端对账和幂等恢复。
@JsonSerializable()
class ServiceOrderEvidenceImage {
/// 创建一条服务端证据状态快照。
const ServiceOrderEvidenceImage({
required this.id,
required this.evidenceType,
this.evidenceTypeName,
required this.evidenceRole,
this.evidenceRoleName,
required this.sequenceNo,
required this.status,
this.statusName,
this.similarity,
this.similarityThreshold,
this.hardId,
this.capturedAt,
this.imageHash,
this.imageUrl,
this.failureReason,
});
/// 服务端证据记录主键。
@JsonKey(fromJson: JsonTool.anyToRequiredString)
final String id;
/// 服务端稳定证据类型编码。
final String evidenceType;
/// 服务端按稳定编码转换的证据类型中文名称。
final String? evidenceTypeName;
/// 服务端稳定图片角色编码。
final String evidenceRole;
/// 服务端按稳定编码转换的图片角色中文名称。
final String? evidenceRoleName;
/// 同一角色下的图片序号。
final int sequenceNo;
/// 服务端证据状态,取 PENDING、AVAILABLE 或 UNAVAILABLE。
final String status;
/// 服务端按稳定编码转换的证据状态中文名称。
final String? statusName;
/// 人脸识别相似度快照,范围为 0 到 1,非人脸凭证允许为空。
@JsonKey(fromJson: JsonTool.anyToNullableDouble)
final double? similarity;
/// 人脸识别采用的阈值快照,范围为 0 到 1。
@JsonKey(fromJson: JsonTool.anyToNullableDouble)
final double? similarityThreshold;
/// 采集该凭证的服务端设备 ID。
@JsonKey(fromJson: JsonTool.anyToString)
final String? hardId;
/// 终端真正完成识别的本地采集时间。
final DateTime? capturedAt;
/// 服务端已登记的图片 SHA-256。
final String? imageHash;
/// PC 可访问的服务端证据图片地址。
final String? imageUrl;
/// 永久缺失或复制失败摘要。
final String? failureReason;
/// 从服务端 JSON 解析证据状态。
factory ServiceOrderEvidenceImage.fromJson(Map<String, dynamic> json) =>
_$ServiceOrderEvidenceImageFromJson(json);
/// 转换为测试或诊断使用的 JSON。
Map<String, dynamic> toJson() => _$ServiceOrderEvidenceImageToJson(this);
}
/// 服务端打印任务的只读快照,用于核销完整详情展示和兑换券重打定位。
@JsonSerializable()
class ServicePrintRecord {
/// 创建一条不写入终端本地数据库的服务端打印任务快照。
const ServicePrintRecord({
required this.id,
required this.orderId,
this.hardId,
this.hardName,
this.printerHardId,
this.printerHardName,
required this.printType,
required this.printNo,
required this.retryVersion,
required this.attemptCount,
required this.status,
this.failureStage,
this.lastError,
this.printedAt,
this.reprintReason,
this.pic,
this.createTime,
});
/// 服务端 hard_invoice 打印任务主键。
@JsonKey(fromJson: JsonTool.anyToRequiredString)
final String id;
/// 打印凭证所属的服务端订单主键。
@JsonKey(fromJson: JsonTool.anyToRequiredString)
final String orderId;
/// 产生该任务的食堂或超市业务终端 ID。
@JsonKey(fromJson: JsonTool.anyToString)
final String? hardId;
/// 产生该任务的食堂或超市业务终端名称。
final String? hardName;
/// 服务端绑定的逻辑打印机资产 ID。
@JsonKey(fromJson: JsonTool.anyToString)
final String? printerHardId;
/// 服务端绑定的逻辑打印机资产名称。
final String? printerHardName;
/// 凭证类型编码,1 为发票,2 为核销兑换券。
@JsonKey(defaultValue: '1')
final String printType;
/// 同一订单和凭证类型下从 1 开始的打印序号。
@JsonKey(defaultValue: 1)
final int printNo;
/// 失败任务的人工重试版本,用于终端过滤过期 MQTT 消息。
@JsonKey(defaultValue: 0)
final int retryVersion;
/// 终端已经执行的 USB 打印尝试次数。
@JsonKey(defaultValue: 0)
final int attemptCount;
/// 服务端打印任务状态编码,取 0 到 4。
@JsonKey(defaultValue: '')
final String status;
/// 最近一次失败阶段的稳定编码,成功和未处理任务允许为空。
final String? failureStage;
/// 最近一次可展示的失败摘要,不包含认证或支付凭证。
final String? lastError;
/// 终端确认完整写入 USB 打印机的服务端记录时间。
final DateTime? printedAt;
/// 人工重新打印时填写的原因,首次打印允许为空。
final String? reprintReason;
/// 后端生成的打印凭证图片地址,生成前或生成失败时允许为空。
final String? pic;
/// 服务端打印任务创建时间。
final DateTime? createTime;
/// 从终端专用在线接口解析打印任务。
factory ServicePrintRecord.fromJson(Map<String, dynamic> json) =>
_$ServicePrintRecordFromJson(json);
/// 转换为测试和诊断使用的 JSON。
Map<String, dynamic> toJson() => _$ServicePrintRecordToJson(this);
}
/// 按终端订单号对账返回的服务端订单和全部证据位置。
@JsonSerializable()
class ServiceOrderEvidenceResolve {
/// 创建一份服务端订单对账结果。
const ServiceOrderEvidenceResolve({
required this.orderId,
required this.orderStatus,
this.evidenceImages = const [],
});
/// 服务端订单主键。
@JsonKey(fromJson: JsonTool.anyToRequiredString)
final String orderId;
/// 服务端订单状态编码,只有已支付、已核销或退款订单允许继续补传。
final String orderStatus;
/// 服务端当前已登记的证据位置及状态。
final List<ServiceOrderEvidenceImage> evidenceImages;
/// 从统一响应中的 data 对象解析订单对账结果。
factory ServiceOrderEvidenceResolve.fromJson(Map<String, dynamic> json) =>
_$ServiceOrderEvidenceResolveFromJson(json);
/// 转换为测试或诊断使用的 JSON。
Map<String, dynamic> toJson() => _$ServiceOrderEvidenceResolveToJson(this);
}
/// 服务端提交元数据或上传现场图片后的幂等结果。
@JsonSerializable()
class ServiceOrderEvidenceUploadResult {
/// 创建一份服务端证据写入结果。
const ServiceOrderEvidenceUploadResult({
required this.evidenceId,
required this.orderId,
required this.status,
required this.uploaded,
required this.message,
this.imageUrl,
});
/// 服务端证据记录主键。
@JsonKey(fromJson: JsonTool.anyToRequiredString)
final String evidenceId;
/// 服务端订单主键。
@JsonKey(fromJson: JsonTool.anyToRequiredString)
final String orderId;
/// 服务端证据状态。
final String status;
/// 本次请求是否实际新写入文件;幂等重复成功时为 false。
final bool uploaded;
/// 面向任务日志的简短服务端处理结果。
final String message;
/// AVAILABLE 时的服务端证据图片地址。
final String? imageUrl;
/// 从统一响应中的 data 对象解析上传结果。
factory ServiceOrderEvidenceUploadResult.fromJson(
Map<String, dynamic> json,
) =>
_$ServiceOrderEvidenceUploadResultFromJson(json);
/// 转换为测试或诊断使用的 JSON。
Map<String, dynamic> toJson() =>
_$ServiceOrderEvidenceUploadResultToJson(this);
}
@JsonSerializable()
class ServiceHardware extends ServiceBase {
/// 编号
final String? id;
/// 设备名
final String? name;
/// 设备类型
final String? type;
/// 设备类型enum
final String? typeEnum;
/// 商户id
final String? merchantId;
/// 商户部门id
final String? merchantDeptId;
/// 硬件分组id
final String? hardGroupId;
/// 商户名
final String? merchantStr;
/// mq连接id
final String? mqClientId;
/// android唯一id
final String? uniqueCode;
/// 当前设备的topic
final String? mainTopic;
/// mq地址
final String? mqSocketAddress;
/// mq端口
final String? mqSocketPort;
/// mq用户名
final String? mqUsername;
/// mq密码
final String? mqPassword;
/// 同步次数版本
final int? mqSyncCount;
/// 人脸appId
final String? faceAppId;
/// 人脸sdkKey
final String? faceSdkKey;
/// 人脸activeKey
final String? faceActiveKey;
/// 商户饭卡密码 B(mch_manage.card_key,6 字节 hex);由 /hard-api/ad 终端接口下发。
final String? cardKey;
ServiceHardware({
this.id,
this.name,
this.type,
this.typeEnum,
this.merchantId,
this.merchantDeptId,
this.hardGroupId,
this.merchantStr,
this.mqClientId,
this.uniqueCode,
this.mainTopic,
this.mqSocketAddress,
this.mqSocketPort,
this.mqUsername,
this.mqPassword,
this.mqSyncCount,
this.faceAppId,
this.faceSdkKey,
this.faceActiveKey,
this.cardKey,
});
factory ServiceHardware.fromJson(Map<String, dynamic> json) =>
_$ServiceHardwareFromJson(json);
@override
Map<String, dynamic> toJson() => _$ServiceHardwareToJson(this);
}
@JsonSerializable()
class ServiceCar {
/// 编号
@JsonKey(fromJson: JsonTool.anyToString)
final String? id;
/// 父购物车id
@JsonKey(fromJson: JsonTool.anyToString)
final String? parentCarId;
/// 商品名
final String? productName;
/// 商品价格
final int? productPrice;
/// 商品id
@JsonKey(fromJson: JsonTool.anyToString)
final String? productId;
/// 数量
final int? productCount;
/// 商品性质,1 为按件商品,2 为称重商品。
final String? productNature;
/// 称重商品重量,单位沿用服务端购物车快照。
@JsonKey(fromJson: JsonTool.anyToNullableDouble)
final double? productWeight;
/// 总价(分),兼容服务端 Long 返回数字或字符串。
@JsonKey(
fromJson: JsonTool.anyToNullableInt,
toJson: JsonTool.intToString,
)
final int? totalPrice;
/// 商品图片
final String? productPic;
ServiceCar({
this.id,
this.parentCarId,
this.productName,
this.productPrice,
this.productId,
this.productCount,
this.productNature,
this.productWeight,
this.totalPrice,
this.productPic,
});
factory ServiceCar.fromJson(Map<String, dynamic> json) =>
_$ServiceCarFromJson(json);
Map<String, dynamic> toJson() => _$ServiceCarToJson(this);
}
@JsonSerializable()
class ServiceGenerateInvoice {
/// 图片
final String? pic;
/// 记录id
final String? historyId;
ServiceGenerateInvoice({
this.pic,
this.historyId,
});
factory ServiceGenerateInvoice.fromJson(Map<String, dynamic> json) =>
_$ServiceGenerateInvoiceFromJson(json);
Map<String, dynamic> toJson() => _$ServiceGenerateInvoiceToJson(this);
}
@JsonSerializable()
class ServiceQRCode {
/// 总id
@JsonKey(fromJson: JsonTool.intToString, toJson: JsonTool.stringToInt)
final String? id;
/// 子id
@JsonKey(fromJson: JsonTool.intToString, toJson: JsonTool.stringToInt)
final String? itemId;
/// 类型id 比如钱包类型
@JsonKey(fromJson: JsonTool.intToString, toJson: JsonTool.stringToInt)
final String? typeId;
/// 用户id
@JsonKey(fromJson: JsonTool.intToString, toJson: JsonTool.stringToInt)
final String? userId;
/// 订单类型
@JsonKey(
fromJson: JsonTool.stringToOrderType,
toJson: JsonTool.orderTypeToString,
)
final OrderType? orderType;
/// 支付类型
@JsonKey(
fromJson: JsonTool.stringToOrderPayType,
toJson: JsonTool.orderPayTypeToString,
)
final OrderPayType? payType;
/// 过期时间 -1 代表没有限制
final int? exceedTime;
/// 额外的用户信息
final String? extra;
ServiceQRCode({
this.id,
this.itemId,
this.typeId,
this.userId,
this.orderType,
this.payType,
this.exceedTime,
this.extra,
});
factory ServiceQRCode.fromJson(Map<String, dynamic> json) =>
_$ServiceQRCodeFromJson(json);
Map<String, dynamic> toJson() => _$ServiceQRCodeToJson(this);
}
@JsonSerializable()
class ServiceHardOrder {
/// 服务端订单主键。
@JsonKey(fromJson: JsonTool.anyToString)
final String? id;
/// 业务订单号。
final String? orderNo;
/// 用户id
@JsonKey(fromJson: JsonTool.anyToString)
final String? userId;
/// 用户名
final String? username;
/// 用户手机号
final String? userMobile;
/// 用户头像
final String? userAvatar;
/// 订单类型
final String? orderType;
/// 订单状态
final String? orderStatus;
/// 支付方式
final String? payType;
/// 钱包id
@JsonKey(fromJson: JsonTool.anyToString)
final String? walletId;
/// 用餐时段。
final String? hourType;
/// 预约用餐时段,旧预约订单可能只返回该字段。
final String? apptHourType;
/// 商品摘要。
final String? productDesc;
/// 用户所属部门。
final String? userDeptName;
/// 商品总价(分)。
@JsonKey(fromJson: JsonTool.anyToNullableInt)
final int? totalPrice;
/// 额外支付(分)。
@JsonKey(fromJson: JsonTool.anyToNullableInt)
final int? extraPrice;
/// 实际支付(分)。
@JsonKey(fromJson: JsonTool.anyToNullableInt)
final int? payPrice;
/// 终端订单号。
final String? androidOrderCode;
/// 下单时间。
final DateTime? createTime;
ServiceHardOrder({
this.id,
this.orderNo,
this.userId,
this.username,
this.userMobile,
this.userAvatar,
this.orderType,
this.orderStatus,
this.payType,
this.walletId,
this.hourType,
this.apptHourType,
this.productDesc,
this.userDeptName,
this.totalPrice,
this.extraPrice,
this.payPrice,
this.androidOrderCode,
this.createTime,
});
factory ServiceHardOrder.fromJson(Map<String, dynamic> json) =>
_$ServiceHardOrderFromJson(json);
Map<String, dynamic> toJson() => _$ServiceHardOrderToJson(this);
}
/// 当前终端预约核销记录的服务端查询参数。
@JsonSerializable(includeIfNull: false)
class VerificationRecordQueryRequest {
const VerificationRecordQueryRequest({
required this.hardId,
required this.startDate,
required this.endDate,
this.verificationType,
this.scope,
});
final int hardId;
final String startDate;
final String endDate;
final String? verificationType;
/// 数据范围:留空仅本机,MERCHANT 按终端所属商户查询全部设备。
final String? scope;
factory VerificationRecordQueryRequest.fromJson(Map<String, dynamic> json) =>
_$VerificationRecordQueryRequestFromJson(json);
Map<String, dynamic> toJson() => _$VerificationRecordQueryRequestToJson(this);
}
/// 终端交易记录的服务端查询参数,数据范围由服务端按设备归属解析。
@JsonSerializable(includeIfNull: false)
class TerminalOrderRecordQueryRequest {
const TerminalOrderRecordQueryRequest({
required this.hardId,
required this.startDate,
required this.endDate,
this.scope,
this.orderStatusCodes,
this.hourType,
});
final int hardId;
final String startDate;
final String endDate;
/// 数据范围:留空仅本机,MERCHANT 按终端所属商户查询全部设备。
final String? scope;
/// 订单状态编码集合,留空查询全部状态。
final List<String>? orderStatusCodes;
/// 用餐时段编码,留空或 -1 不区分。
final String? hourType;
factory TerminalOrderRecordQueryRequest.fromJson(Map<String, dynamic> json) =>
_$TerminalOrderRecordQueryRequestFromJson(json);
Map<String, dynamic> toJson() =>
_$TerminalOrderRecordQueryRequestToJson(this);
}
/// 交易记录远端行只承载列表展示字段,金额与时间口径和本地订单一致。
@JsonSerializable()
class ServiceTerminalOrderRecord {
const ServiceTerminalOrderRecord({
required this.orderId,
required this.orderNo,
required this.orderType,
required this.orderTypeName,
required this.orderStatus,
required this.orderStatusName,
required this.payType,
required this.payTypeName,
required this.username,
required this.productDesc,
required this.totalPrice,
required this.extraPrice,
required this.payPrice,
this.userDeptName,
this.hourType,
this.hardName,
this.createTime,
});
/// 后端 Long 为避免跨端精度丢失可能序列化为字符串,终端同时兼容数字返回。
@JsonKey(fromJson: JsonTool.anyToInt)
final int orderId;
final String orderNo;
final String orderType;
final String orderTypeName;
final String orderStatus;
final String orderStatusName;
final String payType;
final String payTypeName;
final String username;
final String? userDeptName;
final String productDesc;
final String? hourType;
/// 完成交易的设备名称;全部数据范围下用于区分不同机器。
final String? hardName;
/// 金额仍按整数分使用,同时兼容部分环境将数值序列化为字符串。
@JsonKey(fromJson: JsonTool.anyToInt)
final int totalPrice;
@JsonKey(fromJson: JsonTool.anyToInt)
final int extraPrice;
@JsonKey(fromJson: JsonTool.anyToInt)
final int payPrice;
final DateTime? createTime;
factory ServiceTerminalOrderRecord.fromJson(Map<String, dynamic> json) =>
_$ServiceTerminalOrderRecordFromJson(json);
Map<String, dynamic> toJson() => _$ServiceTerminalOrderRecordToJson(this);
}
@JsonSerializable()
class ServiceTerminalOrderRecordPage extends ServicePageBase {
ServiceTerminalOrderRecordPage({this.records});
final List<ServiceTerminalOrderRecord>? records;
factory ServiceTerminalOrderRecordPage.fromJson(Map<String, dynamic> json) =>
_$ServiceTerminalOrderRecordPageFromJson(json);
@override
Map<String, dynamic> toJson() => _$ServiceTerminalOrderRecordPageToJson(this);
}
/// 核销记录只承载列表展示字段,不复用本地订单实体,避免混淆远端与本地状态。
@JsonSerializable()
class ServiceVerificationRecord {
const ServiceVerificationRecord({
required this.orderId,
required this.orderNo,
required this.verificationType,
required this.verificationTypeName,
required this.username,
required this.productDesc,
required this.payTypeName,
required this.totalPrice,
required this.verificationTime,
this.userDeptName,
});
/// 后端 Long 为避免跨端精度丢失可能序列化为字符串,终端同时兼容数字返回。
@JsonKey(fromJson: JsonTool.anyToInt)
final int orderId;
final String orderNo;
final String verificationType;
final String verificationTypeName;
final String username;
final String? userDeptName;
final String productDesc;
final String payTypeName;
/// 金额仍按整数分使用,同时兼容部分环境将数值序列化为字符串。
@JsonKey(fromJson: JsonTool.anyToInt)
final int totalPrice;
final DateTime verificationTime;
factory ServiceVerificationRecord.fromJson(Map<String, dynamic> json) =>
_$ServiceVerificationRecordFromJson(json);
Map<String, dynamic> toJson() => _$ServiceVerificationRecordToJson(this);
}
@JsonSerializable()
class ServiceVerificationRecordPage extends ServicePageBase {
ServiceVerificationRecordPage({this.records});
final List<ServiceVerificationRecord>? records;
factory ServiceVerificationRecordPage.fromJson(Map<String, dynamic> json) =>
_$ServiceVerificationRecordPageFromJson(json);
@override
Map<String, dynamic> toJson() => _$ServiceVerificationRecordPageToJson(this);
}
@JsonSerializable()
class ServiceOpenCard {
/// 用户名
String? username;
/// 用户手机号
String? mobile;
/// 用户头像
String? avatar;
/// 饭卡状态
String? cardStatus;
/// 编号
String? id;
/// 部门名
String? deptId;
/// 部门名
String? deptName;
/// 用户编号
String? userId;
/// 饭卡类型Id
String? walletTypeId;
/// 饭卡类型
String? walletTypeUniqueCode;
/// 饭卡图标
String? walletTypeIcon;
/// 用户卡号
String? cardNumber;
/// 钱包编号
String? walletId;
/// 是否激活
@JsonKey(fromJson: JsonTool.stringToBoolean, toJson: JsonTool.booleanToString)
bool? isActiveHardware;
ServiceOpenCard({
this.username,
this.mobile,
this.avatar,
this.cardStatus,
this.id,
this.deptId,
this.deptName,
this.userId,
this.walletTypeId,
this.walletTypeUniqueCode,
this.walletTypeIcon,
this.cardNumber,
this.walletId,
this.isActiveHardware,
});
factory ServiceOpenCard.fromJson(Map<String, dynamic> json) =>
_$ServiceOpenCardFromJson(json);
Map<String, dynamic> toJson() => _$ServiceOpenCardToJson(this);
}
@JsonSerializable()
class ServiceOpenCardPage extends ServicePageBase {
List<ServiceOpenCard>? records;
ServiceOpenCardPage({
this.records,
});
factory ServiceOpenCardPage.fromJson(Map<String, dynamic> json) =>
_$ServiceOpenCardPageFromJson(
json,
);
Map<String, dynamic> toJson() => _$ServiceOpenCardPageToJson(this);
}
@JsonSerializable()
class ServiceChartLatitude {
/// 早餐、中餐、晚餐
final List<ServiceChartLatitudeItem> dayTotal;
/// 每天的交易量
final List<ServiceChartLatitudeItem> weekTotal;
/// 每天的交易金额
final List<ServiceChartLatitudeItem> monthTotal;
/// 每周的交易量
final List<ServiceChartLatitudeItem> yearTotal;
/// 每周的交易量
final List<ServiceChartLatitudeItem> allTotal;
ServiceChartLatitude({
required this.dayTotal,
required this.weekTotal,
required this.monthTotal,
required this.yearTotal,
required this.allTotal,
});
factory ServiceChartLatitude.fromJson(Map<String, dynamic> json) =>
_$ServiceChartLatitudeFromJson(
json,
);
Map<String, dynamic> toJson() => _$ServiceChartLatitudeToJson(this);
}
@JsonSerializable()
class ServiceChartLatitudeItem {
/// 早餐、中餐、晚餐
final String? hourType;
/// 每月的交易量
final String? deptId;
/// 每月的交易量
final String? sum;
/// 每月的交易量
final String? count;
ServiceChartLatitudeItem({
this.hourType,
this.deptId,
this.sum,
this.count,
});
factory ServiceChartLatitudeItem.fromJson(Map<String, dynamic> json) =>
_$ServiceChartLatitudeItemFromJson(
json,
);
Map<String, dynamic> toJson() => _$ServiceChartLatitudeItemToJson(this);
}
@JsonSerializable()
class ServiceBroadcastToday {
/// 广播id
final String id;
/// 预定用户
final String userId;
/// 用户名
final String username;
/// 用户手机号
final String userMobile;
/// 硬件id
final String hardId;
/// mq主题
final String topic;
/// 业务类型
final String? bizType;
/// 关联业务编号
final String? bizId;
/// 预定标题
final String title;
/// 预定内容
final String content;
/// 当前广播次数
final int? broadcastCount;
/// 最大广播次数
final int? broadcastMaxCount;
/// 是否广播语音
@JsonKey(fromJson: JsonTool.stringToBoolean, toJson: JsonTool.booleanToString)
final bool isBroadcast;
/// 用餐时间段
final String? hourType;
/// 商品介绍
String productDesc;
/// 支付价格
int payPrice;
/// 创建时间
String createTime;
ServiceBroadcastToday({
required this.id,
required this.userId,
required this.username,
required this.userMobile,
required this.hardId,
required this.topic,
this.bizType,
this.bizId,
required this.title,
required this.content,
this.broadcastCount,
this.broadcastMaxCount,
required this.isBroadcast,
this.hourType,
required this.productDesc,
required this.payPrice,
required this.createTime,
});
factory ServiceBroadcastToday.fromJson(Map<String, dynamic> json) =>
_$ServiceBroadcastTodayFromJson(
json,
);
Map<String, dynamic> toJson() => _$ServiceBroadcastTodayToJson(this);
}
@JsonSerializable()
class ServiceBroadcastTodayPage extends ServicePageBase {
List<ServiceBroadcastToday>? records;
ServiceBroadcastTodayPage({
this.records,
});
factory ServiceBroadcastTodayPage.fromJson(Map<String, dynamic> json) =>
_$ServiceBroadcastTodayPageFromJson(
json,
);
Map<String, dynamic> toJson() => _$ServiceBroadcastTodayPageToJson(this);
}
@JsonSerializable()
class ServiceHardCreateHardQrCodeScanOrder {
/// 订单id
String orderId;
/// 订单id
String mchId;
/// 订单id
String qrCodeData;
ServiceHardCreateHardQrCodeScanOrder({
required this.orderId,
required this.mchId,
required this.qrCodeData,
});
factory ServiceHardCreateHardQrCodeScanOrder.fromJson(
Map<String, dynamic> json) =>
_$ServiceHardCreateHardQrCodeScanOrderFromJson(
json,
);
Map<String, dynamic> toJson() =>
_$ServiceHardCreateHardQrCodeScanOrderToJson(this);
}
/// 终端按本地订单号对账查询到的服务端订单最小状态。
///
/// 创建订单请求超时后用于确认服务端是否已建单扣款;手写 fromJson,
/// 不参与 json_serializable 代码生成。
class ServiceOrderByAndroidCode {
/// 服务端订单 ID
String orderId;
/// 订单状态编码(5=已支付)
String orderStatus;
/// 支付方式编码
String payType;
/// 实付金额(分)
int payPrice;
ServiceOrderByAndroidCode({
required this.orderId,
required this.orderStatus,
required this.payType,
required this.payPrice,
});
factory ServiceOrderByAndroidCode.fromJson(Map<String, dynamic> json) {
return ServiceOrderByAndroidCode(
orderId: '${json['orderId']}',
orderStatus: '${json['orderStatus']}',
payType: '${json['payType']}',
payPrice: (json['payPrice'] as num?)?.toInt() ?? 0,
);
}
}
/// 收银终端支付宝、微信聚合订单码创建结果。
///
/// 该模型只接收 `AGGREGATE_ORDER_PAY` HTTPS 收银地址,不承载自有钱包码或平台原生码。
@JsonSerializable()
class ServiceHardAggregateOrderCodePay {
/// Hardware 业务订单 ID,状态查询必须与 [aggregateNo] 一起提交。
final String orderId;
/// 当前终端绑定的收款商户 ID。
final String mchId;
/// Thirdparty 服务生成并持久化绑定到 Hardware 订单的聚合会话编号。
final String aggregateNo;
/// 支付宝和微信均可扫码访问的 HTTPS 聚合收银地址。
final String qrCode;
/// 二维码协议类型,服务端固定返回 `AGGREGATE_ORDER_PAY`。
final String qrCodeType;
/// 服务端确定的聚合二维码失效时间。
final DateTime expireTime;
/// 创建不可变的聚合订单码结果。
const ServiceHardAggregateOrderCodePay({
required this.orderId,
required this.mchId,
required this.aggregateNo,
required this.qrCode,
required this.qrCodeType,
required this.expireTime,
});
/// 将 Hardware 接口 JSON 转换为聚合订单码结果。
factory ServiceHardAggregateOrderCodePay.fromJson(
Map<String, dynamic> json,
) =>
_$ServiceHardAggregateOrderCodePayFromJson(json);
/// 将聚合订单码结果转换为 JSON,供测试和跨 Engine 消息核对使用。
Map<String, dynamic> toJson() =>
_$ServiceHardAggregateOrderCodePayToJson(this);
}
/// Hardware 聚合订单码状态查询结果。
///
/// [paySuccess] 为 `true` 时,服务端已在订单锁内完成 Hardware 订单和库存更新。
@JsonSerializable()
class ServiceHardAggregateOrderCodePayStatus {
/// Hardware 业务订单 ID。
final String orderId;
/// 与 Hardware 订单持久化绑定的聚合会话编号。
final String aggregateNo;
/// 聚合会话状态编码:10 等待、15 创建中、20 支付中、30 成功、40 关闭、50 过期、60 创建失败。
final String status;
/// 首个有效扫码选定的平台,尚未扫码时为空。
final String? selectedPlatform;
/// 支付宝或微信实际子订单号,尚未创建时为空。
final String? payNo;
/// 是否已经由支付平台确认成功并同步 Hardware 业务订单。
final bool paySuccess;
/// 聚合二维码服务端失效时间;已由本地成功态短路返回时允许为空。
final DateTime? expireTime;
/// Hardware 业务订单当前状态编码。
final String orderStatus;
/// 创建不可变的聚合支付状态。
const ServiceHardAggregateOrderCodePayStatus({
required this.orderId,
required this.aggregateNo,
required this.status,
this.selectedPlatform,
this.payNo,
required this.paySuccess,
this.expireTime,
required this.orderStatus,
});
/// 将 Hardware 接口 JSON 转换为聚合支付状态。
factory ServiceHardAggregateOrderCodePayStatus.fromJson(
Map<String, dynamic> json,
) =>
_$ServiceHardAggregateOrderCodePayStatusFromJson(json);
/// 将聚合支付状态转换为 JSON,供日志脱敏筛选和测试使用。
Map<String, dynamic> toJson() =>
_$ServiceHardAggregateOrderCodePayStatusToJson(this);
}
/// 终端本人预约菜单查询参数。
@JsonSerializable(includeIfNull: false)
class ReservationMenuQueryRequest {
const ReservationMenuQueryRequest({
required this.hardId,
required this.recognitionType,
required this.maskName,
this.cardNumber,
this.faceUserId,
});
/// 当前终端设备 ID。
final int hardId;
/// 本人识别方式,沿用后端 CARD、FACE 契约。
final String recognitionType;
/// 是否由服务端脱敏用户姓名。
final bool maskName;
/// 饭卡卡号,仅 CARD 识别时传递。
final String? cardNumber;
/// 人脸插件识别出的用户 ID,仅 FACE 识别时传递。
final int? faceUserId;
factory ReservationMenuQueryRequest.fromJson(Map<String, dynamic> json) =>
_$ReservationMenuQueryRequestFromJson(json);
Map<String, dynamic> toJson() => _$ReservationMenuQueryRequestToJson(this);
}
/// 终端识别本人后返回的预约菜单,姓名由服务端按终端配置决定是否脱敏。
@JsonSerializable(explicitToJson: true)
class ServiceReservationMenuQuery {
/// 服务端按终端配置返回的用户姓名;字段名保留用于兼容既有协议。
final String maskedName;
/// 用户所属部门名称。
final String? deptName;
/// 当前终端绑定的食堂名称。
final String merchantName;
/// 查询结果中包含预约的日期数量。
final int totalDayCount;
/// 查询结果中包含预约的餐段数量。
final int totalMealCount;
/// 按预约日期升序排列的菜单列表。
final List<ServiceReservationDay> days;
const ServiceReservationMenuQuery({
required this.maskedName,
this.deptName,
required this.merchantName,
required this.totalDayCount,
required this.totalMealCount,
required this.days,
});
factory ServiceReservationMenuQuery.fromJson(Map<String, dynamic> json) =>
_$ServiceReservationMenuQueryFromJson(json);
Map<String, dynamic> toJson() => _$ServiceReservationMenuQueryToJson(this);
}
@JsonSerializable(explicitToJson: true)
class ServiceReservationDay {
/// 预约用餐日期,格式为 yyyy-MM-dd。
final String date;
/// 当天按餐段顺序排列的预约菜单。
final List<ServiceReservationMeal> meals;
const ServiceReservationDay({
required this.date,
required this.meals,
});
factory ServiceReservationDay.fromJson(Map<String, dynamic> json) =>
_$ServiceReservationDayFromJson(json);
Map<String, dynamic> toJson() => _$ServiceReservationDayToJson(this);
}
@JsonSerializable(explicitToJson: true)
class ServiceReservationMeal {
/// 预约餐段编码,沿用硬件订单餐段契约。
final String hourType;
/// 预约餐段显示名称。
final String mealTitle;
/// 当前餐段所有预约订单的去重餐品汇总,用于兼容旧服务端和旧终端。
final List<String> items;
/// 当前餐段可核销的预约订单 ID 列表。
@JsonKey(fromJson: JsonTool.anyListToIntList)
final List<int> orderIds;
/// 当前餐段内每笔预约订单与餐品的明确对应关系。
final List<ServiceReservationOrder> orders;
const ServiceReservationMeal({
required this.hourType,
required this.mealTitle,
required this.items,
this.orderIds = const [],
this.orders = const [],
});
factory ServiceReservationMeal.fromJson(Map<String, dynamic> json) =>
_$ServiceReservationMealFromJson(json);
Map<String, dynamic> toJson() => _$ServiceReservationMealToJson(this);
}
/// 同一餐段内单笔预约与餐品的对应关系;旧服务端没有该字段时保持空列表。
@JsonSerializable(explicitToJson: true)
class ServiceReservationOrder {
/// 可核销的预约订单 ID。
@JsonKey(fromJson: JsonTool.anyToInt)
final int orderId;
/// 该笔预约订单实际购买的商品与数量明细。
final List<ServiceReservationOrderItem> items;
const ServiceReservationOrder({
required this.orderId,
required this.items,
});
factory ServiceReservationOrder.fromJson(Map<String, dynamic> json) =>
_$ServiceReservationOrderFromJson(json);
Map<String, dynamic> toJson() => _$ServiceReservationOrderToJson(this);
}
/// 单笔预约订单中的商品与购买数量。
@JsonSerializable(explicitToJson: true)
class ServiceReservationOrderItem {
/// 订单中的菜品库商品 SPU ID;旧服务端未返回时为空。
@JsonKey(fromJson: JsonTool.anyToNullableInt)
final int? productId;
/// 订单中的商品名称。
final String productName;
/// 订单中的商品图片地址。
final String? productPic;
/// 订单中的商品购买数量;历史异常数据缺失时允许为空。
final int? productCount;
/// 商品类型:1 为单品,2 为套餐;旧服务端缺失时按单品处理。
final int spuType;
/// 套餐内的组成菜品;单品或旧服务端返回时为空列表。
final List<ServiceReservationComboItem> comboItems;
/// 创建服务端预约订单商品;新字段均提供兼容旧服务端的默认值。
const ServiceReservationOrderItem({
this.productId,
required this.productName,
this.productPic,
this.productCount,
this.spuType = 1,
this.comboItems = const [],
});
/// 从预约菜单接口 JSON 创建订单商品。
factory ServiceReservationOrderItem.fromJson(Map<String, dynamic> json) =>
_$ServiceReservationOrderItemFromJson(json);
/// 将订单商品转换为可传输 JSON。
Map<String, dynamic> toJson() => _$ServiceReservationOrderItemToJson(this);
}
/// 预约订单中的套餐组成菜品,只承担服务端 JSON 与终端展示模型之间的传输。
@JsonSerializable()
class ServiceReservationComboItem {
/// 组成菜品 SPU ID;菜品已删除或历史数据缺失时为空。
@JsonKey(fromJson: JsonTool.anyToNullableInt)
final int? childSpuId;
/// 组成菜品名称;关联菜品缺失时为空。
final String? name;
/// 组成菜品封面地址;未配置时为空。
final String? picUrl;
/// 套餐内组成菜品的份数;异常或缺失时由页面兜底为 1。
final int? quantity;
/// 套餐组成显示顺序;缺失时按接口返回顺序保留。
final int? sortOrder;
/// 组成菜品展示单价,单位为分;缺失时不展示价格。
final int? price;
/// 创建服务端套餐组成传输模型,缺失字段保持为空并交由页面模型规范化。
const ServiceReservationComboItem({
this.childSpuId,
this.name,
this.picUrl,
this.quantity,
this.sortOrder,
this.price,
});
/// 从预约菜单接口 JSON 创建套餐组成。
factory ServiceReservationComboItem.fromJson(Map<String, dynamic> json) =>
_$ServiceReservationComboItemFromJson(json);
/// 将套餐组成转换为可传输 JSON。
Map<String, dynamic> toJson() => _$ServiceReservationComboItemToJson(this);
}