/// <summary> /// 根据信息校验用户是否篡改信息,是否满足商铺积分规则 /// </summary> /// <param name="receiptOCR"></param> /// <returns></returns> private static Result VerifyRecognition(ReceiptOCR receiptOCR) { //识别的原始数据 var RecongnizeModel = dal.GetModel <ApplyPictureRecongnize>($" and id ='{receiptOCR.RecongnizelId}'"); if (RecongnizeModel == null) { return(new Result(false, "ApplyPictureRecongnize is null", null)); } #region 检查数据是否篡改(Contain 不是绝对) ReceiptOCR OldReceipt = JsonConvert.DeserializeObject <ReceiptOCR>(RecongnizeModel.OCRResult); var CompareResult = CompareModel <ReceiptOCR>(OldReceipt, receiptOCR); if (!CompareResult.Success) { return(CompareResult); } #endregion #region 匹配商铺规则 StoreOCR StoreOCRRule = CacheHandle <StoreOCR>( Key: $"StoreOCR{receiptOCR.StoreId}", Hour: double.Parse(ConfigurationUtil.GetSection("ObjectConfig:CacheExpiration:StoreOCR")), sqlWhere: $"and StoreId = '{receiptOCR.StoreId}'"); if (StoreOCRRule.Enabled != 1) { return(new Result(false, "商铺未启用自动积分", null)); } if (StoreOCRRule.needVerify == 1) //当商铺启用校验规则 { if (receiptOCR.TranAmount < StoreOCRRule.MinValidReceiptValue || receiptOCR.TranAmount > StoreOCRRule.MaxValidReceiptValue) { return(new Result(false, "小票金额不在店铺规则范围之内!", null)); } if (StoreOCRRule.MaxTicketPerDay != 0) //日自动交易笔数为0时 代表不限制 { var TicketPerDay = DbContext.Query <int>($@"select count(*) from ApplyPoint where StoreID = '{receiptOCR.StoreId}' and VerifyStatus = 1 and SourceType=7 and DATEDIFF(dd,AuditDate,GETDATE())=0").FirstOrDefault(); //当日交易笔数 if (TicketPerDay >= StoreOCRRule.MaxTicketPerDay) { return(new Result(false, "今日已超过最大自动积分记录数量", null)); } } Store StoreModel = CacheHandle <Store>( Key: $"Store{receiptOCR.StoreId}", Hour: double.Parse(ConfigurationUtil.GetSection("ObjectConfig:CacheExpiration:Store")), sqlWhere: $" and StoreId = '{receiptOCR.StoreId}'"); if ((StoreModel.IsStandardPOS == "1" ? 0 : 1) != StoreOCRRule.POSType) { return(new Result(false, "OCR商铺POS类型不一致", null)); } //POS门店代码暂无验证 } #endregion return(new Result(true, "验证成功", null)); }
/// <summary> /// 从OCR接口中 根据规则 获取详细内容 (暂无校验) /// </summary> /// <param name="OcrResult"></param> /// <returns></returns> private static Result RecognitOCRResult(string OcrResult) { try { var OCRResultModel = JsonConvert.DeserializeObject <OCRResult>(OcrResult); var WordList = OCRResultModel.words_result; //被识别的内容 var OCRStoreName = string.Empty; //被识别出来的商铺名称 //查询所有的商铺规则并缓存 List <StoreOCRDetail> AllStoreOCRDetailRuleList = CacheHandle <List <StoreOCRDetail> >( Key: "AllStoreOCRDetailRuleList" , Hour: double.Parse(ConfigurationUtil.GetSection("ObjectConfig:CacheExpiration:AllStoreOCRDetailRuleList")) , sqlWhere: ""); //所有商铺名称规则 var StoreNameRuleList = AllStoreOCRDetailRuleList.Where(s => s.OCRKeyType == (int)OCRKeyType.StoreName).Select(c => c.OCRKey).ToList(); var resultStoreName = FindStoreNameFromAllRule(WordList, StoreNameRuleList);//根据所有的店铺名规则匹配出的StoreName var StoreModel = dal.GetModel <Store>($" and StoreName like '%{resultStoreName}%'"); if (StoreModel == null) { return(new Result(false, "识别商铺名称失败!", "")); } //最后识别结果 var ReceiptOCRModel = new ReceiptOCR { StoreId = StoreModel.StoreId, StoreName = resultStoreName, StoreCode = StoreModel.StoreCode, ReceiptNo = "", TranAmount = 0, TransDatetime = Commom.DefaultDateTime, RecongnizelId = Guid.Empty, Base64 = "" }; //当前店铺的规则明细 var ThisStoreOCRDetail = AllStoreOCRDetailRuleList.Where(s => s.StoreId == StoreModel.StoreId).ToList(); //根据店铺规则明细 关键字类型 关键字 取值方法 匹配识别结果 foreach (var StoreDetailRule in ThisStoreOCRDetail) { for (int i = 0; i < WordList.Count(); i++) { Result ReturnResult = GetValue(WordList, i, StoreDetailRule); //根据规则取值 if (ReturnResult.Success) { var ReturnData = ReturnResult.Data.ToString(); if (!string.IsNullOrWhiteSpace(ReturnData)) { switch (StoreDetailRule.OCRKeyType) //枚举有注释,根据关键字类型赋值 { case (int)OCRKeyType.StoreName: continue; case (int)OCRKeyType.ReceiptNO: if (!string.IsNullOrWhiteSpace(ReturnData) && string.IsNullOrWhiteSpace(ReceiptOCRModel.ReceiptNo)) { ReceiptOCRModel.ReceiptNo = ReturnResult.Data.ToString(); continue; } break; case (int)OCRKeyType.DateTime: if (!string.IsNullOrWhiteSpace(ReturnData) && ReceiptOCRModel.TransDatetime == Commom.DefaultDateTime) { ReturnData = ReturnData.Replace(" ", "").Insert(10, " "); //可能会识别成 2019 - 05 - 1512:14:44 转datetime 报错 if (DateTime.TryParse(ReturnData, out var DateTimeResult)) { ReceiptOCRModel.TransDatetime = DateTimeResult; continue; } } break; case (int)OCRKeyType.Amount: if (!string.IsNullOrWhiteSpace(ReturnData) && ReceiptOCRModel.TranAmount == 0) { if (decimal.TryParse(ReturnResult.Data.ToString(), out var AmountResult)) { ReceiptOCRModel.TranAmount = AmountResult; continue; } } break; default: return(new Result(false, $"商铺未设置该关键字类型取值方法:{StoreDetailRule.OCRKeyType}", null)); } } } } } var RecongnizeModelId = Guid.NewGuid(); var RecongnizeModel = new ApplyPictureRecongnize { id = RecongnizeModelId, applyid = Guid.Empty, Lineno = 0, LineContent = JsonConvert.SerializeObject(WordList), OCRResult = JsonConvert.SerializeObject(ReceiptOCRModel) }; var AddResult = DbContext.Add(RecongnizeModel);//添加原始数据 applyid 等待积分申请 //添加成功后 出参RecongnizeModelId if (AddResult == 0) { ReceiptOCRModel.RecongnizelId = RecongnizeModelId; } else { return(new Result(false, "添加到ApplyPictureRecongnize失败", null)); } return(new Result(true, "识别成功", ReceiptOCRModel)); } catch (Exception ex) { Log.Error("VerifyOCRResult", ex); return(new Result(false, ex.Message, null)); } //同步寻找 string FindStoreNameFromAllRule(List <Words> words, List <string> StoreNameList) { foreach (var Name in StoreNameList) { foreach (var word in words) { if (word.words.Contains(Name)) { return(word.words); } } } return(""); } //异步寻找 async Task <string> FindStoreNameFromAllRuleAsync(List <Words> words, List <string> StoreNameList) { var Sresult = ""; foreach (var names in StoreNameList) { var LineCount = words.Count(); //识别内容数量 //二分异步寻找 var afterLine = LineCount % 2 == 1 ? (LineCount - 1) / 2 : LineCount / 2; //前一半 var beforeLine = LineCount - afterLine; //后一半 CancellationTokenSource ct = new CancellationTokenSource(); for (int i = 0; i < 2; i++) { var min = i % 2 == 0 ? 0 : afterLine; var max = i % 2 == 0 ? afterLine - 1 : LineCount; await Task.Run(() => { for (int j = min; j < max; j++) { if (ct.IsCancellationRequested) { if (words[j].words.Contains(names)) { ct.Cancel(); Sresult = words[j].words; } } } }, ct.Token); } } return(""); } //根据规则获取指定识别内容 Result GetValue(List <Words> words_result, int index, StoreOCRDetail StoreDetailRule) { var WordValue = ""; if (words_result[index].words.Contains(StoreDetailRule.OCRKey)) { switch (StoreDetailRule.GetValueWay)//可查看枚举注释 { case (int)GetValueWay.OCRKey: WordValue = words_result[index].words; break; case (int)GetValueWay.AfterOCRKey: var IndexOfKey = words_result[index].words.IndexOf(StoreDetailRule.OCRKey) + StoreDetailRule.OCRKey.Length + StoreDetailRule.SkipLines; WordValue = words_result[index].words.Substring(IndexOfKey); break; case (int)GetValueWay.NextLine: if (index + StoreDetailRule.SkipLines <= words_result.Count()) { WordValue = words_result[index + StoreDetailRule.SkipLines].words; } break; default: return(new Result(false, $"商铺未设置该关键字取值方法:{StoreDetailRule.GetValueWay}", null)); } } return(new Result(true, "", WordValue)); } }