z8018
2 天以前 d8dc91f9c1fece5711e38edd1b1274cb9e579015
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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<Dt_RuntimeCode, IRepository<Dt_RuntimeCode>>, IRuntimeCodeService
    {
        private const int BaseRandomLength = 25;
        private const int RuntimeCodeLength = 25;
 
        private readonly IRepository<Dt_Products> _productRepository;
 
        public RuntimeCodeService(IRepository<Dt_RuntimeCode> BaseDal, IRepository<Dt_Products> 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);
        }
    }
}