Files
FATrace/FATrace.Model/QRModel.cs
2026-01-13 15:03:02 +08:00

114 lines
4.0 KiB
C#
Raw 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.Model
{
/// <summary>
/// 二维码模型信息
/// 示例DYG05030013,20250923,802,3,01,0001
/// 1段产品编码
/// 2段批号/生产日期,格式 yyyyMMdd例如 20250923
/// 3段重量编码3/4 位数字,末位为小数位,例如 802 表示 80.2g
/// 4段保质期月数1 位数字
/// 5段国家代码01=国内02=日本
/// 6段当日产量计数4 位,从 0001 开始)
/// </summary>
public class QRModel
{
/// <summary>
/// 原始二维码字符串
/// </summary>
public string RawText { get; set; } = string.Empty;
/// <summary>
/// 原料编号(第一段)
/// </summary>
public string RawCode { get; set; } = string.Empty;
/// <summary>
/// 批号
/// </summary>
public string Batch { get; set; }
/// <summary>
/// 重量(第三段解析后的实际数值,比如 802 -> 80.2
/// 单位:克(如有需要可在业务层自行换算)
/// </summary>
public decimal Weight { get; set; }
/// <summary>
/// 保质期(月数,来自第四段)
/// </summary>
public int ShelfLife { get; set; }
/// <summary>
/// 国家代码(第五段,例如 01=国内02=日本)
/// </summary>
public string RawSource { get; set; } = string.Empty;
/// <summary>
/// 当日生产序号第六段4 位,从 1 开始)
/// </summary>
public int DailySequence { get; set; }
/// <summary>
/// 解析二维码字符串为 QRModel。
/// 预期格式:"产品编码,yyyyMMdd,重量编码,保质期(月),国家代码,当日序号"。
/// </summary>
/// <param name="text">二维码原始字符串</param>
/// <returns>解析成功的 QRModel 实例</returns>
/// <exception cref="ArgumentException">当格式不正确时抛出</exception>
public static QRModel Parse(string text)
{
if (string.IsNullOrWhiteSpace(text))
{
throw new ArgumentException("二维码内容不能为空。", nameof(text));
}
var parts = text.Split(',');
if (parts.Length != 6)
{
throw new ArgumentException($"二维码格式不正确,预期 6 段,实际为 {parts.Length} 段。内容:{text}", nameof(text));
}
var model = new QRModel
{
RawText = text.Trim(),
RawCode = parts[0].Trim(),
Batch = parts[1].Trim(),
RawSource = parts[4].Trim()
};
// 重量3/4 位数字,末位为小数位,例如 802 -> 80.2
var weightCode = parts[2].Trim();
if (!int.TryParse(weightCode, out var weightInt))
{
throw new ArgumentException($"重量段不是有效数字:{weightCode}", nameof(text));
}
// 按 1 位小数解析80.2g),如需其他规则可在此调整
model.Weight = weightInt / 10m;
// 保质期(月)
var shelfText = parts[3].Trim();
if (!int.TryParse(shelfText, out var shelfMonths) || shelfMonths < 0)
{
throw new ArgumentException($"保质期(月)不是有效数字:{shelfText}", nameof(text));
}
model.ShelfLife = shelfMonths;
// 当日序号
var seqText = parts[5].Trim();
if (!int.TryParse(seqText, out var seq) || seq < 0)
{
throw new ArgumentException($"当日生产序号不是有效数字:{seqText}", nameof(text));
}
model.DailySequence = seq;
return model;
}
}
}