using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Globalization; namespace FATrace.Com { /// /// NVR 公共的类 /// public class NVRCom { private static string[] SplitCodeParts(string code) { if (string.IsNullOrWhiteSpace(code)) return Array.Empty(); var normalized = code.Trim() .Replace(',', ',') .Replace(';', ',') .Replace(';', ','); // 优先使用逗号分隔,避免 SolidBeveBatch 中包含空格导致被错误切分 if (normalized.Contains(',')) { return normalized .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(p => p.Trim()) .ToArray(); } // 无逗号时回退到按空白分隔 return normalized .Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries) .Select(p => p.Trim()) .ToArray(); } /// /// 获取视频名称 /// /// /// public static string GetVideoPathName(string basePath, string Code) { // 清洗非法文件名字符,避免保存失败 string safeCode = Code; try { var invalid = System.IO.Path.GetInvalidFileNameChars(); safeCode = new string(Code.Where(c => !invalid.Contains(c)).ToArray()); if (string.IsNullOrWhiteSpace(safeCode)) safeCode = DateTime.Now.ToString("yyyy-MM-dd HHmmss"); } catch { } return $"{basePath}\\{safeCode}.mp4"; } /// /// 获取视频名称 /// /// public static string GetVideoName(string Code) { string safeCode = Code; try { var invalid = System.IO.Path.GetInvalidFileNameChars(); safeCode = new string(Code.Where(c => !invalid.Contains(c)).ToArray()); if (string.IsNullOrWhiteSpace(safeCode)) safeCode = DateTime.Now.ToString("yyyy-MM-dd HHmmss"); } catch { } return $"{safeCode}.mp4"; } /// /// 解析条码 /// /// public static (string RawCode, string Batch, string Weight) ParseCode(string Code) { if (string.IsNullOrWhiteSpace(Code)) { return (string.Empty, string.Empty, string.Empty); } try { var parts = SplitCodeParts(Code); // 新二维码固定 7 段:RawCode,Batch,SolidBeveBatch,Weight,ShelfLife,Region,DayCount if (parts.Length != 7) { return (string.Empty, string.Empty, string.Empty); } string rawCode = parts.Length > 0 ? parts[0] : string.Empty; // 批号:通常为 8 位日期 yyyyMMdd;保留前 8 位数字 string batch = string.Empty; if (parts.Length > 1) { var digits = new string(parts[1].Where(char.IsDigit).ToArray()); if (digits.Length >= 8) batch = digits.Substring(0, 8); else batch = digits; // 若不足 8 位,原样返回可供上层判定 } // 重量:3/4 位数字,最后一位为小数位(例:802 => 80.2g)。 string weight = string.Empty; var weightIndex = 3; if (parts.Length > 3) { var digits = new string(parts[weightIndex].Where(char.IsDigit).ToArray()); if (digits.Length >= 2) { // 在最后一位前插入小数点,如 802 => 80.2,1234 => 123.4 weight = string.Concat(digits.AsSpan(0, digits.Length - 1), ".", digits.AsSpan(digits.Length - 1)); } else if (digits.Length == 1) { weight = "0." + digits; // 兜底:1 位数字视为 0.x } } return (rawCode, batch, weight); } catch { return (string.Empty, string.Empty, string.Empty); } } public static ParsedCodeInfo ParseCodeFull(string code) { var result = new ParsedCodeInfo(); if (string.IsNullOrWhiteSpace(code)) return result; result.Code = code; try { var parts = SplitCodeParts(code); // 新二维码固定 7 段:RawCode,Batch,SolidBeveBatch,Weight,ShelfLife,Region,DayCount if (parts.Length != 7) { return result; } result.RawCode = parts.Length > 0 ? parts[0] : string.Empty; if (parts.Length > 1) { var digits = new string(parts[1].Where(char.IsDigit).ToArray()); result.Batch = digits.Length >= 8 ? digits.Substring(0, 8) : digits; } // 新二维码(7段)第3段为固体饮料批次 result.SolidBeveBatch = parts[2]; var weightIndex = 3; if (parts.Length > 3) { var digits = new string(parts[weightIndex].Where(char.IsDigit).ToArray()); string weightStr = string.Empty; if (digits.Length >= 2) { weightStr = string.Concat(digits.AsSpan(0, digits.Length - 1), ".", digits.AsSpan(digits.Length - 1)); } else if (digits.Length == 1) { weightStr = "0." + digits; } if (!string.IsNullOrWhiteSpace(weightStr)) { if (decimal.TryParse(weightStr, NumberStyles.Any, CultureInfo.InvariantCulture, out var w)) result.Weight = w; } } var shelfLifeIndex = 4; if (parts.Length > 4) { var digits = new string(parts[shelfLifeIndex].Where(char.IsDigit).ToArray()); if (int.TryParse(digits, out var m)) result.ShelfLifeMonths = m; } var regionIndex = 5; if (parts.Length > 5) { var digits = new string(parts[regionIndex].Where(char.IsDigit).ToArray()); result.RegionCode = digits; result.RegionName = digits == "01" ? "国内" : (digits == "02" ? "日本" : "未知"); } var countIndex = 6; if (parts.Length > 6) { var digits = new string(parts[countIndex].Where(char.IsDigit).ToArray()); if (int.TryParse(digits, out var c)) result.Count = c; } } catch { } return result; } } }