private static async Task AddYemUserPurchase(CloudTableClient tableClient, YemUserProductDto yemUserProductDto, string writeYemUserProductAzureTable) { if (yemUserProductDto != null) { CloudTable yemProductTable = tableClient.GetTableReference(writeYemUserProductAzureTable); await yemProductTable.ExecuteAsync(TableOperation.InsertOrReplace(yemUserProductDto)); } }
private static YemUserProductDto BuildYemUserProduct(YemUserProductDto yemUserProductDto, long allocateAmount) { var newYemUserProductDto = yemUserProductDto.MapToYemUserProductDto(); newYemUserProductDto.Allocated += allocateAmount; newYemUserProductDto.Status = newYemUserProductDto.PurchaseMoney == newYemUserProductDto.Allocated ? PurchaseOrderStatus.AllocationComplete.ToEnumInteger() : PurchaseOrderStatus.AllocationOn.ToEnumInteger(); newYemUserProductDto.WaitingBankBackAmount = 0; newYemUserProductDto.UpdatedTime = DateTime.UtcNow.ToChinaStandardTime(); return(newYemUserProductDto); }
/// <summary> /// 创建比例关系 /// </summary> /// <param name="item"></param> /// <param name="onSellAssetDto"></param> /// <param name="allocateAmount"></param> /// <returns></returns> private static Tuple <UserAssetRatio, UserAssetRatio> CreateUserAssetRatio(YemUserProductDto item, OnSellAssetDto onSellAssetDto, long allocateAmount) { UserAssetRatio userAssetRatio = new UserAssetRatio { AssetCategoryCode = onSellAssetDto.AssetCategoryCode, AssetId = onSellAssetDto.OnSellAssetId, BillDueDate = onSellAssetDto.BillDueDate, Capital = allocateAmount, Cellphone = item.Cellphone, CredentialNo = item.CredentialNo, Denominator = onSellAssetDto.PresentValue, IsInvestSuccess = true, //用户资产已报备 IsNotifyTradingSuccess = true, //已通知交易系统 IsReturned = false, NotifyTradingRespInfo = "Mock", NotifyTradingTime = DateTime.UtcNow.ToChinaStandardTime(), Numerator = allocateAmount, OrderId = item.OrderId, OrderTime = item.OrderTime, OriginalUserAssetRatioId = Guid.NewGuid().ToGuidString(), PurchaseMoney = item.PurchaseMoney, Reserve = "1", //放款成功 Status = 4, //用户资产报备成功 UserId = item.UserId, UserName = item.UserName, UserPresentValue = 0, CreatedBy = "System", CreatedTime = DateTime.UtcNow.ToChinaStandardTime(), UpdatedBy = "System", UpdatedTime = DateTime.UtcNow.ToChinaStandardTime(), PartitionKey = item.UserId, ETag = DateTime.UtcNow.ToChinaStandardTime().UnixTimestamp().ToString() }; userAssetRatio.UserAssetRatioId = userAssetRatio.OriginalUserAssetRatioId; userAssetRatio.RowKey = userAssetRatio.AssetId + "_" + userAssetRatio.UserAssetRatioId; //资产用户关系 var assetUserRatio = MapToUserAssetRatio(userAssetRatio); return(Tuple.Create(userAssetRatio, assetUserRatio)); }
/// <summary> /// 更新用户比例信息 /// </summary> /// <param name="tableClient"></param> /// <param name="yemUserProductDto"></param> /// <param name="addUserAssetRatios"></param> /// <param name="addAssetUserRatios"></param> /// <param name="modifyOnSellAssetDtos"></param> /// <param name="writeAssetAzureTable"></param> /// <param name="writeYemUserProductAzureTable"></param> /// <param name="writeUserAssetRatioAzureTable"></param> /// <param name="writeAssetUserRatioAzureTable"></param> /// <param name="batchNum"></param> public static async Task InsertOrReplaceAzureTable(CloudTableClient tableClient, YemUserProductDto yemUserProductDto, List <UserAssetRatio> addUserAssetRatios, List <UserAssetRatio> addAssetUserRatios, List <OnSellAssetDto> modifyOnSellAssetDtos, string writeAssetAzureTable, string writeYemUserProductAzureTable, string writeUserAssetRatioAzureTable, string writeAssetUserRatioAzureTable, int batchNum = 100) { try { List <Task> tasks = new List <Task>(); tasks.Add(AddOnSellAsset(tableClient, modifyOnSellAssetDtos, writeAssetAzureTable, batchNum)); tasks.Add(AddUserAssetRatio(tableClient, addUserAssetRatios, writeUserAssetRatioAzureTable, batchNum)); //资产用户关系 tasks.Add(AddAssetUserRelation(tableClient, addAssetUserRatios, writeAssetUserRatioAzureTable)); //购买 tasks.Add(AddYemUserPurchase(tableClient, yemUserProductDto, writeYemUserProductAzureTable)); await Task.WhenAll(tasks); } catch (Exception e) { Console.WriteLine(e); throw; } }
/// <summary> /// 获取需要分配的资产、订单,排除资产 /// </summary> /// <returns></returns> private static async Task UserToAllocateAssetByNoIncludeAsync(string[] noIncludeAssetIds, long minAmount, long maxAmount, string assetAzureTableName, string yemUserProductAzureTableName, string writeAssetAzureTable, string writeYemUserProductAzureTable, string writeUserAssetRatioAzureTable, string writeAssetUserRatioAzureTable) { string yemUserPurchase = ConfigurationManager.AppSettings["PurchasePartitionKey"]; Console.WriteLine("创建CloudTable对象"); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["BlobConnectionString"]); CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); tableClient.DefaultRequestOptions.RetryPolicy = new ExponentialRetry(2.Seconds(), 6); tableClient.DefaultRequestOptions.MaximumExecutionTime = 2.Minutes(); tableClient.DefaultRequestOptions.ServerTimeout = 2.Minutes(); CloudTable cloudOnSellAssetTable = tableClient.GetTableReference(assetAzureTableName); //查询所有资产信息 TableQuery <OnSellAssetDto> queryOnSellAsset = new TableQuery <OnSellAssetDto>() .Where("RemainderTotal gt 0 and IsLock eq false"); List <OnSellAssetDto> onSellAssetDtos = noIncludeAssetIds.Any() ? cloudOnSellAssetTable.ExecuteQuery(queryOnSellAsset).Where(p => !noIncludeAssetIds.Contains(p.OnSellAssetId)).ToList() : cloudOnSellAssetTable.ExecuteQuery(queryOnSellAsset).OrderBy(p => p.RemainderTotal).ToList(); //获取购买信息 CloudTable cloudPurchaseOrderTable = tableClient.GetTableReference(yemUserProductAzureTableName); TableQuery <YemUserProductDto> queryPurchaseOrder; // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (maxAmount > 0) { //queryPurchaseOrder = new TableQuery<YemUserProductDto>() // .Where($"PartitionKey eq '{yemUserPurchase}' and RemainingAmount ge {minAmount} and RemainingAmount lt {maxAmount} and IsLock eq false"); string startsWithCondition = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, yemUserPurchase), TableOperators.And, TableQuery.GenerateFilterConditionForLong("RemainingAmount", QueryComparisons.GreaterThanOrEqual, minAmount)); string filterCondition = TableQuery.CombineFilters( TableQuery.GenerateFilterConditionForLong("RemainingAmount", QueryComparisons.LessThan, maxAmount), TableOperators.And, startsWithCondition ); string endCondition = TableQuery.CombineFilters( TableQuery.GenerateFilterConditionForBool("IsLock", QueryComparisons.Equal, false), TableOperators.And, filterCondition ); queryPurchaseOrder = new TableQuery <YemUserProductDto>().Where(endCondition); } else { queryPurchaseOrder = new TableQuery <YemUserProductDto>() .Where($"PartitionKey eq '{yemUserPurchase}' and RemainingAmount gt 0 and IsLock eq false"); } var yemUserProductDtos = cloudPurchaseOrderTable.ExecuteQuery(queryPurchaseOrder).OrderByDescending(p => p.RemainingAmount).ToList(); Console.WriteLine("要处理的购买订单条数=" + yemUserProductDtos.Count()); Console.WriteLine("待分配的资产数=" + onSellAssetDtos.Count()); List <OnSellAssetDto> oldOnSellAssetDtos = onSellAssetDtos; if (!oldOnSellAssetDtos.Any()) { Console.WriteLine("没有处理的资产"); return; } int index = 0; foreach (var item in yemUserProductDtos) { index++; var addUserAssetRatios = new List <UserAssetRatio>(); //记录每笔购买产生的比例 用户资产关系 var addAssetUserRatios = new List <UserAssetRatio>(); //记录每笔购买产生的比例 资产用户关系 List <OnSellAssetDto> modifyOnSellAssets = new List <OnSellAssetDto>(); //记录每笔购买使用的资产 YemUserProductDto newYemUserProductDto = null; Console.WriteLine("总共处理的条数为:" + yemUserProductDtos.Count + ",当前处理的条数:" + index); Console.WriteLine("还需要处理的资产数=" + oldOnSellAssetDtos.Count()); long sumAssetCount = oldOnSellAssetDtos.Sum(p => p.RemainderTotal); long waitingDealAmount = item.RemainingAmount; //购买订单待处理的金额 for (int i = oldOnSellAssetDtos.Count - 1; i >= 0; i--) { var assetItem = oldOnSellAssetDtos[i]; long allocateAmount = AllocateAmountByAsset(waitingDealAmount, assetItem.RemainderTotal, sumAssetCount); if (item.RemainingAmount < allocateAmount) { allocateAmount = item.RemainingAmount; } if (assetItem.RemainderTotal < allocateAmount) { allocateAmount = assetItem.RemainderTotal; } if (allocateAmount <= 0) { continue; } var userAssetRatioTuple = CreateUserAssetRatio(item, assetItem, allocateAmount); //第一个是用户资产关系 第二个是资产用户关系 addUserAssetRatios.Add(userAssetRatioTuple.Item1); addAssetUserRatios.Add(userAssetRatioTuple.Item2); var updateOnSellAsset = BuildOnSellAsset(assetItem, allocateAmount); //修改资产的信息 modifyOnSellAssets.Add(updateOnSellAsset); newYemUserProductDto = BuildYemUserProduct(item, allocateAmount); //修改购买订单需要配置的参数 assetItem.RemainderTotal -= allocateAmount; if (assetItem.RemainderTotal == 0) { oldOnSellAssetDtos.Remove(assetItem); } } //保存数据库 await InsertOrReplaceAzureTable(tableClient, newYemUserProductDto, addUserAssetRatios, addAssetUserRatios, modifyOnSellAssets, writeAssetAzureTable, writeYemUserProductAzureTable, writeUserAssetRatioAzureTable, writeAssetUserRatioAzureTable); if (!oldOnSellAssetDtos.Any()) { Console.WriteLine("没有处理的资产"); break; } } }
private static async Task DealUserToAsset(long minAmount, long maxAmount, string yemUserProductAzureTableName, string writeAssetAzureTable, string writeYemUserProductAzureTable, CloudTableClient tableClient, string yemUserPurchase, List <OnSellAssetDto> onSellAssetDtos) { CloudTable cloudPurchaseOrderTable = tableClient.GetTableReference(yemUserProductAzureTableName); TableQuery <YemUserProductDto> queryPurchaseOrder; // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (maxAmount > 0) { //queryPurchaseOrder = new TableQuery<YemUserProductDto>() // .Where($"PartitionKey eq '{yemUserPurchase}' and RemainingAmount ge {minAmount} and RemainingAmount lt {maxAmount} and IsLock eq false"); string startsWithCondition = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, yemUserPurchase), TableOperators.And, TableQuery.GenerateFilterConditionForLong("RemainingAmount", QueryComparisons.GreaterThanOrEqual, minAmount)); string filterCondition = TableQuery.CombineFilters( TableQuery.GenerateFilterConditionForLong("RemainingAmount", QueryComparisons.LessThan, maxAmount), TableOperators.And, startsWithCondition ); string endCondition = TableQuery.CombineFilters( TableQuery.GenerateFilterConditionForBool("IsLock", QueryComparisons.Equal, false), TableOperators.And, filterCondition ); queryPurchaseOrder = new TableQuery <YemUserProductDto>().Where(endCondition); } else { queryPurchaseOrder = new TableQuery <YemUserProductDto>() .Where($"PartitionKey eq '{yemUserPurchase}' and RemainingAmount gt 0 and IsLock eq false"); } var yemUserProductDtos = cloudPurchaseOrderTable.ExecuteQuery(queryPurchaseOrder).OrderByDescending(p => p.RemainingAmount).ToList(); yemUserProductDtos = yemUserProductDtos.Where(p => p.RemainingAmount > 0).ToList(); Console.WriteLine("要处理的购买订单条数=" + yemUserProductDtos.Count()); Console.WriteLine("待分配的资产数=" + onSellAssetDtos.Count()); List <OnSellAssetDto> oldOnSellAssetDtos = onSellAssetDtos; if (!oldOnSellAssetDtos.Any()) { Console.WriteLine("没有处理的资产"); return; } int index = 0; //int syncIndex = 0; //备份索引 Stopwatch s = new Stopwatch(); s.Start(); List <OnSellAssetDto> lastOnSellAssetDtos = new List <OnSellAssetDto>(); //上一次的资产情况 foreach (var item in yemUserProductDtos) { if (!lastOnSellAssetDtos.Any()) //第一次 { lastOnSellAssetDtos.AddRange(oldOnSellAssetDtos.MapToOnSellAssetList()); } index++; var addUserAssetRatios = new List <UserAssetRatio>(); //记录每笔购买产生的比例 用户资产关系 List <OnSellAssetDto> modifyOnSellAssets = new List <OnSellAssetDto>(); //记录每笔购买使用的资产 var addAssetUserRatios = new List <UserAssetRatio>(); //记录每笔购买产生的比例 资产用户关系 YemUserProductDto newYemUserProductDto = null; Console.WriteLine("总共处理的条数为:" + yemUserProductDtos.Count + ",当前处理的条数:" + index); Console.WriteLine("还需要处理的资产数=" + oldOnSellAssetDtos.Count()); long sumAssetCount = oldOnSellAssetDtos.Sum(p => p.RemainderTotal); long waitingDealAmount = item.RemainingAmount; //购买订单待处理的金额 long currentDealPurchaseAmount = 0; //本次处理的金额 for (int i = oldOnSellAssetDtos.Count - 1; i >= 0; i--) { if (item.RemainingAmount == 0) { break; } var assetItem = oldOnSellAssetDtos[i]; long allocateAmount = AllocateAmountByAsset(waitingDealAmount, assetItem.RemainderTotal, sumAssetCount); if (item.RemainingAmount < allocateAmount) { allocateAmount = item.RemainingAmount; } if (assetItem.RemainderTotal < allocateAmount) { allocateAmount = assetItem.RemainderTotal; } if (allocateAmount <= 0) { continue; } item.RemainingAmount -= allocateAmount; currentDealPurchaseAmount += allocateAmount; //统计该订单分配的总金额 assetItem.RemainderTotal -= allocateAmount; var userAssetRatioTuple = CreateUserAssetRatio(item, assetItem, allocateAmount); //第一个是用户资产关系 第二个是资产用户关系 addUserAssetRatios.Add(userAssetRatioTuple.Item1); addAssetUserRatios.Add(userAssetRatioTuple.Item2); var updateOnSellAsset = BuildOnSellAsset(assetItem, allocateAmount); //修改资产的信息 modifyOnSellAssets.Add(updateOnSellAsset); if (assetItem.RemainderTotal == 0) { oldOnSellAssetDtos.Remove(assetItem); } } newYemUserProductDto = BuildYemUserProduct(item, currentDealPurchaseAmount); //修改购买订单需要配置的参数 //保存数据库 await InsertOrReplaceAzureTable(tableClient, newYemUserProductDto, addUserAssetRatios, addAssetUserRatios, modifyOnSellAssets, writeAssetAzureTable, writeYemUserProductAzureTable, currentDealPurchaseAmount, lastOnSellAssetDtos); lastOnSellAssetDtos = new List <OnSellAssetDto>(); lastOnSellAssetDtos.AddRange(modifyOnSellAssets.MapToOnSellAssetList()); //记录上一次资产列表 if (!oldOnSellAssetDtos.Any()) { Console.WriteLine("没有处理的资产"); break; } } s.Stop(); Console.WriteLine("End:" + s.ElapsedMilliseconds); }
/// <summary> /// 记错误日志 /// </summary> /// <param name="lastOnSellAssetDtos"></param> /// <param name="assetuserRatios"></param> /// <param name="yemUserProductDto"></param> /// <param name="currentDealPurchaseAmount"></param> /// <param name="userAssetRatios"></param> /// <returns></returns> private static async Task AddLogAsync(List <OnSellAssetDto> lastOnSellAssetDtos, List <UserAssetRatio> userAssetRatios, List <UserAssetRatio> assetuserRatios, YemUserProductDto yemUserProductDto, long currentDealPurchaseAmount) { ResetYemUserPurchase resetYemUserPurchase = new ResetYemUserPurchase(); resetYemUserPurchase.OrderId = yemUserProductDto.OrderId; resetYemUserPurchase.YemUserProductDto = yemUserProductDto.MapToYemUserProductDto(); resetYemUserPurchase.CurrentDealPurchaseAmount = currentDealPurchaseAmount; Logger.Logw("ErrorOldLastOnSellAsset", lastOnSellAssetDtos.ToJson()); Logger.Logw("ErrorOldYemUserPurchase", resetYemUserPurchase.ToJson()); Logger.Logw("ErrorOldUserAssetRatio", userAssetRatios.ToJson()); Logger.Logw("ErrorOldAssetUserRatio", assetuserRatios.ToJson()); //记Redis await RedisHelper.SetRedisOnSellAssetByOldAsync(lastOnSellAssetDtos); await RedisHelper.SetRedisUserAssetRatioByOldAsync(userAssetRatios); await RedisHelper.SetRedisAssetUserRatioByOldAsync(assetuserRatios); await RedisHelper.SetRedisYemUserPurchaseByOldAsync(resetYemUserPurchase); }
/// <summary> /// 出错了之后,资产、订单、用户比例还原 /// </summary> /// <param name="tableClient"></param> /// <param name="writeAssetAzureTable"></param> /// <param name="writeYemUserProductAzureTable"></param> /// <param name="lastOnSellAssetDtos"></param> /// <param name="addUserAssetRatios"></param> /// <param name="addAssetUserRatios"></param> /// <param name="yemUserProductDto"></param> /// <param name="currentDealPurchaseAmount"></param> /// <param name="batchNum"></param> /// <returns></returns> public static async Task RollerBackAsync(CloudTableClient tableClient, string writeAssetAzureTable, string writeYemUserProductAzureTable, List <OnSellAssetDto> lastOnSellAssetDtos, List <UserAssetRatio> addUserAssetRatios, List <UserAssetRatio> addAssetUserRatios, YemUserProductDto yemUserProductDto, long currentDealPurchaseAmount, int batchNum) { //资产还原 await AddOnSellAsset(tableClient, lastOnSellAssetDtos, writeAssetAzureTable, batchNum); //lastOnSellAssetDtos为上一次的资产列表 if (addUserAssetRatios.Any()) { await RedisHelper.RemoveRedisUserAssetRatioAsync(addUserAssetRatios); } if (addUserAssetRatios.Any()) { await RedisHelper.RemoveRedisAssetUserRatioAsync(addAssetUserRatios); } //订单还原 await ResetPurchaseAsync(tableClient, writeYemUserProductAzureTable, yemUserProductDto, currentDealPurchaseAmount); //根据处理的金额还原 }
//购买订单还原 public static async Task ResetPurchaseAsync(CloudTableClient tableClient, string writeYemUserProductAzureTable, YemUserProductDto yemUserProductDto, long currentDealPurchaseAmount) { var resetPurchase = yemUserProductDto.MapToYemUserProductDto(); resetPurchase.RemainingAmount += currentDealPurchaseAmount; resetPurchase.Allocated -= currentDealPurchaseAmount; resetPurchase.Status = resetPurchase.PurchaseMoney == resetPurchase.Allocated ? PurchaseOrderStatus.AllocationComplete.ToEnumInteger() : PurchaseOrderStatus.AllocationOn.ToEnumInteger(); resetPurchase.WaitingBankBackAmount = 0; resetPurchase.UpdatedTime = DateTime.UtcNow.ToChinaStandardTime(); await AddYemUserPurchase(tableClient, yemUserProductDto, writeYemUserProductAzureTable); }
/// <summary> /// 更新用户比例信息 /// </summary> /// <param name="tableClient"></param> /// <param name="yemUserProductDto"></param> /// <param name="addUserAssetRatios"></param> /// <param name="addAssetUserRatios"></param> /// <param name="modifyOnSellAssetDtos"></param> /// <param name="writeAssetAzureTable"></param> /// <param name="writeYemUserProductAzureTable"></param> /// <param name="currentDealPurchaseAmount"></param> /// <param name="lastOnSellAssetDtos"></param> /// <param name="batchNum"></param> /// InsertOrReplaceAzureTable public static async Task InsertOrReplaceAzureTable(CloudTableClient tableClient, YemUserProductDto yemUserProductDto, List <UserAssetRatio> addUserAssetRatios, List <UserAssetRatio> addAssetUserRatios, List <OnSellAssetDto> modifyOnSellAssetDtos, string writeAssetAzureTable, string writeYemUserProductAzureTable, long currentDealPurchaseAmount, List <OnSellAssetDto> lastOnSellAssetDtos, int batchNum = 100) { try { await AddOnSellAsset(tableClient, modifyOnSellAssetDtos, writeAssetAzureTable, batchNum); if (addUserAssetRatios.Any()) { await RedisHelper.SetRedisUserAssetRatioAsync(addUserAssetRatios); } if (addAssetUserRatios.Any()) { await RedisHelper.SetRedisAssetUserRatioAsync(addAssetUserRatios); } //购买 await AddYemUserPurchase(tableClient, yemUserProductDto, writeYemUserProductAzureTable); int a = 0; int d = 10 / a; } catch (Exception e) { Console.WriteLine("出错了,正在还原数据"); Logger.Logw("ErrorMessage", "订单号" + yemUserProductDto.OrderId + " " + e.ToJson()); //记日志 await AddLogAsync(lastOnSellAssetDtos, addUserAssetRatios, addAssetUserRatios, yemUserProductDto, currentDealPurchaseAmount); //先还原 // await RollerBackAsync(tableClient, writeAssetAzureTable, writeYemUserProductAzureTable, lastOnSellAssetDtos, addUserAssetRatios, addAssetUserRatios, yemUserProductDto, currentDealPurchaseAmount, batchNum); Console.WriteLine("还原数据完成"); //记日志 throw e; } }