From 0043320cd4f68116585082cbf9115b43ed42a396 Mon Sep 17 00:00:00 2001 From: lyndonliu Date: Mon, 25 Mar 2024 14:40:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=80=83=E8=AF=95=E6=94=B6=E9=9B=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Exams/ExamManager.cs | 438 ++++++++++-------- .../Services/ExamAppService.cs | 2 +- .../AppAliyunBlobNameCalculator.cs | 13 + .../Dolphin.ExamPictureCut.Core.csproj | 12 +- .../DolphinExamPictureCutCoreModule.cs | 17 +- .../Domains/Basic/GroupBook.cs | 4 +- .../Domains/Basic/GroupBookPaperTemplate.cs | 4 +- .../Domains/Basic/Tenant.cs | 2 +- .../Domains/Biz/ExamSubjectSchoolStudent.cs | 12 + .../Domains/Biz/MarkingSettingSubjective.cs | 5 + .../Domains/Biz/MkExamResult.cs | 5 +- .../Domains/Biz/SubjectiveMarkingResult.cs | 10 +- .../Domains/IgnoreUnderLineAttribute.cs | 5 + .../Domains/MySqlConfigureExternalServices.cs | 57 +++ .../Domains/Quest/PenOfflineData.cs | 3 +- .../Exams/Dto/ExamStudentGatherEto.cs | 3 +- .../Exams/Dto/TemplateJsonModelDto.cs | 2 +- .../Options/AliyunOption.cs | 14 + ...Dolphin.ExamPictureCut.HttpApi.Host.csproj | 8 +- .../DolphinExamPictureCutHttpApiHostModule.cs | 46 +- .../appsettings.Development.json | 7 +- .../appsettings.json | 5 +- 22 files changed, 416 insertions(+), 258 deletions(-) create mode 100644 Dolphin.ExamPictureCut.Core/BlobStoring/AppAliyunBlobNameCalculator.cs create mode 100644 Dolphin.ExamPictureCut.Core/Domains/Biz/ExamSubjectSchoolStudent.cs create mode 100644 Dolphin.ExamPictureCut.Core/Domains/IgnoreUnderLineAttribute.cs create mode 100644 Dolphin.ExamPictureCut.Core/Domains/MySqlConfigureExternalServices.cs create mode 100644 Dolphin.ExamPictureCut.Core/Options/AliyunOption.cs diff --git a/Dolphin.ExamPictureCut.Application/Exams/ExamManager.cs b/Dolphin.ExamPictureCut.Application/Exams/ExamManager.cs index 3d28a28..e98d88a 100644 --- a/Dolphin.ExamPictureCut.Application/Exams/ExamManager.cs +++ b/Dolphin.ExamPictureCut.Application/Exams/ExamManager.cs @@ -1,10 +1,14 @@ +using Dolphin.ExamPictureCut.Constants; +using Dolphin.ExamPictureCut.Domains; using Dolphin.ExamPictureCut.Domains.Basic; using Dolphin.ExamPictureCut.Domains.Biz; using Dolphin.ExamPictureCut.Domains.Quest; using Dolphin.ExamPictureCut.Exams.Dto; using Dolphin.ExamPictureCut.Extensions; +using Dolphin.ExamPictureCut.Options; using Flurl.Http; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using NoFurion; using NoFurion.SqlSugar; @@ -12,6 +16,7 @@ using SkiaSharp; using SqlSugar; using Volo.Abp.BlobStoring; using Volo.Abp.Domain.Services; +using Volo.Abp.Uow; using Yitter.IdGenerator; namespace Dolphin.ExamPictureCut.Exams; @@ -19,7 +24,9 @@ namespace Dolphin.ExamPictureCut.Exams; public class ExamManager : DomainService, IExamManager { private readonly ISqlSugarClient Db; + private readonly ISqlSugarClient DbPenOffline; private readonly IBlobContainer _blobContainer; + private readonly AliyunOption _aliyunOption; private readonly SKPaint skPaint = new SKPaint { Color = SKColors.Black, @@ -28,20 +35,22 @@ public class ExamManager : DomainService, IExamManager StrokeWidth = 1, StrokeCap = SKStrokeCap.Round, }; - public ExamManager(ISqlSugarClient db, IBlobContainer blobContainer) + public ExamManager(ISqlSugarClient db, IBlobContainer blobContainer, IOptions aliyunOption) { Db = db; + DbPenOffline = (db as SqlSugarScope).GetConnection(DbConsts.penoffline); _blobContainer = blobContainer; + _aliyunOption = aliyunOption.Value; } + [UnitOfWork(false)] public async Task ExamStudentGather(ExamStudentGatherEto eto) { var penSerial = eto.StudentExamNum; Logger.LogInformation("{ExamSubjectId} {penSerial} 开始收集...", eto.ExamSubjectId, penSerial); var guid = GuidGenerator.Create().ToString("N"); - var templateIds = JsonConvert.DeserializeObject>(eto.TemplateId); - var templates = await Db.Queryable().Where(w => templateIds.Contains(w.Id)) + var templates = await Db.Queryable().Where(w => w.BookId == eto.BookId) .Select(s => new { s.Id, s.PaperId, s.PartId, s.PageIndex, s.ImgUrl, s.QueData, s.Order }).ToListAsync(); var paperInfo = templates.Select(s => { @@ -61,8 +70,9 @@ public class ExamManager : DomainService, IExamManager var paperIds = templates.Select(s => s.PaperId).ToList(); // 获取点阵数据 - var lattices = await Db.Queryable() - .Where(w => w.PenSerial == penSerial && paperIds.Contains(w.PageSerial) && w.logType == LogType.作业) + var timespan = (long)(eto.LastCollectTime - new DateTime(1970, 1, 1, 0, 0, 0)).TotalMilliseconds; + var lattices = await DbPenOffline.Queryable() + .Where(w => w.PenSerial == penSerial && paperIds.Contains(w.PageSerial) && w.logType == LogType.作业 && w.Time <= timespan) .Select(s => new PenOfflineData { PageSerial = s.PageSerial, @@ -71,23 +81,26 @@ public class ExamManager : DomainService, IExamManager Time = s.Time, strokeIndex = s.strokeIndex, }).ToListAsync(); + + var DbBiz = await GetTenantDb(eto.SchoolId); + await DbBiz.Updateable().SetColumns(s => s.CollectStatus == 2).Where(w => w.ExamSubjectSchoolId == eto.ExamSubjectSchoolId && w.StudentExamNum == penSerial).ExecuteCommandAsync(); + if (lattices.Count == 0) { Logger.LogInformation("{ExamSubjectId} {penSerial} 无点阵数据", eto.ExamSubjectId, penSerial); return; } - var DbBiz = await GetTenantDb(eto.SchoolId); var kgtDtls = await DbBiz.Queryable() .Where(w => w.ExamSubjectId == eto.ExamSubjectId) .Select(s => new MkExamResult { - Id = YitIdHelper.NextId(), StudentNo = penSerial, - ExamId = eto.ExamId, + ExamId = eto.ExamSubjectSchoolId, ExamSubjectId = eto.ExamSubjectId, QuestionNumber = s.QuestionNum, IsObjectiveQuestion = true, + QuestionValue = string.Empty, GroupNo = guid, }).ToListAsync(); @@ -104,63 +117,77 @@ public class ExamManager : DomainService, IExamManager return; } - var redisLockKey = "LockKey:" + eto.ExamSubjectId; + var redisLockKey = "GatherLockKey:" + eto.ExamSubjectId; var redisLock = await RedisHelper.GetAsync(redisLockKey); if (string.IsNullOrEmpty(redisLock)) { await RedisHelper.SetAsync(redisLockKey, "1"); - foreach (var paper in paperInfo) + try { - var imgStream = await paper.ImgUrl.GetStreamAsync(); - var bitmap = SKBitmap.Decode(imgStream); - - var nextPaper = paperInfo.FirstOrDefault(w => w.PartId == paper.PartId && w.PageIndex == paper.PageIndex + 1); - - foreach (var que in paper.QueData) + var dotPenOriginalImgs = new List(); + foreach (var paper in paperInfo) { - if (que.type != "2") continue; - if (que.options == null || que.options.Count == 0) continue; + var imgBytes = await paper.ImgUrl.GetBytesAsync(); + var bitmap = SKBitmap.Decode(imgBytes); - var area = que.options[0].AnswerArea; - var areaTop = area.pxTop; - var areaHeight = area.pxHeight; - var sourceRect = new SKRect(0, areaTop, bitmap.Width, areaTop + areaHeight); + var nextPaper = paperInfo.FirstOrDefault(w => w.PartId == paper.PartId && w.PageIndex == paper.PageIndex + 1); - var height = areaHeight; - - SKBitmap nextImgBitmap = null; - SKRect nextSourceRect = new(); - var queOnNextPaper = nextPaper?.QueData.FirstOrDefault(w => w.no == que.no); - if (queOnNextPaper?.options?.Count >= 1) + foreach (var que in paper.QueData) { - var nextImgStream = await nextPaper.ImgUrl.GetStreamAsync(); - nextImgBitmap = SKBitmap.Decode(nextImgStream); + if (que.type != "2") continue; + if (que.options == null || que.options.Count == 0) continue; - var nextArea = queOnNextPaper.options[0].AnswerArea; - var nextAreaTop = nextArea.pxTop; - var nextAreaHeight = nextArea.pxHeight; - height += nextAreaHeight; + var dotPenOriginalImg = $"que/{eto.ExamSubjectId}/{que.no}.jpg"; + if (dotPenOriginalImgs.Contains(dotPenOriginalImg)) continue; - nextSourceRect = new SKRect(0, nextAreaTop, bitmap.Width, nextAreaTop + nextAreaHeight); - } + var area = que.options[0].AnswerArea; + var areaTop = area.pxTop; + var areaHeight = area.pxHeight; + var sourceRect = new SKRect(0, areaTop, bitmap.Width, areaTop + areaHeight); - using (var newBitmap = new SKBitmap(bitmap.Width, height.SSWR(), SKColorType.Rgba8888, SKAlphaType.Premul)) - { - using (var canvas = new SKCanvas(newBitmap)) + var height = areaHeight; + + SKBitmap nextImgBitmap = null; + SKRect nextSourceRect = new(); + var queOnNextPaper = nextPaper?.QueData.FirstOrDefault(w => w.no == que.no); + if (queOnNextPaper?.options?.Count >= 1) { - canvas.DrawBitmap(bitmap, sourceRect, new SKRect(0, 0, bitmap.Width, areaHeight)); - if (nextImgBitmap != null) - canvas.DrawBitmap(nextImgBitmap, nextSourceRect, new SKRect(0, areaHeight, bitmap.Width, height)); + var nextImgBytes = await nextPaper.ImgUrl.GetBytesAsync(); + nextImgBitmap = SKBitmap.Decode(nextImgBytes); + + var nextArea = queOnNextPaper.options[0].AnswerArea; + var nextAreaTop = nextArea.pxTop; + var nextAreaHeight = nextArea.pxHeight; + height += nextAreaHeight; + + nextSourceRect = new SKRect(0, nextAreaTop, bitmap.Width, nextAreaTop + nextAreaHeight); } - var dtl = zgtSettingDtls.FirstOrDefault(w => w.QuestionNum == que.no); - dtl.DotPenOriginalImg = $"que/{eto.ExamSubjectId}/{paper.Sort}/{que.no}.png"; - await _blobContainer.SaveAsync(dtl.DotPenOriginalImg, newBitmap.Encode(SKEncodedImageFormat.Png, 100).ToArray(), true); + using (var newBitmap = new SKBitmap(bitmap.Width, height.SSWR(), SKColorType.Rgba8888, SKAlphaType.Premul)) + { + using (var canvas = new SKCanvas(newBitmap)) + { + canvas.DrawBitmap(bitmap, sourceRect, new SKRect(0, 0, bitmap.Width, areaHeight)); + if (nextImgBitmap != null) + canvas.DrawBitmap(nextImgBitmap, nextSourceRect, new SKRect(0, areaHeight, bitmap.Width, height)); + } + + var dtl = zgtSettingDtls.FirstOrDefault(w => w.QuestionNum == que.no); + dtl.DotPenOriginalImg = dotPenOriginalImg; + await _blobContainer.SaveAsync(dtl.DotPenOriginalImg, newBitmap.Encode(SKEncodedImageFormat.Jpeg, 100).ToArray(), true); + dotPenOriginalImgs.Add(dotPenOriginalImg); + } } } + await DbBiz.Updateable(zgtSettingDtls).UpdateColumns(s => s.DotPenOriginalImg).ExecuteCommandAsync(); + await RedisHelper.DelAsync(redisLockKey); + } + catch (Exception ex) + { + Logger.LogError("{ExamSubjectId} {penSerial} 收集失败! 原题切割异常: {error}", eto.ExamSubjectId, penSerial, ex); + await RedisHelper.DelAsync(redisLockKey); + throw; } - await Db.Updateable(zgtSettingDtls).UpdateColumns(s => s.DotPenOriginalImg).Where(w => w.DotPenOriginalImg.IsNotNullOrEmpty()).ExecuteCommandAsync(); - await RedisHelper.SetAsync(redisLockKey, "0"); } else { @@ -173,184 +200,220 @@ public class ExamManager : DomainService, IExamManager } } - var zgtDtls = zgtSettingDtls.Select(s => new SubjectiveMarkingResult + // 锁处理 + var studentRedisLockKey = "LockKey:" + eto.ExamSubjectId + penSerial; + var studentRedisLock = await RedisHelper.GetAsync(studentRedisLockKey); + if (studentRedisLock == "1") { - Id = YitIdHelper.NextId(), - ExamSubjectId = eto.ExamSubjectId, - ExamSubjectSchoolId = eto.ExamSubjectSchoolId, - StudentExamNum = penSerial, - QuestionNum = s.QuestionNum, - TotalScore = s.Score, - SubQuestionCount = s.SubQuestionCount, - SubQuestionDetail = s.SubQuestionDetail, - GroupNo = guid, - BigQuestionNum = s.BigQuestionNum, - IsExcess = s.IsExcess, - }).ToList(); + Logger.LogInformation("{ExamSubjectId} {penSerial} 正在收集中,此次收集跳过", eto.ExamSubjectId, penSerial); + return; + } + await RedisHelper.SetAsync(studentRedisLockKey, "1"); - var kgt = new List>(); - var zgt = new List>(); // 纸张Id, 题号, 是否跨页 - var pageSerials = new List(); // 需要计算的页 - foreach (var paper in paperInfo) + try { - var paperLatts = lattices.Where(w => w.PageSerial == paper.PaperId).ToList(); - foreach (var que in paper.QueData) + var zgtDtls = zgtSettingDtls.Select(s => new SubjectiveMarkingResult { - if (que.type == "1") // 客观题 + Id = YitIdHelper.NextId(), + ExamSubjectId = eto.ExamSubjectId, + ExamSubjectSchoolId = eto.ExamSubjectSchoolId, + StudentExamNum = penSerial, + QuestionNum = s.QuestionNum, + TotalScore = s.Score, + SubQuestionCount = s.SubQuestionCount, + SubQuestionDetail = s.SubQuestionDetail, + StudentAnswer = $"[\"{_aliyunOption.Host}/{s.DotPenOriginalImg}\"]", + GroupNo = guid, + BigQuestionNum = s.BigQuestionNum, + IsExcess = s.IsExcess, + }).ToList(); + + var kgt = new List>(); + var zgt = new List>(); // 纸张Id, 题号, 是否跨页 + var pageSerials = new List(); // 需要计算的页 + foreach (var paper in paperInfo) + { + var paperLatts = lattices.Where(w => w.PageSerial == paper.PaperId).ToList(); + foreach (var que in paper.QueData) { - if (que.options.Any() && que.options.Any(opt => paperLatts.Any(s => RectExt.IsRectContainsLattice(opt.AnswerArea, s)))) + if (que.type == "1") // 客观题 { - pageSerials.Add(paper.PaperId); - kgt.Add(new(paper.PaperId, que.no)); - } - } - else if (que.type == "2") // 主观题 - { - if (que.options.Any() && paperLatts.Any(s => RectExt.IsRectContainsLattice(que.options[0].AnswerArea, s))) - { - pageSerials.Add(paper.PaperId); - var ky = false; - var quePaperId = paper.PaperId; - var queOthPaper = paperInfo.FirstOrDefault(w => w.PartId == paper.PartId && w.PageIndex != paper.PageIndex && w.QueData.Any(s => s.no == que.no)); - if (queOthPaper != null) + if (que.options.Any() && que.options.Any(opt => paperLatts.Any(s => RectExt.IsRectContainsLattice(opt.AnswerArea, s)))) { - ky = true; - if (paper.PageIndex > queOthPaper.PageIndex) - { - pageSerials.Add(queOthPaper.PaperId); - quePaperId = queOthPaper.PaperId; - } + pageSerials.Add(paper.PaperId); + kgt.Add(new(paper.PaperId, que.no)); + } + } + else if (que.type == "2") // 主观题 + { + if (que.options.Any() && paperLatts.Any(s => RectExt.IsRectContainsLattice(que.options[0].AnswerArea, s))) + { + pageSerials.Add(paper.PaperId); + var ky = false; + var quePaperId = paper.PaperId; + var queOthPaper = paperInfo.FirstOrDefault(w => w.PartId == paper.PartId && w.PageIndex != paper.PageIndex && w.QueData.Any(s => s.no == que.no)); + if (queOthPaper != null) + { + ky = true; + if (paper.PageIndex > queOthPaper.PageIndex) + { + pageSerials.Add(queOthPaper.PaperId); + quePaperId = queOthPaper.PaperId; + } + } + if (!zgt.Any(s => s.Item1 == quePaperId && s.Item2 == que.no)) + zgt.Add(new(quePaperId, que.no, ky)); } - if (!zgt.Any(s => s.Item1 == quePaperId && s.Item2 == que.no)) - zgt.Add(new(quePaperId, que.no, ky)); } } } - } - var kgtPapers = kgt.GroupBy(s => s.Item1).Select(s => s.Key).ToList(); // 客观题处理 - foreach (var paperId in kgtPapers) - { - var paper = paperInfo.FirstOrDefault(w => w.PaperId == paperId); - var paperLatts = lattices.Where(w => w.PageSerial == paperId).ToList(); - - var queNos = kgt.Where(w => w.Item1 == paperId).Select(s => s.Item2).ToList(); - foreach (var queNo in queNos) + foreach (var _kgtDtl in kgtDtls) { - var queInfo = paper.QueData.FirstOrDefault(w => w.no == queNo); - var queLatts = paperLatts.Where(w => queInfo.options.Any(s => RectExt.IsRectContainsLattice(s.AnswerArea, w)) - || queInfo.resetPoint.Any(s => RectExt.IsRectContainsLattice(s, w))).ToList(); + _kgtDtl.Id = YitIdHelper.NextId(); + } + var kgtPapers = kgt.GroupBy(s => s.Item1).Select(s => s.Key).ToList(); // 客观题处理 + foreach (var paperId in kgtPapers) + { + var paper = paperInfo.FirstOrDefault(w => w.PaperId == paperId); + var paperLatts = lattices.Where(w => w.PageSerial == paperId).ToList(); - long? resetTime = null; - if (queInfo.resetPoint.Any()) + var queNos = kgt.Where(w => w.Item1 == paperId).Select(s => s.Item2).ToList(); + foreach (var queNo in queNos) { - var resetLatts = queLatts.Where(w => RectExt.IsRectContainsLattice(queInfo.resetPoint[0], w)).ToList(); - resetTime = resetLatts.Any() ? resetLatts.Max(w => w.Time) : null; - } + var queInfo = paper.QueData.FirstOrDefault(w => w.no == queNo); + var queLatts = paperLatts.Where(w => queInfo.options.Any(s => RectExt.IsRectContainsLattice(s.AnswerArea, w)) + || queInfo.resetPoint.Any(s => RectExt.IsRectContainsLattice(s, w))).ToList(); - var stuAnswer = ""; - // 遍历每个选项 - foreach (var option in queInfo.options) - { - if (!option.point.Any()) continue; // 该选项无坐标数据 - var choose = queLatts.WhereIF(resetTime.HasValue, w => w.Time > resetTime).Where(a => RectExt.IsRectContainsLattice(option.point[0], a)); - if (!choose.Any()) continue; - stuAnswer += option.option; - } + long? resetTime = null; + if (queInfo.resetPoint.Any()) + { + var resetLatts = queLatts.Where(w => RectExt.IsRectContainsLattice(queInfo.resetPoint[0], w)).ToList(); + resetTime = resetLatts.Any() ? resetLatts.Max(w => w.Time) : null; + } - var dtl = kgtDtls.FirstOrDefault(w => w.QuestionNumber == queNo); - if (dtl != null) - { - dtl.QuestionValue = stuAnswer; + var stuAnswer = ""; + // 遍历每个选项 + foreach (var option in queInfo.options) + { + if (!option.point.Any()) continue; // 该选项无坐标数据 + var choose = queLatts.WhereIF(resetTime.HasValue, w => w.Time > resetTime).Where(a => RectExt.IsRectContainsLattice(option.point[0], a)); + if (!choose.Any()) continue; + stuAnswer += option.option; + } + + var dtl = kgtDtls.FirstOrDefault(w => w.QuestionNumber == queNo); + if (dtl != null) + { + dtl.QuestionValue = stuAnswer; + } } } - } - var zgtPapers = zgt.GroupBy(s => s.Item1).Select(s => s.Key).ToList(); // 主观题处理 - foreach (var paperId in zgtPapers) - { - var paper = paperInfo.FirstOrDefault(w => w.PaperId == paperId); - var paperJobPage = templateIds.FindIndex(s => s == paper.TemplateId) + 1; - var paperLatts = lattices.Where(w => w.PageSerial == paperId).ToList(); - - var ques = zgt.Where(w => w.Item1 == paperId).ToList(); - foreach (var que in ques) + var zgtPapers = zgt.GroupBy(s => s.Item1).Select(s => s.Key).ToList(); // 主观题处理 + foreach (var paperId in zgtPapers) { - var queNo = que.Item2; - var queInfo = paper.QueData.FirstOrDefault(w => w.no == queNo); - var answerArea = queInfo.options[0].AnswerArea; - var queLatts = paperLatts.Where(w => RectExt.IsRectContainsLattice(answerArea, w)) - .Select(s => new SubjectiveLatt() - { - Stroke = s.strokeIndex, - X = s.CX.AUToPX(), - Y = s.CY.AUToPX() - answerArea.pxTop, - Time = s.Time, - }).ToList(); + var paper = paperInfo.FirstOrDefault(w => w.PaperId == paperId); + var paperLatts = lattices.Where(w => w.PageSerial == paperId).ToList(); - if (que.Item3) // 跨页 + var ques = zgt.Where(w => w.Item1 == paperId).ToList(); + foreach (var que in ques) { - var queOnNextPaper = paperInfo.FirstOrDefault(w => w.PartId == paper.PartId && w.PageIndex == paper.PageIndex + 1 && w.QueData.Any(s => s.no == queNo)); - var queInfoOnNextPaper = queOnNextPaper.QueData.FirstOrDefault(w => w.no == queNo); - var answerAreaOnNextPaper = queInfoOnNextPaper.options[0].AnswerArea; - var queLattsOnNextPaper = lattices.Where(w => w.PageSerial == queOnNextPaper.PaperId && RectExt.IsRectContainsLattice(answerAreaOnNextPaper, w)) + var queNo = que.Item2; + var queInfo = paper.QueData.FirstOrDefault(w => w.no == queNo); + var answerArea = queInfo.options[0].AnswerArea; + var queLatts = paperLatts.Where(w => RectExt.IsRectContainsLattice(answerArea, w)) .Select(s => new SubjectiveLatt() { Stroke = s.strokeIndex, X = s.CX.AUToPX(), - Y = s.CY.AUToPX() + answerArea.pxHeight - answerAreaOnNextPaper.pxTop, + Y = s.CY.AUToPX() - answerArea.pxTop, Time = s.Time, }).ToList(); - queLatts.AddRange(queLattsOnNextPaper); - } - var stuAnswer = ""; - - var queImgUrl = zgtSettingDtls.FirstOrDefault(w => w.QuestionNum == queNo).DotPenOriginalImg; - var imgStream = await _blobContainer.GetAsync(queImgUrl); - var queBitmap = SKBitmap.Decode(imgStream); - - using (var canvas = new SKCanvas(queBitmap)) - { - // 一笔一笔的画上去 - var strokeIndexs = queLatts.GroupBy(g => g.Stroke).Select(s => s.Key).ToList(); - foreach (var stroke in strokeIndexs) + if (que.Item3) // 跨页 { - var points = queLatts.Where(w => w.Stroke == stroke).OrderBy(s => s.Time).Select(s => new SKPoint(s.X, s.Y)).ToArray(); - var skPointMode = SKPointMode.Polygon; - if (points.Length == 1) - skPointMode = SKPointMode.Points; - else if (points.Length == 2) - skPointMode = SKPointMode.Lines; - - canvas.DrawPoints(skPointMode, points, skPaint); + var queOnNextPaper = paperInfo.FirstOrDefault(w => w.PartId == paper.PartId && w.PageIndex == paper.PageIndex + 1 && w.QueData.Any(s => s.no == queNo)); + var queInfoOnNextPaper = queOnNextPaper.QueData.FirstOrDefault(w => w.no == queNo); + var answerAreaOnNextPaper = queInfoOnNextPaper.options[0].AnswerArea; + var queLattsOnNextPaper = lattices.Where(w => w.PageSerial == queOnNextPaper.PaperId && RectExt.IsRectContainsLattice(answerAreaOnNextPaper, w)) + .Select(s => new SubjectiveLatt() + { + Stroke = s.strokeIndex, + X = s.CX.AUToPX(), + Y = s.CY.AUToPX() + answerArea.pxHeight - answerAreaOnNextPaper.pxTop, + Time = s.Time, + }).ToList(); + queLatts.AddRange(queLattsOnNextPaper); } - stuAnswer = $"queAnswer/{eto.ExamSubjectId}/{penSerial}/{paper.Sort}/{queNo}.png"; - await _blobContainer.SaveAsync(stuAnswer, queBitmap.Encode(SKEncodedImageFormat.Png, 100).ToArray(), true); - } - var dtl = zgtDtls.FirstOrDefault(w => w.QuestionNum == queNo); - if (dtl != null) - { - dtl.StudentAnswer = stuAnswer; + var stuAnswer = ""; + + var queImgUrl = zgtSettingDtls.FirstOrDefault(w => w.QuestionNum == queNo).DotPenOriginalImg; + var imgStream = await _blobContainer.GetAsync(queImgUrl); + var queBitmap = SKBitmap.Decode(imgStream); + + using (var canvas = new SKCanvas(queBitmap)) + { + // 一笔一笔的画上去 + var strokeIndexs = queLatts.GroupBy(g => g.Stroke).Select(s => s.Key).ToList(); + foreach (var stroke in strokeIndexs) + { + var points = queLatts.Where(w => w.Stroke == stroke).OrderBy(s => s.Time).Select(s => new SKPoint(s.X, s.Y)).ToArray(); + var skPointMode = SKPointMode.Polygon; + if (points.Length == 1) + skPointMode = SKPointMode.Points; + else if (points.Length == 2) + skPointMode = SKPointMode.Lines; + + canvas.DrawPoints(skPointMode, points, skPaint); + } + stuAnswer = $"stu-answer/{eto.ExamSubjectId}/{penSerial}/{queNo}.jpg"; + await _blobContainer.SaveAsync(stuAnswer, queBitmap.Encode(SKEncodedImageFormat.Jpeg, 100).ToArray(), true); + } + + var dtl = zgtDtls.FirstOrDefault(w => w.QuestionNum == queNo); + if (dtl != null) + { + dtl.StudentAnswer = $"[\"{_aliyunOption.Host}/{stuAnswer}\"]"; + } } } - } - await DbBiz.UseTranAsync(async () => + try + { + await DbBiz.BeginTranAsync(); + + // 删除 + await DbBiz.Deleteable().Where(w => w.ExamSubjectId == eto.ExamSubjectId && w.StudentNo == penSerial).ExecuteCommandAsync(); + await DbBiz.Updateable() + .SetColumns(s => new SubjectiveMarkingResult { IsDeleted = true, UpdateDate = Clock.Now }) + .Where(w => w.ExamSubjectId == eto.ExamSubjectId && w.StudentExamNum == penSerial && w.IsDeleted == false) + .ExecuteCommandAsync(); + // 新增 + await DbBiz.Insertable(kgtDtls).ExecuteCommandAsync(); + await DbBiz.Insertable(zgtDtls).ExecuteCommandAsync(); + + await DbBiz.CommitTranAsync(); + Logger.LogInformation("{ExamSubjectId} {penSerial} 收集成功", eto.ExamSubjectId, penSerial); + } + catch (Exception saveEx) + { + await DbBiz.RollbackTranAsync(); + Logger.LogError("{ExamSubjectId} {penSerial} 收集失败! 数据存储异常: {error}", eto.ExamSubjectId, penSerial, saveEx); + } + } + catch (Exception ex) { - // 删除 - await DbBiz.Deleteable().Where(w => w.ExamSubjectId == eto.ExamSubjectId && w.StudentNo == penSerial).ExecuteCommandAsync(); - await DbBiz.Updateable() - .SetColumns(s => s.IsDeleted == true) - .Where(w => w.ExamSubjectId == eto.ExamSubjectId && w.StudentExamNum == penSerial && w.IsDeleted == false) - .ExecuteCommandAsync(); - // 新增 - await DbBiz.Insertable(kgtDtls).ExecuteCommandAsync(); - await DbBiz.Insertable(zgtDtls).ExecuteCommandAsync(); - }); + Logger.LogError("{ExamSubjectId} {penSerial} 收集失败! {error}", eto.ExamSubjectId, penSerial, ex); + } + finally + { + await RedisHelper.DelAsync(studentRedisLockKey); + } } + [AutoTran] public async Task ExamAnnotate(ExamAnnotateEto eto) { } @@ -360,13 +423,12 @@ public class ExamManager : DomainService, IExamManager var tenant = await Db.Queryable().Where(w => w.TenantCode == tenantCode).FirstAsync(); ExceptionExt.ThrowIf(tenant == null, $"{nameof(tenant)} is null with ${tenantCode}"); - var config = new SqlSugarConfig(); return new SqlSugarClient(new ConnectionConfig() { DbType = DbType.MySql, ConnectionString = tenant.ConnectionString, IsAutoCloseConnection = true, - ConfigureExternalServices = config.ExtService, + ConfigureExternalServices = MySqlConfigureExternalServices.MySqlExtService, }); } } diff --git a/Dolphin.ExamPictureCut.Application/Services/ExamAppService.cs b/Dolphin.ExamPictureCut.Application/Services/ExamAppService.cs index 78950bd..cf7c9e6 100644 --- a/Dolphin.ExamPictureCut.Application/Services/ExamAppService.cs +++ b/Dolphin.ExamPictureCut.Application/Services/ExamAppService.cs @@ -12,6 +12,6 @@ public class ExamAppService : DolphinAppService public async Task Test() { - await _examManager.ExamStudentGather(new() { SchoolId = 1, StudentExamNum = "BP2-3G3-07K-C0", TemplateId = "[]" }); + await _examManager.ExamStudentGather(new() { SchoolId = 1, StudentExamNum = "BP2-3G3-07K-BZ", BookId = 528102717276229, ExamSubjectSchoolId = 528066671910982, ExamSubjectId = 528066655817797, LastCollectTime = DateTime.Now }); } } diff --git a/Dolphin.ExamPictureCut.Core/BlobStoring/AppAliyunBlobNameCalculator.cs b/Dolphin.ExamPictureCut.Core/BlobStoring/AppAliyunBlobNameCalculator.cs new file mode 100644 index 0000000..6e52b0a --- /dev/null +++ b/Dolphin.ExamPictureCut.Core/BlobStoring/AppAliyunBlobNameCalculator.cs @@ -0,0 +1,13 @@ +using Volo.Abp.BlobStoring; +using Volo.Abp.BlobStoring.Aliyun; +using Volo.Abp.DependencyInjection; + +namespace Dolphin.ExamPictureCut.BlobStoring; + +public class AppAliyunBlobNameCalculator : IAliyunBlobNameCalculator, ITransientDependency +{ + public virtual string Calculate(BlobProviderArgs args) + { + return args.BlobName; + } +} diff --git a/Dolphin.ExamPictureCut.Core/Dolphin.ExamPictureCut.Core.csproj b/Dolphin.ExamPictureCut.Core/Dolphin.ExamPictureCut.Core.csproj index 9649f0a..5b34eb6 100644 --- a/Dolphin.ExamPictureCut.Core/Dolphin.ExamPictureCut.Core.csproj +++ b/Dolphin.ExamPictureCut.Core/Dolphin.ExamPictureCut.Core.csproj @@ -17,16 +17,12 @@ - - - - + + + + - - - - diff --git a/Dolphin.ExamPictureCut.Core/DolphinExamPictureCutCoreModule.cs b/Dolphin.ExamPictureCut.Core/DolphinExamPictureCutCoreModule.cs index f9641fe..f5605f0 100644 --- a/Dolphin.ExamPictureCut.Core/DolphinExamPictureCutCoreModule.cs +++ b/Dolphin.ExamPictureCut.Core/DolphinExamPictureCutCoreModule.cs @@ -1,4 +1,8 @@ using Dolphin.ExamPictureCut.Localization; +using Dolphin.ExamPictureCut.Options; +using Mapster; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using NoFurion.Extensions; using Volo.Abp.Application; using Volo.Abp.BlobStoring; @@ -22,11 +26,22 @@ public class DolphinExamPictureCutCoreModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { + var Configuration = context.Services.GetConfiguration(); + var aliyunOption = Configuration.GetSection("Aliyun").Get(); + Configure(options => aliyunOption.Adapt(options)); Configure(options => { options.Containers.ConfigureDefault(container => { - container.UseAliyun(aliyun => { }); + container.UseAliyun(aliyun => + { + aliyun.AccessKeyId = aliyunOption.AccessKeyId; + aliyun.AccessKeySecret = aliyunOption.AccessKeySecret; + aliyun.Endpoint = aliyunOption.Endpoint; + aliyun.RegionId = aliyunOption.RegionId; + aliyun.ContainerName = aliyunOption.ContainerName; + + }); }); }); diff --git a/Dolphin.ExamPictureCut.Core/Domains/Basic/GroupBook.cs b/Dolphin.ExamPictureCut.Core/Domains/Basic/GroupBook.cs index 0678aa9..a22a043 100644 --- a/Dolphin.ExamPictureCut.Core/Domains/Basic/GroupBook.cs +++ b/Dolphin.ExamPictureCut.Core/Domains/Basic/GroupBook.cs @@ -7,8 +7,8 @@ namespace Dolphin.ExamPictureCut.Domains.Basic; [Table(nameof(GroupBook)), Tenant(DbConsts.marking_basic)] public class GroupBook { - [SugarColumn(IsPrimaryKey = true, ColumnName = "id", Length = 32)] - public string Id { get; set; } + [SugarColumn(IsPrimaryKey = true, ColumnName = "id")] + public long Id { get; set; } [SugarColumn(ColumnName = "book_id")] public long BookId { get; set; } diff --git a/Dolphin.ExamPictureCut.Core/Domains/Basic/GroupBookPaperTemplate.cs b/Dolphin.ExamPictureCut.Core/Domains/Basic/GroupBookPaperTemplate.cs index 977b3eb..73f33d2 100644 --- a/Dolphin.ExamPictureCut.Core/Domains/Basic/GroupBookPaperTemplate.cs +++ b/Dolphin.ExamPictureCut.Core/Domains/Basic/GroupBookPaperTemplate.cs @@ -7,8 +7,8 @@ namespace Dolphin.ExamPictureCut.Domains.Basic; [Table(nameof(GroupBookPaperTemplate)), Tenant(DbConsts.marking_basic)] public class GroupBookPaperTemplate { - [SugarColumn(IsPrimaryKey = true, ColumnName = "id", Length = 32)] - public string Id { get; set; } + [SugarColumn(IsPrimaryKey = true, ColumnName = "id")] + public long Id { get; set; } [SugarColumn(ColumnName = "book_id")] public long BookId { get; set; } diff --git a/Dolphin.ExamPictureCut.Core/Domains/Basic/Tenant.cs b/Dolphin.ExamPictureCut.Core/Domains/Basic/Tenant.cs index 40c621f..1a81940 100644 --- a/Dolphin.ExamPictureCut.Core/Domains/Basic/Tenant.cs +++ b/Dolphin.ExamPictureCut.Core/Domains/Basic/Tenant.cs @@ -19,7 +19,7 @@ public class Tenant : ISoftDelete public string TenantName { get; set; } [NotMapped] - public string ConnectionString => $"Server={IpAddr};Port={Port};Database={Database};Uid={Dbuser};Pwd={Password};"; + public string ConnectionString => $"Server={IpAddr};Port={Port};Database={Database};Uid={Dbuser};Pwd={Password};CharSet=utf8mb4;AllowLoadLocalInfile=true;AllowUserVariables=True;ConvertZeroDatetime=true;"; public bool IsEnable { get; set; } public bool IsDeleted { get; set; } diff --git a/Dolphin.ExamPictureCut.Core/Domains/Biz/ExamSubjectSchoolStudent.cs b/Dolphin.ExamPictureCut.Core/Domains/Biz/ExamSubjectSchoolStudent.cs new file mode 100644 index 0000000..c82eb8c --- /dev/null +++ b/Dolphin.ExamPictureCut.Core/Domains/Biz/ExamSubjectSchoolStudent.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace Dolphin.ExamPictureCut.Domains.Biz; + +[Table(nameof(ExamSubjectSchoolStudent))] +public class ExamSubjectSchoolStudent +{ + public long Id { get; set; } + public long ExamSubjectSchoolId { get; set; } + public string StudentExamNum { get; set; } + public int CollectStatus { get; set; } +} diff --git a/Dolphin.ExamPictureCut.Core/Domains/Biz/MarkingSettingSubjective.cs b/Dolphin.ExamPictureCut.Core/Domains/Biz/MarkingSettingSubjective.cs index 56290bf..3d7a2dd 100644 --- a/Dolphin.ExamPictureCut.Core/Domains/Biz/MarkingSettingSubjective.cs +++ b/Dolphin.ExamPictureCut.Core/Domains/Biz/MarkingSettingSubjective.cs @@ -1,7 +1,12 @@ +using SqlSugar; +using System.ComponentModel.DataAnnotations.Schema; + namespace Dolphin.ExamPictureCut.Domains.Biz; +[Table(nameof(MarkingSettingSubjective))] public class MarkingSettingSubjective { + [SugarColumn(IsPrimaryKey = true)] public long Id { get; set; } public long ExamSubjectId { get; set; } public string QuestionNum { get; set; } diff --git a/Dolphin.ExamPictureCut.Core/Domains/Biz/MkExamResult.cs b/Dolphin.ExamPictureCut.Core/Domains/Biz/MkExamResult.cs index 013aea0..2e27460 100644 --- a/Dolphin.ExamPictureCut.Core/Domains/Biz/MkExamResult.cs +++ b/Dolphin.ExamPictureCut.Core/Domains/Biz/MkExamResult.cs @@ -1,8 +1,9 @@ +using Dolphin.ExamPictureCut.Options; using SqlSugar; namespace Dolphin.ExamPictureCut.Domains.Biz; -[SugarTable("MK_ExamResult")] +[SugarTable("MK_ExamResult"), IgnoreUnderLine] public class MkExamResult { [SugarColumn(IsPrimaryKey = true, ColumnName = "ID_bigint")] @@ -14,6 +15,7 @@ public class MkExamResult [SugarColumn(ColumnName = "ExamId_bigint")] public long ExamId { get; set; } + [SugarColumn(ColumnName = "ExamSubjectId")] public long ExamSubjectId { get; set; } [SugarColumn(ColumnName = "QuestionNumber_int")] @@ -34,5 +36,6 @@ public class MkExamResult [SugarColumn(ColumnName = "GroupNo_nvarchar")] public string GroupNo { get; set; } + [SugarColumn(ColumnName = "IsSync")] public bool IsSync { get; set; } } diff --git a/Dolphin.ExamPictureCut.Core/Domains/Biz/SubjectiveMarkingResult.cs b/Dolphin.ExamPictureCut.Core/Domains/Biz/SubjectiveMarkingResult.cs index a5f4b27..e7653d4 100644 --- a/Dolphin.ExamPictureCut.Core/Domains/Biz/SubjectiveMarkingResult.cs +++ b/Dolphin.ExamPictureCut.Core/Domains/Biz/SubjectiveMarkingResult.cs @@ -1,7 +1,10 @@ +using SqlSugar; +using System.ComponentModel.DataAnnotations.Schema; using Volo.Abp; namespace Dolphin.ExamPictureCut.Domains.Biz; +[Table(nameof(SubjectiveMarkingResult))] public class SubjectiveMarkingResult : ISoftDelete { public long Id { get; set; } @@ -17,10 +20,15 @@ public class SubjectiveMarkingResult : ISoftDelete public string GroupNo { get; set; } public bool IsAssign { get; set; } public bool IsRating { get; set; } - public string CommentImgUrl { get; set; } = "[]"; + public string CommentImageUrl { get; set; } = "[]"; public string BigQuestionNum { get; set; } public bool IsExcess { get; set; } + public bool IsDeleted { get; set; } + + [SugarColumn(InsertServerTime = true)] public DateTime CreateDate { get; set; } + + [SugarColumn(InsertServerTime = true, UpdateServerTime = true)] public DateTime UpdateDate { get; set; } } diff --git a/Dolphin.ExamPictureCut.Core/Domains/IgnoreUnderLineAttribute.cs b/Dolphin.ExamPictureCut.Core/Domains/IgnoreUnderLineAttribute.cs new file mode 100644 index 0000000..349a109 --- /dev/null +++ b/Dolphin.ExamPictureCut.Core/Domains/IgnoreUnderLineAttribute.cs @@ -0,0 +1,5 @@ +namespace Dolphin.ExamPictureCut.Domains; + +public class IgnoreUnderLineAttribute : Attribute +{ +} diff --git a/Dolphin.ExamPictureCut.Core/Domains/MySqlConfigureExternalServices.cs b/Dolphin.ExamPictureCut.Core/Domains/MySqlConfigureExternalServices.cs new file mode 100644 index 0000000..221cf85 --- /dev/null +++ b/Dolphin.ExamPictureCut.Core/Domains/MySqlConfigureExternalServices.cs @@ -0,0 +1,57 @@ +using NoFurion; +using SqlSugar; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Reflection; + +namespace Dolphin.ExamPictureCut.Domains; + +public class MySqlConfigureExternalServices +{ + public static ConfigureExternalServices MySqlExtService = new ConfigureExternalServices + { + EntityService = delegate (PropertyInfo prop, EntityColumnInfo col) + { + if (prop.GetCustomAttribute() != null) + { + col.IsIgnore = true; + } + + if (!col.IsPrimarykey) + { + if (prop.GetCustomAttribute() != null) + { + return; + } + + if (new NullabilityInfoContext().Create(prop).WriteState == NullabilityState.Nullable || prop.PropertyType == typeof(string)) + { + col.IsNullable = true; + } + } + + var sugarColumn = prop.GetCustomAttribute(); + if (sugarColumn != null && sugarColumn.ColumnName.IsNotNullOrEmpty()) + { + return; + } + if (prop.DeclaringType.GetCustomAttribute() == null) + { + col.DbColumnName = UtilMethods.ToUnderLine(col.DbColumnName); + } + }, + EntityNameService = delegate (Type t, EntityInfo entity) + { + if (t.GetCustomAttribute() != null) + { + return; + } + + TableAttribute customAttribute = t.GetCustomAttribute(); + if (customAttribute != null) + { + entity.DbTableName = UtilMethods.ToUnderLine(customAttribute.Name); + } + } + }; +} diff --git a/Dolphin.ExamPictureCut.Core/Domains/Quest/PenOfflineData.cs b/Dolphin.ExamPictureCut.Core/Domains/Quest/PenOfflineData.cs index c65396f..1f76880 100644 --- a/Dolphin.ExamPictureCut.Core/Domains/Quest/PenOfflineData.cs +++ b/Dolphin.ExamPictureCut.Core/Domains/Quest/PenOfflineData.cs @@ -1,5 +1,6 @@ using Dolphin.ExamPictureCut.Constants; using Dolphin.ExamPictureCut.Domains.Basic; +using Dolphin.ExamPictureCut.Options; using SqlSugar; namespace Dolphin.ExamPictureCut.Domains.Quest; @@ -7,7 +8,7 @@ namespace Dolphin.ExamPictureCut.Domains.Quest; /// /// 点阵笔离线数据 /// -[Tenant(DbConsts.penoffline)] +[Tenant(DbConsts.penoffline), IgnoreUnderLine] public class PenOfflineData { /// diff --git a/Dolphin.ExamPictureCut.Core/Exams/Dto/ExamStudentGatherEto.cs b/Dolphin.ExamPictureCut.Core/Exams/Dto/ExamStudentGatherEto.cs index a9f6e9d..0e35cdb 100644 --- a/Dolphin.ExamPictureCut.Core/Exams/Dto/ExamStudentGatherEto.cs +++ b/Dolphin.ExamPictureCut.Core/Exams/Dto/ExamStudentGatherEto.cs @@ -24,9 +24,10 @@ public class ExamStudentGatherEto /// /// 模板id /// - public string TemplateId { get; set; } + public long BookId { get; set; } /// /// 所属学生 /// public string StudentExamNum { get; set; } + public DateTime LastCollectTime { get; set; } } diff --git a/Dolphin.ExamPictureCut.Core/Exams/Dto/TemplateJsonModelDto.cs b/Dolphin.ExamPictureCut.Core/Exams/Dto/TemplateJsonModelDto.cs index d8d936a..0fd36bd 100644 --- a/Dolphin.ExamPictureCut.Core/Exams/Dto/TemplateJsonModelDto.cs +++ b/Dolphin.ExamPictureCut.Core/Exams/Dto/TemplateJsonModelDto.cs @@ -20,7 +20,7 @@ public class TemplateJsonModel_DataArr } public class PaperQueData { - public string TemplateId { get; set; } + public long TemplateId { get; set; } public string PaperId { get; set; } public long PartId { get; set; } public int PageIndex { get; set; } diff --git a/Dolphin.ExamPictureCut.Core/Options/AliyunOption.cs b/Dolphin.ExamPictureCut.Core/Options/AliyunOption.cs new file mode 100644 index 0000000..74d0f9c --- /dev/null +++ b/Dolphin.ExamPictureCut.Core/Options/AliyunOption.cs @@ -0,0 +1,14 @@ +namespace Dolphin.ExamPictureCut.Options; + +public class AliyunOption +{ + public string AccessKeyId { get; set; } + public string AccessKeySecret { get; set; } + public string Endpoint { get; set; } + public string RegionId { get; set; } + /// + /// Bucket + /// + public string ContainerName { get; set; } + public string Host { get; set; } +} diff --git a/Dolphin.ExamPictureCut.HttpApi.Host/Dolphin.ExamPictureCut.HttpApi.Host.csproj b/Dolphin.ExamPictureCut.HttpApi.Host/Dolphin.ExamPictureCut.HttpApi.Host.csproj index 6189630..18d82a7 100644 --- a/Dolphin.ExamPictureCut.HttpApi.Host/Dolphin.ExamPictureCut.HttpApi.Host.csproj +++ b/Dolphin.ExamPictureCut.HttpApi.Host/Dolphin.ExamPictureCut.HttpApi.Host.csproj @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/Dolphin.ExamPictureCut.HttpApi.Host/DolphinExamPictureCutHttpApiHostModule.cs b/Dolphin.ExamPictureCut.HttpApi.Host/DolphinExamPictureCutHttpApiHostModule.cs index d4a7b55..a5fa2f5 100644 --- a/Dolphin.ExamPictureCut.HttpApi.Host/DolphinExamPictureCutHttpApiHostModule.cs +++ b/Dolphin.ExamPictureCut.HttpApi.Host/DolphinExamPictureCutHttpApiHostModule.cs @@ -1,5 +1,7 @@ using Dolphin.ExamPictureCut.Constants; +using Dolphin.ExamPictureCut.Domains; using Dolphin.ExamPictureCut.Extensions; +using Dolphin.ExamPictureCut.Options; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Cors; using Microsoft.OpenApi.Models; @@ -41,45 +43,6 @@ public class DolphinExamPictureCutHttpApiHostModule : AbpModule private void ConfigureSqlSugar(ServiceConfigurationContext context, IConfiguration configuration) { - var config = new SqlSugarConfig(); - var ExtService = new ConfigureExternalServices - { - EntityService = delegate (PropertyInfo prop, EntityColumnInfo col) - { - if (prop.GetCustomAttribute() != null) - { - col.IsIgnore = true; - } - - if (prop.PropertyType == typeof(string)) - { - col.DataType = "text"; - } - - if (!col.IsPrimarykey) - { - if (prop.GetCustomAttribute() != null) - { - return; - } - - if (new NullabilityInfoContext().Create(prop).WriteState == NullabilityState.Nullable || prop.PropertyType == typeof(string)) - { - col.IsNullable = true; - } - } - - col.DbColumnName = UtilMethods.ToUnderLine(col.DbColumnName); - }, - EntityNameService = delegate (Type t, EntityInfo entity) - { - TableAttribute customAttribute = t.GetCustomAttribute(); - if (customAttribute != null) - { - entity.DbTableName = UtilMethods.ToUnderLine(customAttribute.Name); - } - } - }; context.Services.AddSingleton(s => { var scope = new SqlSugarScope( @@ -90,7 +53,7 @@ public class DolphinExamPictureCutHttpApiHostModule : AbpModule DbType = DbType.MySql, ConnectionString = configuration.GetConnectionString(DbConsts.marking_basic), IsAutoCloseConnection = true, - ConfigureExternalServices = ExtService, + ConfigureExternalServices = MySqlConfigureExternalServices.MySqlExtService, }, new ConnectionConfig() { @@ -98,13 +61,14 @@ public class DolphinExamPictureCutHttpApiHostModule : AbpModule DbType = DbType.QuestDB, ConnectionString = configuration.GetConnectionString(DbConsts.penoffline), IsAutoCloseConnection = true, - ConfigureExternalServices = ExtService, + ConfigureExternalServices = MySqlConfigureExternalServices.MySqlExtService, }, }, db => { db.QueryFilter.AddTableFilter(s => s.IsDeleted == false); + var config = new SqlSugarConfig(); db.Aop.DataExecuting = config.DataExecuting(context.Services); db.Aop.OnLogExecuting = (sql, pars) => diff --git a/Dolphin.ExamPictureCut.HttpApi.Host/appsettings.Development.json b/Dolphin.ExamPictureCut.HttpApi.Host/appsettings.Development.json index 8236e45..681b5e7 100644 --- a/Dolphin.ExamPictureCut.HttpApi.Host/appsettings.Development.json +++ b/Dolphin.ExamPictureCut.HttpApi.Host/appsettings.Development.json @@ -4,7 +4,7 @@ }, "ConnectionStrings": { "marking_basic": "Server=192.168.2.9;Port=3306;Database=marking_basic;Uid=root;Pwd=qwe123!@#;AllowLoadLocalInfile=true;", - "penoffline": "host=192.168.2.7;port=8812;username=zhjs;password=zhjsniubi;database=qdb;ServerCompatibilityMode=NoTypeLoading;" + "penoffline": "host=47.108.209.28;port=8812;username=zhjs;password=zhjsniubi;database=qdb;ServerCompatibilityMode=NoTypeLoading;" }, "Redis": { "Configuration": "192.168.2.7:6379,password=qwe123!@#,defaultDatabase=14,idleTimeout=3000,poolsize=5,prefix=marking" @@ -18,12 +18,13 @@ "HostName": "192.168.2.7", "Port": "5672", "UserName": "rabbit", - "Password": "qwe123!@#" + "Password": "qwe123!@#", + "VirtualHost": "marking" } }, "EventBus": { "ClientName": "collect_queue", - "ExchangeName": "tenant_ex" + "ExchangeName": "exam_gather_ex" } }, "Aliyun": { diff --git a/Dolphin.ExamPictureCut.HttpApi.Host/appsettings.json b/Dolphin.ExamPictureCut.HttpApi.Host/appsettings.json index 5ef0e80..9738e38 100644 --- a/Dolphin.ExamPictureCut.HttpApi.Host/appsettings.json +++ b/Dolphin.ExamPictureCut.HttpApi.Host/appsettings.json @@ -18,12 +18,13 @@ "HostName": "192.168.2.7", "Port": "5672", "UserName": "rabbit", - "Password": "qwe123!@#" + "Password": "qwe123!@#", + "VirtualHost": "marking" } }, "EventBus": { "ClientName": "collect_queue", - "ExchangeName": "tenant_ex" + "ExchangeName": "exam_gather_ex" } }, "Aliyun": {