114 lines
4.0 KiB
C#
114 lines
4.0 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|