using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_DTO.BasicInfo; using WIDESEA_IBasicInfoServices; using WIDESEA_Model.Models; namespace WIDESEA_BasicInfoServices { public class RuntimeCodeService : ServiceBase>, IRuntimeCodeService { private const int BaseRandomLength = 25; private const int RuntimeCodeLength = 25; private readonly IRepository _productRepository; public RuntimeCodeService(IRepository BaseDal, IRepository productRepository) : base(BaseDal) { _productRepository = productRepository; } // 生成设备运行码主方法 public WebResponseContent GenerateRuntimeCode(DeviceInfoDTO deviceInfo) { try { int productId = -1; Dt_Products product = _productRepository.QueryFirst(x => x.ProductName == deviceInfo.ProductName); if (product != null) { productId = product.Id; } Dt_RuntimeCode runtimeCodeModel = BaseDal.QueryFirst(x => x.DeviceId == deviceInfo.DeviceId && x.ProductId == productId); if (runtimeCodeModel != null) { return WebResponseContent.Instance.OK(data: runtimeCodeModel.RuntimeCode); } GenerateBaseRandomL: // 1. 生成基础随机码 string baseRandom = GenerateBaseRandom(); // 2. 添加校验位 char checkDigit = CalculateCheckDigit(baseRandom); // 3. 组合完整运行码 string runtimeCode = FormatRuntimeCode(baseRandom + checkDigit); if (BaseDal.QueryFirst(x => x.RuntimeCode == runtimeCode) != null) { goto GenerateBaseRandomL; } // 4. 存储到数据库 StoreRuntimeCode(deviceInfo.DeviceId, checkDigit.ToString(), baseRandom, runtimeCode, deviceInfo.DeviceInfoJson, productId); return WebResponseContent.Instance.OK(data: runtimeCode); } catch (Exception ex) { return WebResponseContent.Instance.Error(message: "生成运行码失败"); } } // 生成20位随机基础码 private string GenerateBaseRandom() { const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var random = new Random(); return new string(Enumerable.Repeat(chars, BaseRandomLength) .Select(s => s[random.Next(s.Length)]).ToArray()); } // 计算Luhn校验位 private char CalculateCheckDigit(string baseRandom) { int sum = 0; bool alternate = true; // 从右向左处理 for (int i = baseRandom.Length - 1; i >= 0; i--) { int n = CharToInt(baseRandom[i]); sum += alternate ? n : (n * 2 > 9 ? n * 2 - 9 : n * 2); alternate = !alternate; } int checkDigit = (10 - (sum % 10)) % 10; return checkDigit.ToString().ToCharArray().FirstOrDefault(); } // 字符转数字 private int CharToInt(char c) { return c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10; } // 格式化运行码 (XXXXX-XXXXX-XXXXX-XXXXX-XXXXX) private string FormatRuntimeCode(string rawCode) { return string.Join("-", rawCode.Substring(0, 5), rawCode.Substring(5, 5), rawCode.Substring(10, 5), rawCode.Substring(15, 5), rawCode.Substring(20, 5)); } // 存储到数据库 private void StoreRuntimeCode(string deviceId, string checkDigit, string baseRandom, string runtimeCode, string deviceInfo, int productId) { Dt_RuntimeCode runtimeRecord = new Dt_RuntimeCode { BaseRandom = baseRandom, RuntimeCode = runtimeCode, DeviceInfo = deviceInfo, DeviceId = deviceId, CheckDigit = checkDigit, ProductId = productId // 假设产品ID为1,实际应用中应根据具体逻辑获取 }; BaseDal.AddData(runtimeRecord); } } }