| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- using DaJiaoYan.Models;
- using DaJiaoYan.Utils;
- using DaJiaoYan.Variables;
- using OpenCvSharp;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Threading.Tasks;
- using static DaJiaoYan.Models.PartitionConfig;
- namespace DaJiaoYan.Services
- {
- struct ScanResult
- {
- public string Filename;
- public int Index;
- }
- internal class PingHandler : HttpHandler
- {
- private ResponseData pongResponse = new ResponseData { Code = 200, Data = "pong" };
- public PingHandler(AsyncHttpServer httpServer) : base(httpServer)
- {
- }
- public override void Get(HttpListenerRequest request, HttpListenerResponse response)
- {
- Json(ref response, ref pongResponse);
- }
- }
- internal class ScannerHandler : HttpHandler
- {
- public ScannerHandler(AsyncHttpServer httpServer) : base(httpServer)
- {
- }
- public override void Get(HttpListenerRequest request, HttpListenerResponse response)
- {
- ResponseData result = new ResponseData { Code = 200, Data = Variables.Vars.Scanners };
- Json(ref response, ref result);
- }
- }
- public class ScanHandler : HttpHandler
- {
- public ScanHandler(AsyncHttpServer httpServer) : base(httpServer)
- {
- }
- public override async void Post(HttpListenerRequest request, HttpListenerResponse response)
- {
- ResponseData result = new ResponseData { Code = 200 };
- var form = this.HttpServer.ParseForm(ref request);
- form.TryGetValue("scanner", out string scanner);
- var files = new List<string>();
- var finished = false;
- result.Data = files;
- if (string.IsNullOrEmpty(scanner))
- {
- result.Code = 400;
- result.Errors = "请选择扫描仪";
- finished = true;
- }
- else if (!Vars.Scanners.Contains(scanner))
- {
- result.Code = 400;
- result.Errors = "请选择正确的扫描仪";
- finished = true;
- }
- else if (Scan.State == Scan.ScannerState.Running)
- {
- result.Code = 400;
- result.Errors = "正在扫描中";
- finished = true;
- }
- else
- {
- ScanTask scanTask = new ScanTask
- {
- Scanner = scanner,
- ImageDpi = 200,
- ImageSuffix = "png",
- Colorful = true,
- Path = Const.TMP_PATH,
- CapXferCount = 2,
- OnScanBegin = (bool begin, string err) =>
- {
- if (!begin)
- {
- result.Code = 400;
- result.Errors = err;
- finished = true;
- }
- },
- OnDeleScanFileCompleted = (string f, int index) =>
- {
- try
- {
- Mat img = Cv2.ImRead(f);
- if (img != null && img.Channels() > 1)
- {
- ImageUtils.Red2OtherColor(ref img, Scalar.Black);
- Mat dstImg = new Mat(img.Size(), MatType.CV_8UC1);
- Cv2.CvtColor(img, dstImg, ColorConversionCodes.BGR2GRAY);
- Cv2.ImWrite(f, dstImg);
- dstImg.Dispose();
- }
- files.Add(ImageUtils.ToBase64(f));
- img?.Dispose();
- }
- catch
- {
- }
- },
- OnScanTaskCompleted = () =>
- {
- result.Code = 200;
- finished = true;
- },
- OnScannerError = () =>
- {
- result.Code = 200;
- result.Errors = "扫描出错!";
- finished = true;
- }
- };
- Scan.Start(scanTask);
- while (!finished || files.Count < 2)
- {
- await Task.Delay(100);
- }
- }
- Json(ref response, ref result);
- }
- }
- public class UploadHandler : HttpHandler
- {
- public UploadHandler(AsyncHttpServer httpServer) : base(httpServer)
- {
- }
- /// <summary>
- /// 扫描图片上传接口
- /// </summary>
- /// <param name="request"></param>
- /// <param name="response"></param>
- public override async void Post(HttpListenerRequest request, HttpListenerResponse response)
- {
- ResponseData result = new ResponseData { Code = 200 };
- int ocrVer = 0;
- var form = this.HttpServer.ParseForm(ref request);
- form.TryGetValue("token", out string token);
- form.TryGetValue("type", out string type);
- form.TryGetValue("school_id", out string school_id);
- form.TryGetValue("campus_id", out string campus_id);
- form.TryGetValue("class_id", out string class_id);
- form.TryGetValue("test_id", out string test_id);
- form.TryGetValue("subject_id", out string subject_id);
- form.TryGetValue("is_school_no", out string is_school_no);
- form.TryGetValue("sign_weight", out string sign_weight);
- form.TryGetValue("marking_type", out string marking_type);
- form.TryGetValue("scanner", out string scanner);
- form.TryGetValue("directory", out string directory);
- form.TryGetValue("ver", out string ver);
- if (!string.IsNullOrEmpty(ver))
- {
- int.TryParse(ver, out ocrVer);
- }
- UploadHandlerPostParam param = new UploadHandlerPostParam(
- token, type, school_id, campus_id, class_id, test_id, subject_id, is_school_no, sign_weight, scanner, directory, marking_type,
- ocrVer
- );
- if (param.GetErrorType != UploadHandlerPostParam.ErrorType.None)
- {
- result.Code = 400;
- result.Errors = param.ErrorMessage;
- }
- else
- {
- var divideConfig = await Api.GetDividePartitionConfig(param.TestId, param.Token);
- if (param.Type == UploadHandlerPostParam.UploadType.Scan)
- {
- if (Scan.State == Scan.ScannerState.Running)
- {
- result.Code = 400;
- result.Errors = "正在扫描中,请稍候";
- }
- if (string.IsNullOrEmpty(scanner))
- {
- result.Code = 400;
- result.Errors = "请选择扫描仪";
- param.ScanFinish = true;
- }
- else if (!Vars.Scanners.Contains(scanner))
- {
- result.Code = 400;
- result.Errors = "请选择正确的扫描仪";
- param.ScanFinish = true;
- }
- else
- {
- AliyunOssClient ossClient = new AliyunOssClient(param.Token);
- if (!ossClient.AccessAvailable)
- {
- result.Code = 400;
- result.Errors = "没有上传权限,请检查";
- }
- else
- {
- string batchId = Functions.GenUUID();
- string uploadTaskInfoId = batchId;
- result.Data = batchId;
- UploadTask.deleNewUploadTask(uploadTaskInfoId);
- string path = Path.Combine(Const.TMP_PATH, campus_id.ToString(), test_id.ToString(), batchId);
- FileExts.CheckDirectory(path, true);
- param.Directory = path;
- object _locker = new object();
- ScanResultPost scanResult = new ScanResultPost(param);
- //List<string> files = new List<string>();
- List<ScanResult> scanFiles = new List<ScanResult>();
- int n = 0, finished = 0;
- const int BATCH_SIZE = 2; //扫描1张就上传
- bool uploadImage(string ossFn, string fn)
- {
- bool res = false;
- if (scanResult.MarkingType == UploadHandlerPostParam.MarkType.OnlineMarking)
- {
- try
- {
- Mat img = Cv2.ImRead(fn);
- if (img != null && img.Channels() > 1)
- {
- Mat dstImg = new Mat(img.Size(), MatType.CV_8UC1);
- Cv2.CvtColor(img, dstImg, ColorConversionCodes.BGR2GRAY);
- Cv2.ImWrite(fn, dstImg);
- img.Dispose();
- dstImg.Dispose();
- }
- img?.Dispose();
- }
- catch
- {
- }
- }
- res = ossClient.SimpleUpload(ossFn, fn);
- UploadTask.deleIncreaseUploadTask(uploadTaskInfoId);
- return res;
- }
- async void uploadedFilenames()
- {
- //Console.WriteLine($"n={n}, total={scanResult.Total}, finish={scanResult.Finish}");
- if (n >= BATCH_SIZE || scanResult.Finish)
- {
- List<Task> tasks = new List<Task>();
- ScanResultPost sr = new ScanResultPost(param);
- lock (_locker)
- {
- sr.Finish = scanResult.Finish;
- sr.Total = scanResult.Total;
- sr.BatchId = scanResult.BatchId;
- }
- for (int i = sr.Total - n; i < sr.Total; i++)
- {
- int idx = i;
- ScanResultPost.ImageInfo info = new ScanResultPost.ImageInfo()
- {
- Image = scanFiles[idx].Filename,
- HasError = 1,
- Index = scanFiles[idx].Index
- };
- sr.Images.Add(info);
- tasks.Add(Task.Run(() =>
- {
- if (uploadImage(scanFiles[idx].Filename, Path.Combine(path, Path.GetFileName(scanFiles[idx].Filename))))
- {
- info.HasError = 0;
- }
- }));
- }
- n = 0;
- await Task.Factory.StartNew(async () =>
- {
- await Task.WhenAll(tasks.ToArray());
- // 上传图片地址
- await Api.PostExaminationScanResult(sr, param.Token);
- Vars.UploadedCounterIncrease(tasks.Count);
- lock (_locker)
- {
- finished += BATCH_SIZE;
- }
- //UploadTask.deleIncreaseUploadTask(uploadTaskInfoId, BATCH_SIZE);
- });
- }
- }
- ScanTask scanTask = new ScanTask
- {
- Scanner = scanner,
- ImageDpi = 200,
- ImageSuffix = "jpg",
- Colorful = param.MarkingType == UploadHandlerPostParam.MarkType.LocalMarking || (divideConfig != null && !divideConfig.Template.MarkingOnLine),
- Path = path,
- CapXferCount = -1,
- OnScanBegin = (bool begin, string err) =>
- {
- if (!begin)
- {
- result.Code = 400;
- result.Errors = err;
- scanResult.Finish = true;
- }
- },
- OnDeleScanFileCompleted = (string f, int index) =>
- {
- try
- {
- Task.Factory.StartNew(() =>
- {
- string originFilename = Functions.GenUploadOriginImageName(param.TestId, param.CampusId, f, scanResult.BatchId);
- lock (_locker)
- {
- //files.Add(originFilename);
- scanFiles.Add(new ScanResult { Filename = originFilename, Index = index });
- n++;
- scanResult.Total++;
- }
- UploadTask.deleIncreaseScanTask(uploadTaskInfoId, 1);
- uploadedFilenames();
- });
- }
- catch
- {
- }
- },
- OnScanTaskCompleted = async () =>
- {
- result.Code = 200;
- if (scanFiles.Count > 0)
- {
- while (finished < scanResult.Total)
- {
- await Task.Delay(1000);
- }
- }
- scanResult.Finish = true;
- UploadTask.deleFinishScanTask(uploadTaskInfoId);
- },
- OnScannerError = () =>
- {
- result.Code = 200;
- result.Errors = "扫描出错!";
- scanResult.Finish = true;
- }
- };
- await Task.Factory.StartNew(async () =>
- {
- Scan.Start(scanTask);
- Vars.SetTaskStatus(batchId, false);
- while (!scanResult.Finish)
- {
- await Task.Delay(100);
- }
- uploadedFilenames();
- Vars.SetTaskStatus(batchId, true);
- UploadTask.deleFinishUploadTask(uploadTaskInfoId);
- });
- }
- }
- }
- else
- {
- int answerSheetsLength = 2;
- if (divideConfig != null)
- {
- answerSheetsLength = divideConfig.AnswerSheets.Length;
- }
- // 上传文件夹
- List<string> files = FileExts.GetImageFiles(param.Directory);
- if (divideConfig != null && files.Count > 0 && answerSheetsLength > 0 && files.Count % answerSheetsLength != 0)
- {
- result.Code = 400;
- result.Errors = "本地答卷数量与模板数量不一致,请核查";
- }
- else if (files.Count > 0)
- {
- AliyunOssClient ossClient = new AliyunOssClient(param.Token);
- if (!ossClient.AccessAvailable)
- {
- result.Code = 400;
- result.Errors = "没有上传权限,请检查";
- }
- else
- {
- const int BATCH_SIZE = 4; //作为一个批次上传的图片数量
- string uploadTaskInfoId = Functions.GenUUID();
- UploadTask.deleNewUploadTask(uploadTaskInfoId);
- UploadTask.deleIncreaseScanTask(uploadTaskInfoId, files.Count);
- UploadTask.deleFinishScanTask(uploadTaskInfoId);
- result.Data = uploadTaskInfoId;
- int n = 0, idx = 0;
- ScanResultPost scanResult = new ScanResultPost(param)
- {
- Total = files.Count
- };
- bool uploadImage(string ossFn, string fn)
- {
- bool res = false;
- MemoryStream ms = new MemoryStream();
- string suffix = Path.GetExtension(fn).ToLower();
- ImageEncodingParam imageEncodingParam = Vars.IMAGE_SAVE_PNG_PARAM;
- Mat img;
- if (suffix.Equals(".jpeg", StringComparison.OrdinalIgnoreCase) || suffix.Equals(".jpg", StringComparison.OrdinalIgnoreCase))
- {
- imageEncodingParam = Vars.IMAGE_SAVE_JPEG_PARAM;
- }
- if (scanResult.MarkingType == UploadHandlerPostParam.MarkType.LocalMarking || (divideConfig != null && !divideConfig.Template.MarkingOnLine))
- {
- img = ImageUtils.Read(fn);
- }
- else
- {
- img = ImageUtils.Read(fn, ImreadModes.Grayscale);
- }
- if (img != null)
- {
- ms = img.ToMemoryStream(suffix, imageEncodingParam);
- res = ossClient.SimpleUpload(ossFn, ms);
- img?.Dispose();
- ms?.Dispose();
- }
- return res;
- }
- async Task uploadedFilenames()
- {
- //Console.WriteLine($"n={n}, total={scanResult.Total}, finish={scanResult.Finish}");
- List<Task> tasks = new List<Task>();
- if (n >= BATCH_SIZE || scanResult.Finish)
- {
- scanResult.Images.Clear();
- for (int i = 0; idx < scanResult.Total && i < n; i++)
- {
- int _k = idx;
- string originImageFilename = Functions.GenUploadOriginImageName(scanResult.TestId, scanResult.CampusId, files[_k], scanResult.BatchId);
- ScanResultPost.ImageInfo info = new ScanResultPost.ImageInfo() { Image = originImageFilename, HasError = 1 };
- scanResult.Images.Add(info);
- tasks.Add(Task.Run(() =>
- {
- if (uploadImage(originImageFilename, files[_k]))
- {
- Console.WriteLine($"{originImageFilename} uploaded.");
- info.HasError = 0;
- info.Index = _k + 1;
- UploadTask.deleIncreaseUploadTask(uploadTaskInfoId);
- }
- }));
- idx++;
- }
- n = 0;
- }
- Task.WaitAll(tasks.ToArray());
- // 上传图片地址
- await Api.PostExaminationScanResult(scanResult, param.Token);
- Vars.UploadedCounterIncrease(tasks.Count);
- }
- _ = Task.Factory.StartNew(async () =>
- {
- string batchId = scanResult.BatchId;
- Vars.SetTaskStatus(batchId, false);
- for (int i = 0; i < files.Count; i += BATCH_SIZE)
- {
- n = BATCH_SIZE;
- await uploadedFilenames();
- await Task.Delay(100);
- }
- scanResult.Finish = true;
- n = BATCH_SIZE;
- await uploadedFilenames();
- Vars.SetTaskStatus(batchId, true);
- UploadTask.deleFinishUploadTask(uploadTaskInfoId);
- });
- }
- }
- else
- {
- result.Code = 400;
- result.Errors = "没有可上传的图片";
- }
- }
- }
- Json(ref response, ref result);
- }
- public override void Get(HttpListenerRequest request, HttpListenerResponse response)
- {
- ResponseData result = new ResponseData { Code = 200 };
- string id = request.QueryString.Get("id");
- result.Data = UploadTask.deleGetUploadTask(id);
- Json(ref response, ref result);
- }
- }
- }
|