Parcourir la source

添加项目文件。

baowei il y a 7 mois
Parent
commit
7386100068

+ 13 - 0
EInk.Lot3/.config/dotnet-tools.json

@@ -0,0 +1,13 @@
+{
+  "version": 1,
+  "isRoot": true,
+  "tools": {
+    "dotnet-ef": {
+      "version": "8.0.6",
+      "commands": [
+        "dotnet-ef"
+      ],
+      "rollForward": false
+    }
+  }
+}

+ 111 - 0
EInk.Lot3/Controllers/Lot3Controller.cs

@@ -0,0 +1,111 @@
+using EInk.Dtos;
+using EInk.Models;
+using Microsoft.AspNetCore.Mvc;
+using Newtonsoft.Json;
+using SqlSugar;
+using System;
+using System.ComponentModel;
+using System.Xml.Linq;
+using System;
+using System.Threading;
+using System.Text;
+
+namespace EInk.Controllers
+{
+    [Route("api/[controller]")]
+    [ApiController]
+    public class Lot3Controller : ControllerBase
+    {
+        private readonly ISqlSugarClient _db;
+        public Lot3Controller(ISqlSugarClient db)
+        {
+            _db = db;
+        }
+
+        // POST api/<Lot3Controller>
+        [HttpPost("AccessLot3")]
+        public IActionResult Lot3Data(string Lot3Data)
+        {
+            try
+            {
+                if (String.IsNullOrEmpty(Lot3Data))
+                {
+                    return Ok(ResultDto.Fail("Components is null"));
+                }
+                Lot2Lot3Dto lot3Dto = new Lot2Lot3Dto();
+                try
+                {
+                    lot3Dto = JsonConvert.DeserializeObject<Lot2Lot3Dto>(Lot3Data);
+                }
+                catch (Exception)
+                {
+                    return Ok(ResultDto.Fail("Incorrect Json format"));
+                }
+                try
+                {
+                    lot3Dto.Valid();
+                }
+                catch (Exception ex)
+                {
+                    return Ok(ResultDto.Fail(ex.Message));
+                }
+                //int id = _db.Ado.GetInt("select max(count) from lot2lot3_info");
+                Lot2Lot3Model lot3model = new()
+                {
+                    //id = id + 1,
+                    lot_id = lot3Dto.id,
+                    //判断数据是否重复插入,重复插入is_send标记为3
+                    is_send = _db.Ado.GetInt(string.Format("select count(*) from lot2lot3_info where lot_id='{0}'", lot3Dto.id)) == 0 ? 0 : 3,
+                    content = Lot3Data,
+                    create_time = DateTime.Now
+                };
+                _db.Insertable(lot3model).ExecuteCommand();
+                return Ok(ResultDto.Success());
+            }
+            catch (Exception ex)
+            {
+                return Ok(ResultDto.Fail("error:" + ex.Message));
+            }
+        }
+
+        // POST api/<Lot3Controller>
+        [HttpPost("UpdateDefectInfo")]
+        public IActionResult UpdateDefectInfo(IFormFile file)
+        {
+            if (file == null || file.Length == 0)
+            {
+                return Ok(ResultDto.Fail("No file selected"));
+            }
+
+            string line;
+            try
+            {
+                _db.Ado.BeginTran();
+                _db.Deleteable<DefectModel>().ExecuteCommand();
+                using (var reader = new StreamReader(file.OpenReadStream(), Encoding.GetEncoding("gb2312")))
+                {
+                    var header = reader.ReadLine();
+                    var headers = header.Split(',');
+                    while ((line = reader.ReadLine()) != null)
+                    {
+                        string[] linelist = line.Split(",");
+                        _db.Insertable(new DefectModel
+                        {
+                            id = Convert.ToInt32(linelist[0]),
+                            defect_code = linelist[1],
+                            defect_name = linelist[2],
+                            classification = linelist[3].Replace(';', ',')
+                        }).ExecuteCommand();
+                    }
+                }
+                _db.Ado.CommitTran();
+            }
+            catch(Exception ex)
+            {
+                _db.Ado.RollbackTran();
+                return Ok(ResultDto.Fail(ex.Message));
+            }
+            return Ok(ResultDto.Success());
+        }
+    }
+}

+ 12 - 0
EInk.Lot3/Dtos/GuidDto.cs

@@ -0,0 +1,12 @@
+namespace EInk.Dtos
+{
+    public class GuidDto
+    {
+        public GuidDto()
+        {
+            Id = Guid.NewGuid().ToString().ToUpper(); 
+        }
+
+        public string Id { get; set; }
+    }
+}

+ 16 - 0
EInk.Lot3/Dtos/InitLot2DetailDto.cs

@@ -0,0 +1,16 @@
+namespace EInk.Dtos
+{
+    public class InitLot2DetailDto
+    {
+
+        public string ID { get; set; }
+        public string Classification { get; set; }
+        public string ContourRect_X { get; set; }
+        public string ContourRect_Y { get; set; }
+        public string ContourRect_Width { get; set; }
+        public string ContourRect_Height { get; set; }
+        public string ContourRect_Area { get; set; }
+    }
+
+
+}

+ 169 - 0
EInk.Lot3/Dtos/Lot2Lot3Dto.cs

@@ -0,0 +1,169 @@
+using Microsoft.Extensions.FileSystemGlobbing.Internal;
+using System.ComponentModel;
+using static System.Collections.Specialized.BitVector32;
+
+namespace EInk.Dtos
+{
+    public class Lot2Lot3Dto
+    {
+        public string id { get; set; }
+        public string slidesNumber { get; set; }
+        public string topic { get; set; }
+        public string createTime { get; set; }
+        public string result { get; set; }
+        public List<itemCheckData> itemCheckDatas { get; set; } = new List<itemCheckData>();
+
+        public void Valid()
+        {
+            if (String.IsNullOrEmpty(id.Trim()))
+            {
+                throw new Exception("Empty id");
+            }
+            if (String.IsNullOrEmpty(slidesNumber.Trim()))
+            {
+                throw new Exception("Empty slidesNumber");
+            }
+            if (String.IsNullOrEmpty(result.Trim()))
+            {
+                throw new Exception("Empty result");
+            }
+            if (result!="NG"&&result!="OK")
+            {
+                throw new Exception("Incorrect result");
+            }
+            try
+            {
+                DateTime valid = Convert.ToDateTime(createTime);
+            }
+            catch
+            {
+                throw new Exception("Incorrect createTime");
+            }
+            foreach (var itemCheckData in itemCheckDatas)
+            {
+                itemCheckData.Valid();
+            }
+        }
+    }
+
+    public class itemCheckData
+    {
+        public string station { get; set; }
+        public string method { get; set; }
+        public string pattern { get; set; }
+        public string result { get; set; }
+        public string imagePath { get; set; }
+        public string detailImagePath { get; set; }
+        public List<detail> details { get; set; } = new List<detail>();
+        public void Valid()
+        {
+            if (String.IsNullOrEmpty(station.Trim()))
+            {
+                throw new Exception("Empty station");
+            }
+            if (String.IsNullOrEmpty(method.Trim()))
+            {
+                throw new Exception("Empty method");
+            }
+            if (String.IsNullOrEmpty(pattern.Trim()))
+            {
+                throw new Exception("Empty pattern");
+            }
+            if (String.IsNullOrEmpty(result.Trim()))
+            {
+                throw new Exception("Empty result");
+            }
+            if (result != "NG" && result != "OK")
+            {
+                throw new Exception("Incorrect result");
+            }
+            foreach (var itemdetail in details)
+            {
+                itemdetail.Valid();
+            }
+        }
+    }
+
+    public class detail
+    {
+        public string defectCode { get; set; }
+        public string defectName { get; set; }
+        public string x { get; set; }
+        public string y { get; set; }
+        public string width { get; set; }
+        public string height { get; set; }
+        public string area { get; set; }
+        public void Valid()
+        {
+            if (String.IsNullOrEmpty(defectCode.Trim()))
+            {
+                throw new Exception("Empty defectCode");
+            }
+            if (String.IsNullOrEmpty(defectName.Trim()))
+            {
+                throw new Exception("Empty defectName");
+            }
+            if (String.IsNullOrEmpty(x.Trim()))
+            {
+                throw new Exception("Empty x");
+            }
+            if (String.IsNullOrEmpty(y.Trim()))
+            {
+                throw new Exception("Empty y");
+            }
+            if (String.IsNullOrEmpty(width.Trim()))
+            {
+                throw new Exception("Empty width");
+            }
+            if (String.IsNullOrEmpty(height.Trim()))
+            {
+                throw new Exception("Empty height");
+            }
+            if (String.IsNullOrEmpty(area.Trim()))
+            {
+                throw new Exception("Empty area");
+            }
+
+            //try
+            //{
+            //    double valid = Convert.ToDouble(x);
+            //}
+            //catch
+            //{
+            //    throw new Exception("Incorrect x");
+            //}
+            //try
+            //{
+            //    double valid = Convert.ToDouble(y);
+            //}
+            //catch
+            //{
+            //    throw new Exception("Incorrect y");
+            //}
+            //try
+            //{
+            //    double valid = Convert.ToDouble(width);
+            //}
+            //catch
+            //{
+            //    throw new Exception("Incorrect width");
+            //}
+            //try
+            //{
+            //    double valid = Convert.ToDouble(height);
+            //}
+            //catch
+            //{
+            //    throw new Exception("Incorrect height");
+            //}
+            //try
+            //{
+            //    double valid = Convert.ToDouble(area);
+            //}
+            //catch
+            //{
+            //    throw new Exception("Incorrect area");
+            //}
+        }
+    }
+}

+ 62 - 0
EInk.Lot3/Dtos/ResultDto.cs

@@ -0,0 +1,62 @@
+namespace EInk.Dtos
+{
+    public enum CodeEnum
+    {
+        Ok = 0,
+        Fail = 1,
+        Error = 500
+    }
+
+    public class ResultDto
+    {
+        public CodeEnum Code { get; set; }
+        public string? Message { get; set; }
+
+        //public long? Time { get; set; }
+
+        public static ResultDto Success()
+        {
+            return new ResultDto { Code = CodeEnum.Ok, Message = "Ok!" };
+        }
+
+        //public static ResultDto Success(long time)
+        //{
+        //    return new ResultDto { Code = CodeEnum.Ok, Message = "Ok!", Time = time };
+        //}
+
+        public static ResultDto Fail(string message)
+        {
+            return new ResultDto { Code = CodeEnum.Fail, Message = message};
+        }
+
+        public static ResultDto Error(string message)
+        {
+            return new ResultDto { Code = CodeEnum.Error, Message = message };
+        }
+    }
+
+    public class ResultDto<T> : ResultDto where T : class
+    {
+        public T? Data { get; set; }
+
+        public static new ResultDto<T> Success()
+        {
+            return new ResultDto<T> { Code = CodeEnum.Ok, Message = "Ok!" };
+        }
+
+        public static new ResultDto Fail(string message)
+        {
+            return new ResultDto { Code = CodeEnum.Fail, Message = message };
+        }
+
+        public static ResultDto<T> Success(T data)
+        {
+            return new ResultDto<T> { Code = CodeEnum.Ok, Message = "Ok!", Data = data };
+        }
+
+        //public static ResultDto Success(long time, T data)
+        //{
+        //    return new ResultDto<T> { Code = CodeEnum.Ok, Message = "Ok!", Time = time, Data = data };
+        //}
+    }
+}

+ 16 - 0
EInk.Lot3/EInk.Lot2Lot3.csproj

@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>net6.0</TargetFramework>
+    <Nullable>enable</Nullable>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <GenerateDocumentationFile>True</GenerateDocumentationFile>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Quartz" Version="3.9.0" />
+    <PackageReference Include="SqlSugarCore" Version="5.1.4.158" />
+    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
+  </ItemGroup>
+
+</Project>

+ 21 - 0
EInk.Lot3/Models/DefectModel.cs

@@ -0,0 +1,21 @@
+using SqlSugar;
+
+namespace EInk.Models
+{
+    [SugarTable("defect_info")]
+    public class DefectModel
+    {
+        [SugarColumn(ColumnName = "id", IsPrimaryKey = true)]
+        public int id { get; set; }
+
+        [SugarColumn(ColumnName = "defect_code")]
+        public string defect_code { get; set; }
+
+        [SugarColumn(ColumnName = "defect_name")]
+        public string defect_name { get; set; }
+
+        [SugarColumn(ColumnName = "classification")]
+        public string classification { get; set; }
+
+    }
+}

+ 29 - 0
EInk.Lot3/Models/InitLot2Model.cs

@@ -0,0 +1,29 @@
+using SqlSugar;
+
+namespace EInk.Models
+{
+    [SugarTable("product")]
+    public class InitLot2Model
+    {
+        [SugarColumn(ColumnName = "id", IsPrimaryKey = true)]
+        public int id { get; set; }
+
+        [SugarColumn(ColumnName = "productno")]
+        public string productno { get; set; }
+
+        [SugarColumn(ColumnName = "station")]
+        public string station { get; set; }
+
+        [SugarColumn(ColumnName = "pattern")]
+        public string pattern { get; set; }
+
+        [SugarColumn(ColumnName = "result")]
+        public string result { get; set; }
+
+        [SugarColumn(ColumnName = "detail")]
+        public string detail { get; set; }
+
+        [SugarColumn(ColumnName = "created_at")]
+        public DateTime created_at { get; set; }
+    }
+}

+ 32 - 0
EInk.Lot3/Models/Lot2Lot3Model.cs

@@ -0,0 +1,32 @@
+using SqlSugar;
+
+namespace EInk.Models
+{
+    [SugarTable("lot2lot3_info")]
+    public class Lot2Lot3Model
+    {
+        [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
+        public int id { get; set; }
+
+        [SugarColumn(ColumnName = "lot_id")]
+        public string lot_id { get; set; }
+
+        [SugarColumn(ColumnName = "is_send")]
+        public int is_send { get; set; }
+
+        [SugarColumn(ColumnName = "content")]
+        public string content { get; set; }
+
+        [SugarColumn(ColumnName = "create_time")]
+        public DateTime create_time { get; set; }
+
+        [SugarColumn(ColumnName = "send_time")]
+        public DateTime send_time { get; set; }
+
+        [SugarColumn(ColumnName = "product_no")]
+        public string product_no { get; set; }
+
+        [SugarColumn(ColumnName = "product_id")]
+        public int product_id { get; set; }
+    }
+}

+ 52 - 0
EInk.Lot3/Program.cs

@@ -0,0 +1,52 @@
+using EInk.Lot2Lot3;
+using EInk.TaskThread;
+using SqlSugar;
+using System.Text;
+
+Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+var builder = WebApplication.CreateBuilder(args);
+// Add services to the container.
+builder.Services.AddControllers();
+// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen();
+builder.Services.AddSingleton<IStartupFilter, ReadLot2Filter>();
+builder.Services.AddSingleton<IStartupFilter, SendLot2Lot3Filter>();
+builder.Services.AddSingleton<ISqlSugarClient>(s =>
+{
+    SqlSugarScope sqlSugar = new(new ConnectionConfig()
+    {
+        DbType = DbType.PostgreSQL,
+        //ConnectionString = "Host=127.0.0.1;Port=5432;Database=pg;Username=postgres;Password=eink;",
+        ConnectionString = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build().GetValue<string>("LocalDbConnectionString"),
+        IsAutoCloseConnection = true,
+    },
+    db =>
+    {
+        //db.DbMaintenance.CreateDatabase();
+        //db.CodeFirst.InitTables(typeof(BoxDetai2l));
+        //db.Aop.OnLogExecuting = (sql, pars) =>
+        //{
+
+        //};
+    });
+    return sqlSugar;
+});
+
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+//if (app.Environment.IsDevelopment())
+//{
+//    app.UseSwagger();
+//    app.UseSwaggerUI();
+//}
+app.UseSwagger();
+app.UseSwaggerUI();
+app.UseHttpsRedirection();
+
+app.UseAuthorization();
+
+app.MapControllers();
+
+app.Run();

+ 31 - 0
EInk.Lot3/Properties/launchSettings.json

@@ -0,0 +1,31 @@
+{
+  "$schema": "https://json.schemastore.org/launchsettings.json",
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:58293",
+      "sslPort": 44350
+    }
+  },
+  "profiles": {
+    "EInk.Lot2Lot3": {
+      "commandName": "Project",
+      "dotnetRunMessages": true,
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "applicationUrl": "https://localhost:7084;http://localhost:5229",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    }
+  }
+}

+ 56 - 0
EInk.Lot3/Startup.cs

@@ -0,0 +1,56 @@
+using EInk.TaskThread;
+using Microsoft.AspNetCore.Builder;
+using SqlSugar;
+
+namespace EInk.Lot2Lot3
+{
+    
+    public class ReadLot2Filter : IStartupFilter
+    {
+        private readonly ISqlSugarClient _db = new SqlSugarClient(new ConnectionConfig()
+        {
+            DbType = DbType.PostgreSQL,
+            ConnectionString = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build().GetValue<string>("TargetDbConnectionString"),
+            IsAutoCloseConnection = true
+        });
+
+        private readonly ISqlSugarClient _local_db = new SqlSugarClient(new ConnectionConfig()
+        {
+            DbType = DbType.PostgreSQL,
+            ConnectionString = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build().GetValue<string>("LocalDbConnectionString"),
+            IsAutoCloseConnection = true
+        });
+
+        public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
+        {
+            ReadLot2Thread readLot2 = new ReadLot2Thread(_db, _local_db);
+            if (new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build().GetValue<string>("ReadLot2Thread") =="on")
+            {
+                readLot2.ReadThreadStart(); 
+            }
+            return app => next(app);
+        }
+    }
+
+    public class SendLot2Lot3Filter : IStartupFilter
+    {
+        private readonly ISqlSugarClient _db = new SqlSugarClient(new ConnectionConfig()
+        {
+            DbType = DbType.PostgreSQL,
+            ConnectionString = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build().GetValue<string>("LocalDbConnectionString"),
+            IsAutoCloseConnection = true
+        });
+
+        public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
+        {
+            SendLot2Lot3Thread sendLot2Lot3 = new SendLot2Lot3Thread(_db);
+            if (new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build().GetValue<string>("SendLot2Lot3Thread") == "on")
+            {
+                sendLot2Lot3.SendThreadStart();
+            }
+            return app => next(app);
+        }
+    }
+
+
+}

+ 331 - 0
EInk.Lot3/TaskThread/ReadLot2Thread.cs

@@ -0,0 +1,331 @@
+using EInk.Models;
+using EInk.Dtos;
+using SqlSugar;
+using System.ComponentModel;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using EInk.Tools;
+using Microsoft.Extensions.FileSystemGlobbing.Internal;
+using System.Linq;
+
+namespace EInk.TaskThread
+{
+    public class ReadLot2Thread
+    {
+        private readonly ISqlSugarClient _db;
+        private readonly ISqlSugarClient _local_db;
+
+        public ReadLot2Thread(ISqlSugarClient db, ISqlSugarClient local_db)
+        {
+            _db = db;
+            _local_db = local_db;
+        }
+
+        public void ReadThreadStart()
+        {
+            Thread t = new Thread(ReadTask);
+            t.Start((_db, _local_db));
+        }
+
+        static void ReadTask(Object dblist)
+        {
+            var (db, local_db) = ((ISqlSugarClient, ISqlSugarClient))dblist;
+            IConfiguration _configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();
+            string topic = _configuration.GetValue<string>("Topic");
+            List<string> patternlist = _configuration.GetValue<string>("PatternList").Split(",").ToList();
+            int product_startid = _configuration.GetValue<int>("ProductStartID");
+            ISqlSugarClient _db = (ISqlSugarClient)db;
+            ISqlSugarClient _local_db = (ISqlSugarClient)local_db;
+            while (true)
+            {
+                try
+                {
+                    int max_productid = _local_db.Ado.GetInt("select max(product_id) from lot2lot3_info");
+                    List<InitLot2Model> read_list = new List<InitLot2Model>();
+                    if (product_startid == 0)
+                    {
+                        read_list = _db.Queryable<InitLot2Model>().Where(x => x.id > max_productid).Where(x => (x.productno != null && x.station != null && x.pattern != null) && (x.result == "enOK" || x.result == "enNG")).OrderBy(x => x.id).Take(30).ToList();
+                    }
+                    else
+                    {
+                        read_list = _db.Queryable<InitLot2Model>().Where(x => x.id >= product_startid).Where(x => x.id > max_productid).Where(x => (x.productno != null && x.station != null && x.pattern != null) && (x.result == "enOK" || x.result == "enNG")).Take(60).OrderBy(x => x.id).Take(30).ToList();
+                    }
+                    if (read_list != null && read_list.Count > 0)
+                    {
+                        try
+                        {
+                            _local_db.Ado.BeginTran();
+                            foreach (var read_lot2 in read_list)
+                            {
+                                if (string.IsNullOrEmpty(read_lot2.productno) || string.IsNullOrEmpty(read_lot2.station) || string.IsNullOrEmpty(read_lot2.result))
+                                {
+                                    continue;
+                                }
+                                List<InitLot2DetailDto> lot2JsonList = new List<InitLot2DetailDto>();
+                                try
+                                {
+                                    //校验json格式
+                                    lot2JsonList = JsonConvert.DeserializeObject<List<InitLot2DetailDto>>(read_lot2.detail);
+                                }
+                                catch (Exception ex)
+                                {
+                                    LogerHelper.RecordLogTxt("ReadLot2Task,read_lot2Json有误" + ex.Message + "," + JsonConvert.SerializeObject(read_lot2));
+                                }
+                                List<Lot2Lot3Model> Lot2ModelList = _local_db.Queryable<Lot2Lot3Model>().Where(x => x.product_no == read_lot2.productno).ToList();
+                                if (Lot2ModelList == null || Lot2ModelList.Count == 0)
+                                {
+                                    Lot2Lot3Dto lot2Detail = new()
+                                    {
+                                        id = new GuidDto().Id,
+                                        slidesNumber = read_lot2.productno.Split('_')[0],
+                                        topic = topic,
+                                        createTime = read_lot2.created_at.ToString(),
+                                        result = read_lot2.result == "enOK" ? "OK" : "NG",
+                                        itemCheckDatas = new List<itemCheckData>()
+                                    };
+                                    itemCheckData lot2item = new itemCheckData()
+                                    {
+                                        station = read_lot2.station,
+                                        method = "1",
+                                        pattern = read_lot2.pattern,
+                                        result = read_lot2.result == "enOK" ? "OK" : "NG",
+                                        details = new List<detail>()
+                                    };
+                                    if (lot2JsonList != null && lot2JsonList.Count > 0)
+                                    {
+                                        foreach (var item in lot2JsonList)
+                                        {
+                                            string defectCode = "null";
+                                            string defectName = "null";
+                                            if (!string.IsNullOrEmpty(item.Classification.Trim()))
+                                            {
+                                                List<DefectModel> defectCodelist = _local_db.SqlQueryable<DefectModel>("SELECT * FROM public.defect_info where classification ~* '" + item.Classification + "'").ToList();
+                                                //List<DefectModel> defectCodelist = _local_db.Queryable<DefectModel>().Where(x => x.defect_name == item.Classification).ToList();
+                                                if (defectCodelist != null && defectCodelist.Count != 0)
+                                                {
+                                                    foreach (var defect_info in defectCodelist)
+                                                    {
+                                                        foreach (var defect_classification in defect_info.classification.Split(','))
+                                                        {
+                                                            if (item.Classification == defect_classification)
+                                                            {
+                                                                defectCode = defect_info.defect_code;
+                                                                defectName = defect_info.defect_name;
+                                                                break;
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                            lot2item.details.Add(new detail()
+                                            {
+                                                defectCode = defectCode,
+                                                defectName = defectName,
+                                                x = item.ContourRect_X,
+                                                y = item.ContourRect_Y,
+                                                width = item.ContourRect_Width,
+                                                height = item.ContourRect_Height,
+                                                area = item.ContourRect_Area
+                                            });
+                                        }
+                                    }
+                                    lot2Detail.itemCheckDatas.Add(lot2item);
+                                    Lot2Lot3Model lot2model = new()
+                                    {
+                                        lot_id = lot2Detail.id,
+                                        is_send = 2,
+                                        content = JsonConvert.SerializeObject(lot2Detail),
+                                        create_time = DateTime.Now,
+                                        product_no = read_lot2.productno,
+                                        product_id = read_lot2.id
+                                    };
+                                    _local_db.Insertable(lot2model).ExecuteCommand();
+                                }
+                                else
+                                {
+                                    if (Lot2ModelList[0].is_send == 2)
+                                    {
+                                        Lot2ModelList[0].create_time = DateTime.Now;
+                                        Lot2Lot3Dto lot2Detail = new Lot2Lot3Dto();
+                                        try
+                                        {
+                                            lot2Detail = JsonConvert.DeserializeObject<Lot2Lot3Dto>(Lot2ModelList[0].content);
+                                        }
+                                        catch (Exception ex)
+                                        {
+                                            LogerHelper.RecordLogTxt("ReadLot2Task,lot2DetailJson有误" + ex.Message + "," + JsonConvert.SerializeObject(Lot2ModelList[0].content));
+                                        }
+                                        //is_send:0、等待发送;1、已发送;2、等待补充信息;3、重复插入;
+                                        lot2Detail.createTime = read_lot2.created_at.ToString();
+                                        bool send_flag = true;
+                                        foreach (var item in patternlist)
+                                        {
+                                            bool flag = false;
+                                            if (item == read_lot2.pattern)
+                                            {
+                                                flag = true;
+                                            }
+                                            else
+                                            {
+                                                foreach (var item1 in lot2Detail.itemCheckDatas)
+                                                {
+                                                    if (item == item1.pattern)
+                                                    {
+                                                        flag = true;
+                                                        break;
+                                                    }
+                                                }
+                                            }
+                                            send_flag = send_flag & flag;
+                                        }
+                                        Lot2ModelList[0].is_send = send_flag ? 0 : 2;
+                                        Lot2ModelList[0].product_id = read_lot2.id;
+                                        if (read_lot2.result == "enNG")
+                                        {
+                                            lot2Detail.result = "NG";
+                                        }
+                                        itemCheckData lot2item = new itemCheckData()
+                                        {
+                                            station = read_lot2.station,
+                                            method = "1",
+                                            pattern = read_lot2.pattern,
+                                            result = read_lot2.result == "enOK" ? "OK" : "NG",
+                                            details = new List<detail>()
+                                        };
+                                        if (lot2JsonList != null && lot2JsonList.Count > 0)
+                                        {
+                                            foreach (var item in lot2JsonList)
+                                            {
+                                                string defectCode = "null";
+                                                string defectName = "null";
+                                                if (!string.IsNullOrEmpty(item.Classification.Trim()))
+                                                {
+                                                    List<DefectModel> defectCodelist = _local_db.SqlQueryable<DefectModel>("SELECT * FROM public.defect_info where classification ~* '" + item.Classification + "'").ToList();
+                                                    //List<DefectModel> defectCodelist = _local_db.Queryable<DefectModel>().Where(x => x.defect_name == item.Classification).ToList();
+                                                    if (defectCodelist != null && defectCodelist.Count != 0)
+                                                    {
+                                                        foreach (var defect_info in defectCodelist)
+                                                        {
+                                                            foreach (var defect_classification in defect_info.classification.Split(','))
+                                                            {
+                                                                if (item.Classification == defect_classification)
+                                                                {
+                                                                    defectCode = defect_info.defect_code;
+                                                                    defectName = defect_info.defect_name;
+                                                                    break;
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                                lot2item.details.Add(new detail()
+                                                {
+                                                    defectCode = defectCode,
+                                                    defectName = defectName,
+                                                    x = item.ContourRect_X,
+                                                    y = item.ContourRect_Y,
+                                                    width = item.ContourRect_Width,
+                                                    height = item.ContourRect_Height,
+                                                    area = item.ContourRect_Area
+                                                });
+                                            }
+                                        }
+                                        lot2Detail.itemCheckDatas.Add(lot2item);
+                                        Lot2ModelList[0].content = JsonConvert.SerializeObject(lot2Detail);
+                                        _local_db.Updateable<Lot2Lot3Model>(Lot2ModelList[0]).WhereColumns(s => s.id).ExecuteCommand();
+                                    }
+                                    else
+                                    {
+                                        Lot2Lot3Dto lot2Detail = new()
+                                        {
+                                            id = new GuidDto().Id,
+                                            slidesNumber = read_lot2.productno.Split('_')[0],
+                                            topic = topic,
+                                            createTime = read_lot2.created_at.ToString(),
+                                            result = read_lot2.result == "enOK" ? "OK" : "NG",
+                                            itemCheckDatas = new List<itemCheckData>()
+                                        };
+                                        itemCheckData lot2item = new itemCheckData()
+                                        {
+                                            station = read_lot2.station,
+                                            method = "1",
+                                            pattern = read_lot2.pattern,
+                                            result = read_lot2.result == "enOK" ? "OK" : "NG",
+                                            details = new List<detail>()
+                                        };
+                                        if (lot2JsonList != null && lot2JsonList.Count > 0)
+                                        {
+                                            foreach (var item in lot2JsonList)
+                                            {
+                                                string defectCode = "null";
+                                                string defectName = "null";
+                                                if (!string.IsNullOrEmpty(item.Classification.Trim()))
+                                                {
+                                                    List<DefectModel> defectCodelist = _local_db.SqlQueryable<DefectModel>("SELECT * FROM public.defect_info where classification ~* '" + item.Classification + "'").ToList();
+                                                    //List<DefectModel> defectCodelist = _local_db.Queryable<DefectModel>().Where(x => x.defect_name == item.Classification).ToList();
+                                                    if (defectCodelist != null && defectCodelist.Count != 0)
+                                                    {
+                                                        foreach (var defect_info in defectCodelist)
+                                                        {
+                                                            foreach (var defect_classification in defect_info.classification.Split(','))
+                                                            {
+                                                                if (item.Classification == defect_classification)
+                                                                {
+                                                                    defectCode = defect_info.defect_code;
+                                                                    defectName = defect_info.defect_name;
+                                                                    break;
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                                lot2item.details.Add(new detail()
+                                                {
+                                                    defectCode = defectCode,
+                                                    defectName = defectName,
+                                                    x = item.ContourRect_X,
+                                                    y = item.ContourRect_Y,
+                                                    width = item.ContourRect_Width,
+                                                    height = item.ContourRect_Height,
+                                                    area = item.ContourRect_Area
+                                                });
+                                            }
+                                        }
+                                        lot2Detail.itemCheckDatas.Add(lot2item);
+                                        Lot2Lot3Model lot2model = new()
+                                        {
+                                            lot_id = lot2Detail.id,
+                                            is_send = 3,
+                                            content = JsonConvert.SerializeObject(lot2Detail),
+                                            create_time = DateTime.Now,
+                                            product_no = read_lot2.productno,
+                                            product_id = read_lot2.id
+                                        };
+                                        _local_db.Insertable(lot2model).ExecuteCommand();
+                                    }
+                                }
+                                Thread.Sleep(500);
+                            }
+                            _local_db.Ado.CommitTran();
+                        }
+                        catch (Exception ex)
+                        {
+                            LogerHelper.RecordLogTxt("ReadLot2Task[1]," + ex.Message);
+                            _local_db.Ado.RollbackTran();
+                        }
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LogerHelper.RecordLogTxt("ReadLot2Task[2]," + ex.Message);
+                }
+                finally
+                {
+                    Thread.Sleep(5000);
+                }
+            }
+
+        }
+
+    }
+}

+ 73 - 0
EInk.Lot3/TaskThread/SendLot2Lot3Thread.cs

@@ -0,0 +1,73 @@
+using EInk.Dtos;
+using EInk.Models;
+using EInk.Tools;
+using Newtonsoft.Json;
+using SqlSugar;
+
+namespace EInk.TaskThread
+{
+    public class SendLot2Lot3Thread
+    {
+        private readonly ISqlSugarClient _db;
+
+        public SendLot2Lot3Thread(ISqlSugarClient db)
+        {
+            _db = db;
+        }
+
+        public void SendThreadStart()
+        {
+            Thread t = new Thread(SendTask);
+            t.Start(_db);
+        }
+
+        static void SendTask(Object db)
+        {
+            ISqlSugarClient _db = (ISqlSugarClient)db;
+            IConfiguration _configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();
+            while (true)
+            {
+                try
+                {
+                    List<Lot2Lot3Model> unsend_list = _db.Queryable<Lot2Lot3Model>().Where(x => x.is_send == 0).OrderBy(x => x.id).ToList();
+                    if (unsend_list != null && unsend_list.Count > 0)
+                    {
+                        foreach (var unsend in unsend_list)
+                        {
+                            var (rt_bl, rt_str) = HttpHelper.Post(_configuration.GetValue<string>("MesUrl")+ "/MesApi/LotAoiUpLoad", unsend.content, _configuration.GetValue<int>("MesUrlTime"));
+                            if (rt_bl && !string.IsNullOrEmpty(rt_str))
+                            {
+                                ResultDto rt = JsonConvert.DeserializeObject<ResultDto>(rt_str);
+                                if (rt.Code == CodeEnum.Ok)
+                                {
+                                    unsend.is_send = 1;
+                                    unsend.send_time = DateTime.Now;
+                                    _db.Updateable<Lot2Lot3Model>(unsend).WhereColumns(s => s.id).ExecuteCommand();
+                                }
+                                else
+                                {
+                                    LogerHelper.RecordLogTxt("SendLotTask,MesApi1," + rt.Code + "," + rt.Message + "," + unsend.content);
+                                } 
+                            }
+                            else
+                            {
+                                LogerHelper.RecordLogTxt("SendLotTask,MesApi2," + rt_bl.ToString() + "," + rt_str + "," + unsend.content);
+                            }
+                            Thread.Sleep(5000);
+                        }
+                    }
+                }
+                catch(Exception ex)
+                {
+                    LogerHelper.RecordLogTxt("SendLotTask," + ex.Message);
+                }
+                finally
+                {
+                    Thread.Sleep(5000);
+                }
+            }
+
+        }
+
+    }
+}

+ 50 - 0
EInk.Lot3/Tools/HttpHelper.cs

@@ -0,0 +1,50 @@
+namespace EInk.Tools
+{
+    public enum HttpResultCode
+    {
+        Ok,
+        Fail,
+        Error
+    }
+
+    public static class HttpHelper
+    {
+        public static (bool, string) Get(string url, int timeOut = 10)
+        {
+            try
+            {
+                using HttpClient client = new();
+                client.Timeout = TimeSpan.FromSeconds(1000 * timeOut);
+                HttpResponseMessage response = client.GetAsync(url).Result;
+                response.EnsureSuccessStatusCode();
+                string responseBody = response.Content.ReadAsStringAsync().Result;
+                return (true, responseBody);
+            }
+            catch (HttpRequestException ex)
+            {
+                return (false, ex.Message);
+            }
+        }
+        public static (bool, string) Post(string url, string inputData, int timeOut = 10)
+        {
+            try
+            {
+                using HttpClient client = new();
+                client.Timeout = TimeSpan.FromSeconds(1000 * timeOut);
+                HttpContent content = new StringContent(inputData, System.Text.Encoding.UTF8, "application/json");
+                HttpResponseMessage response = client.PostAsync(url, content).Result;
+                response.EnsureSuccessStatusCode();
+                string responseBody = response.Content.ReadAsStringAsync().Result;
+                return (true, responseBody);
+            }
+            catch (HttpRequestException ex)
+            {
+                return (false, ex.Message);
+            }
+        }
+        public static (bool, string) Post(string url, int timeOut = 10)
+        {
+            return Post(url, "", timeOut);
+        }
+    }
+}

+ 35 - 0
EInk.Lot3/Tools/LogerHelper.cs

@@ -0,0 +1,35 @@
+namespace EInk.Tools
+{
+    public static class LogerHelper
+    {
+        public static void RecordLogTxt(string message)
+        {
+            string strPath;
+            DateTime dt = DateTime.Now;
+            try
+            {
+                strPath = Directory.GetCurrentDirectory() + "\\Log";
+
+                if (Directory.Exists(strPath) == false)
+                {
+                    Directory.CreateDirectory(strPath);
+                }
+                strPath = strPath + "\\" + dt.ToString("yyyy") + "\\" + dt.ToString("MM");
+
+                if (Directory.Exists(strPath) == false)
+                {
+                    Directory.CreateDirectory(strPath);
+                }
+                strPath = strPath + "\\" + dt.Year.ToString() + "-" + dt.Month.ToString() + "-" + dt.Day.ToString() + ".txt";
+
+                StreamWriter FileWriter = new StreamWriter(strPath, true);
+                FileWriter.WriteLine("[" + dt.ToString("yyyy-MM-dd HH:mm:ss") + "]  " + message);
+                FileWriter.Close();
+            }
+            catch (Exception ex)
+            {
+                string str = ex.Message.ToString();
+            }
+        }
+    }
+}

+ 8 - 0
EInk.Lot3/appsettings.Development.json

@@ -0,0 +1,8 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  }
+}

+ 19 - 0
EInk.Lot3/appsettings.json

@@ -0,0 +1,19 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+  "LocalDbConnectionString": "Host=127.0.0.1;Port=5432;Database=localdb;Username=postgres;Password=eink;",
+  //"TargetDbConnectionString": "Host=127.0.0.1;Port=5432;Database=targetdb;Username=postgres;Password=eink;",
+  "TargetDbConnectionString": "Host=192.168.1.108;Port=5432;Database=eink;Username=postgres;Password=eink;",
+  "ProductStartID": 0,
+  "MesUrl": "http://eyzms.toc.eink.com:8088",
+  "MesUrlTime": 30,
+  "PatternList": "wht,dot",
+  "Topic": "LOT2AOIData#04#04-2AOI01",
+  "ReadLot2Thread": "off",
+  "SendLot2Lot3Thread": "off"
+}

+ 25 - 0
Eink.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.35013.160
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EInk.Lot2Lot3", "EInk.Lot3\EInk.Lot2Lot3.csproj", "{0C0961A1-494F-4FFC-82B9-1623AA58F174}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{0C0961A1-494F-4FFC-82B9-1623AA58F174}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{0C0961A1-494F-4FFC-82B9-1623AA58F174}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0C0961A1-494F-4FFC-82B9-1623AA58F174}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{0C0961A1-494F-4FFC-82B9-1623AA58F174}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {C3A48B75-27B5-46EA-A93F-92A909C63AB9}
+	EndGlobalSection
+EndGlobal