using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FATrace.Model
{
///
/// 二维码模型信息
/// 示例:DYG05030013,20250923,802,3,01,0001
/// 1段:产品编码
/// 2段:批号/生产日期,格式 yyyyMMdd,例如 20250923
/// 3段:重量编码,3/4 位数字,末位为小数位,例如 802 表示 80.2g
/// 4段:保质期(月数),1 位数字
/// 5段:国家代码,01=国内,02=日本
/// 6段:当日产量计数(4 位,从 0001 开始)
///
public class QRModel
{
///
/// 原始二维码字符串
///
public string RawText { get; set; } = string.Empty;
///
/// 原料编号(第一段)
///
public string RawCode { get; set; } = string.Empty;
///
/// 批号
///
public string Batch { get; set; }
///
/// 重量(第三段解析后的实际数值,比如 802 -> 80.2)
/// 单位:克(如有需要可在业务层自行换算)
///
public decimal Weight { get; set; }
///
/// 保质期(月数,来自第四段)
///
public int ShelfLife { get; set; }
///
/// 国家代码(第五段,例如 01=国内,02=日本)
///
public string RawSource { get; set; } = string.Empty;
///
/// 当日生产序号(第六段,4 位,从 1 开始)
///
public int DailySequence { get; set; }
///
/// 解析二维码字符串为 QRModel。
/// 预期格式:"产品编码,yyyyMMdd,重量编码,保质期(月),国家代码,当日序号"。
///
/// 二维码原始字符串
/// 解析成功的 QRModel 实例
/// 当格式不正确时抛出
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;
}
}
}