/// <summary> /// 小票OCR结果匹配商铺自动积分规则 /// </summary> /// <param name="OCRResult"></param> /// <returns></returns> private static Result VerifyOCRResult(ApplyPointOCRResult OCRResult) { //是否全部识别 if (string.IsNullOrWhiteSpace(OCRResult.StoreCode) || OCRResult.TranAmount == 0 || OCRResult.TransDatetime == DefaultDateTime || string.IsNullOrWhiteSpace(OCRResult.ReceiptNo)) { OCRResult.Status = 1; } else { OCRResult.Status = 2; } if (DbContext.Add(OCRResult) == 0) //添加至积分申请识别结果表 { if (OCRResult.needVerify == 1) //当需要需要校验 { var ApplyPointModel = dal.GetModel <ApplyPoint>($"and ApplyPointID='{OCRResult.applyid}'"); Store StoreModel = CacheHandle <Store>($"Store{OCRResult.StoreID}", 1, $" and StoreId = '{OCRResult.StoreID}'"); if (string.IsNullOrWhiteSpace(OCRResult.StoreCode) || StoreModel.StoreCode != OCRResult.StoreCode) { return(new Result(false, "OCR店铺Code未识别正确!", null)); } if (OCRResult.TransDatetime == DefaultDateTime && OCRResult.TransDatetime.ToString("yyyy-MM-dd") != ApplyPointModel.TransDate.ToString("yyyy-MM-dd")) { return(new Result(false, "OCR交易日期未识别正确!", null)); } StoreOCR StoreOCRRule = CacheHandle <StoreOCR>($"StoreOCR{OCRResult.StoreID}", 0.5, $"and StoreId = '{OCRResult.StoreID.ToString()}'"); if (OCRResult.TranAmount < StoreOCRRule.MinValidReceiptValue || OCRResult.TranAmount > StoreOCRRule.MaxValidReceiptValue) { return(new Result(false, "OCR小票金额不在店铺规则范围之内!", null)); } if (OCRResult.TranAmount != ApplyPointModel.TransAmt) { return(new Result(false, "OCR小票金额不一致!", null)); } if (StoreOCRRule.MaxTicketPerDay != 0) //日自动交易笔数为0时 代表不限制 { var TicketPerDay = DbContext.Query <int>($@"select count(*) from ApplyPoint where StoreID = '{OCRResult.StoreID.ToString()}' and VerifyStatus = 1 and SourceType=7 and DATEDIFF(dd,AuditDate,GETDATE())=0").FirstOrDefault(); //当日交易笔数 if (TicketPerDay >= StoreOCRRule.MaxTicketPerDay) { return(new Result(false, "今日已超过最大自动积分记录数量", null)); } } if ((StoreModel.IsStandardPOS == "1" ? 0 : 1) != StoreOCRRule.POSType) { return(new Result(false, "OCR商铺POS类型不一致", null)); } MallOCRRule MallOCRRule = CacheHandle <MallOCRRule>($"MallOCRRule{OCRResult.StoreID}", 1, $" and MallID='{StoreModel.MallID}'"); var posUrl = MallOCRRule.POSServeURL; var posToken = MallOCRRule.POSServerToken; var posUser = MallOCRRule.POSServerUser; var userPwd = MallOCRRule.POSServerPassword; //请求POS POSSID //if (POSSID != StoreOCRRule.POSSID) //{ // return new Result(false, "OCR商铺POS代码不一致", null); //} } } else { return(new Result(false, "ApplyPointOCRResult添加失败", null)); } OCRResult.VerifyStatus = 1; if (DbContext.Update(OCRResult)) { return(new Result(true, "", null)); } else { return(new Result(false, "ApplyPointOCRResult修改VerifyStatus失败", null)); } }
/// <summary> /// 创建积分申请单,校验信息成功并推送 /// 若原先存在积分申请单,失败的原因:校验失败 所有应该重新赋值 /// </summary> /// <param name="applyPointRequest"></param> /// <returns></returns> public static Result CreateApplyPoint(ApplyPointRequest applyPointRequest) { try { #region 图片上传 ImageResponse ImageResponse = null; try { var FileUploadResult = ImageUpload(Commom.FileUploadUrl, applyPointRequest.receiptOCR.Base64); if (!FileUploadResult.Success) { return(FileUploadResult); } ImageResponse = JsonConvert.DeserializeObject <ImageResponse>(FileUploadResult.Data.ToString()); } catch (Exception ex) { Log.Error("CreateApplyPoint-FileUpload", ex); return(new Result(false, ex.Message, null)); } #endregion Store StoreModel = CacheHandle <Store>( Key: $"Store{applyPointRequest.receiptOCR.StoreId}", Hour: double.Parse(ConfigurationUtil.GetSection("ObjectConfig:CacheExpiration:Store")), sqlWhere: $" and StoreId = '{applyPointRequest.receiptOCR.StoreId}'"); StoreOCR StoreOCRRule = CacheHandle <StoreOCR>( Key: $"StoreOCR{applyPointRequest.receiptOCR.StoreId}", Hour: double.Parse(ConfigurationUtil.GetSection("ObjectConfig:CacheExpiration:StoreOCR")), sqlWhere: $"and StoreId = '{applyPointRequest.receiptOCR.StoreId}'"); var ApplyPoint = dal.GetModel <ApplyPoint>($" and ReceiptNo='{applyPointRequest.receiptOCR.ReceiptNo}' and StoreID='{applyPointRequest.receiptOCR.StoreId}'"); ApplyPictureRecongnize applyPictureRecongnize = dal.GetModel <ApplyPictureRecongnize>($" and id='{applyPointRequest.receiptOCR.RecongnizelId}'"); var IsHas = false; // 是否原先存在积分申请单 默认没有 更新识别原始表 if (ApplyPoint == null) //判断该小票号 是否存在积分申请单 不存在则添加原始积分申请单 (已解析原始数据,校验失败) { var ApplyPointId = Guid.NewGuid(); ApplyPoint = new ApplyPoint { ApplyPointID = ApplyPointId, MallID = StoreModel.MallID, StoreID = applyPointRequest.receiptOCR.StoreId, CardID = Guid.Parse(applyPointRequest.cardId), ReceiptNo = applyPointRequest.receiptOCR.ReceiptNo, TransDate = applyPointRequest.receiptOCR.TransDatetime, TransAmt = applyPointRequest.receiptOCR.TranAmount, VerifyStatus = StoreOCRRule.needVerify == 0 ? 1 : 0, ReceiptPhoto = ImageResponse.fileURL }; applyPictureRecongnize.applyid = ApplyPointId; DbContext.Update <ApplyPictureRecongnize>(applyPictureRecongnize); } else { IsHas = true; ApplyPoint.MallID = StoreModel.MallID; ApplyPoint.StoreID = applyPointRequest.receiptOCR.StoreId; ApplyPoint.CardID = Guid.Parse(applyPointRequest.cardId); ApplyPoint.ReceiptNo = applyPointRequest.receiptOCR.ReceiptNo; ApplyPoint.TransDate = applyPointRequest.receiptOCR.TransDatetime; ApplyPoint.TransAmt = applyPointRequest.receiptOCR.TranAmount; ApplyPoint.VerifyStatus = StoreOCRRule.needVerify == 0 ? 1 : 0; } var VerifyRecognitionResult = VerifyRecognition(applyPointRequest.receiptOCR); //校验结果 ApplyPoint.AuditDate = DateTime.Now; if (VerifyRecognitionResult.Success) //校验成功 { ApplyPoint.RecongizeStatus = 2; ApplyPoint.VerifyStatus = 1; } else//校验失败 修改值 { ApplyPoint.RecongizeStatus = 3; ApplyPoint.VerifyStatus = 0; ApplyPoint.Status = 0; if (IsHas) { DbContext.Update <ApplyPoint>(ApplyPoint); } else { DbContext.Add <ApplyPoint>(ApplyPoint); } return(VerifyRecognitionResult); } var LastRes = true;//添加是否成功 if (IsHas) { if (!DbContext.Update <ApplyPoint>(ApplyPoint)) { LastRes = false; } } else { if (DbContext.Add <ApplyPoint>(ApplyPoint) != 0) { LastRes = false; } } if (LastRes) { List <Company> companyList = CacheHandle <List <Company> >( Key: "Company", Hour: double.Parse(ConfigurationUtil.GetSection("ObjectConfig:CacheExpiration:Company")), sqlWhere: ""); List <OrgInfo> orgList = CacheHandle <List <OrgInfo> >( Key: "OrgInfo", Hour: double.Parse(ConfigurationUtil.GetSection("ObjectConfig:CacheExpiration:OrgInfo")), sqlWhere: ""); //自动积分 推送 var arg = new WebPosArg { companyID = companyList.Where(s => s.CompanyId == StoreModel.CompanyID).FirstOrDefault()?.CompanyCode ?? "", storeID = StoreModel.StoreCode, cardID = dal.GetModel <Card>($" and CardID='{applyPointRequest.cardId}'")?.CardCode ?? "", cashierID = "CrmApplyPoint", discountPercentage = 0, orgID = orgList.Where(s => s.OrgId == StoreModel.OrgID).FirstOrDefault()?.OrgCode ?? "", receiptNo = applyPointRequest.receiptOCR.ReceiptNo, txnDateTime = applyPointRequest.receiptOCR.TransDatetime }; var argStr = JsonConvert.SerializeObject(arg); ProducerMQ(argStr); return(new Result(true, "校验成功,已申请积分!", null)); } return(new Result(false, "校验成功,对ApplyPoint操作失败!", null)); } catch (Exception ex) { Log.Error("CreateApplyPoint", ex); return(new Result(false, ex.Message, null)); } }
/// <summary> /// 根据商铺规则明细取到内容 /// </summary> /// <param name="ApplyId">积分申请单ID</param> /// <param name="StoreId">商铺Id</param> /// <param name="OCRResult">OCR识别原始数据</param> /// <returns></returns> private static Result GetApplyPointOCRResult(Guid ApplyId, Guid StoreId, string OCRResult) { try { //缓存处理 StoreOCR StoreOCRRule = CacheHandle <StoreOCR>($"StoreOCR{StoreId}", 0.5, $"and StoreId = '{StoreId.ToString()}'"); if (StoreOCRRule == null) { return(new Result(false, "商铺未设置自动积分规则", null)); } if (StoreOCRRule.Enabled != 1) { return(new Result(false, "商铺未启用自动积分", null)); } //当商铺启用自动积分 var OCRResultModel = JsonConvert.DeserializeObject <OCRResult>(OCRResult);//识别的内容 if (OCRResultModel == null) { return(new Result(false, "OCR识别失败", null)); } List <StoreOCRDetail> StoreOCRDetailRuleList = CacheHandle <List <StoreOCRDetail> >($"StoreOCRDetail{StoreId}", 0.5, $"and StoreId = '{StoreId.ToString()}'"); if (StoreOCRDetailRuleList == null) { return(new Result(false, "商铺未设置自动规则明细", null)); } ApplyPointOCRResult applyPointOCRResult = new ApplyPointOCRResult //积分申请识别结果 { id = Guid.NewGuid(), applyid = ApplyId, StoreID = StoreId, VerifyStatus = 0, Status = 0, needVerify = StoreOCRRule.needVerify, StoreCode = "", ReceiptNo = "", TransDatetime = DefaultDateTime, TranAmount = 0, }; //1 异步 明细数量个线程 识别 ??? foreach (var StoreDetailRule in StoreOCRDetailRuleList) //遍历商铺规则明细 { for (int i = 0; i < OCRResultModel.words_result.Count(); i++) //根据规则循环匹配识别文字 { Result ReturnResult = GetValue(OCRResultModel.words_result, i, StoreDetailRule); //根据规则取值 if (ReturnResult.Success) { var ReturnData = ReturnResult.Data.ToString(); switch (StoreDetailRule.OCRKeyType) //枚举有注释,根据关键字类型赋值 { case (int)OCRKeyType.StoreName: if (!string.IsNullOrWhiteSpace(ReturnData) && string.IsNullOrWhiteSpace(applyPointOCRResult.StoreCode)) { applyPointOCRResult.StoreCode = dal.GetModel <Store>($" and StoreName like '%{ReturnData}%'")?.StoreCode ?? ""; continue; } break; case (int)OCRKeyType.ReceiptNO: if (!string.IsNullOrWhiteSpace(ReturnData) && string.IsNullOrWhiteSpace(applyPointOCRResult.ReceiptNo)) { applyPointOCRResult.ReceiptNo = ReturnResult.Data.ToString(); continue; } break; case (int)OCRKeyType.DateTime: if (!string.IsNullOrWhiteSpace(ReturnData) && applyPointOCRResult.TransDatetime == DefaultDateTime) { ReturnData = ReturnData.Replace(" ", "").Insert(10, " "); //可能会识别成 2019 - 05 - 1512:14:44 转datetime 报错 if (DateTime.TryParse(ReturnData, out var DateTimeResult)) { applyPointOCRResult.TransDatetime = DateTimeResult; continue; } } break; case (int)OCRKeyType.Amount: if (!string.IsNullOrWhiteSpace(ReturnData) && applyPointOCRResult.TranAmount == 0) { if (decimal.TryParse(ReturnResult.Data.ToString(), out var AmountResult)) { applyPointOCRResult.TranAmount = AmountResult; continue; } } break; default: return(new Result(false, $"商铺未设置该关键字类型取值方法:{StoreDetailRule.OCRKeyType}", null)); } } else { return(ReturnResult); } } } return(new Result(true, "匹配规则成功", applyPointOCRResult)); //根据规则获取指定识别内容 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)); } } catch (Exception ex) { return(new Result(false, ex.Message, null)); } }
/// <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)); }