This commit is contained in:
tongfei
2024-04-20 11:16:47 +08:00
parent 356253d154
commit 57acf1b699
4 changed files with 61 additions and 38 deletions

View File

@@ -2,7 +2,9 @@
using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
using StackExchange.Redis;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@@ -25,6 +27,7 @@ using WMS.Web.Domain.Infrastructure;
using WMS.Web.Domain.IService; using WMS.Web.Domain.IService;
using WMS.Web.Domain.IService.Public; using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Mappers; using WMS.Web.Domain.Mappers;
using WMS.Web.Domain.Options;
using WMS.Web.Domain.Values; using WMS.Web.Domain.Values;
using WMS.Web.Domain.Values.Erp; using WMS.Web.Domain.Values.Erp;
@@ -51,9 +54,11 @@ namespace WMS.Web.Domain.Services
private readonly IBoxInventoryRepositories _boxInventoryRepositories; private readonly IBoxInventoryRepositories _boxInventoryRepositories;
private readonly ILogger<InStockService> _logger; private readonly ILogger<InStockService> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly AppOptions _options;
private ConnectionMultiplexer redisMultiplexer;
public StackExchange.Redis.IDatabase _redisDb = null;
private readonly ConcurrentDictionary<int, SemaphoreSlim> _locks = new ConcurrentDictionary<int, SemaphoreSlim>(); public InStockService(IMapper mapper, IOptions<AppOptions> options, ISerialNumbersRepositories serialNumbersRepositories, IErpService erpService, IBoxInventoryService boxInventoryService, ISerialNumberService serialNumberService, ILoginService loginService, IBoxRepositories boxRepositories,
public InStockService(IMapper mapper, ISerialNumbersRepositories serialNumbersRepositories, IErpService erpService, IBoxInventoryService boxInventoryService, ISerialNumberService serialNumberService, ILoginService loginService, IBoxRepositories boxRepositories,
IBasicsRepositories basicsRepositories, IErpBasicDataExtendService erpBasicDataExtendService, IChangeMoveBoxService changeMoveBoxService, IInStockTaskBoxRepositories inStockTaskBoxRepositories, IBasicsRepositories basicsRepositories, IErpBasicDataExtendService erpBasicDataExtendService, IChangeMoveBoxService changeMoveBoxService, IInStockTaskBoxRepositories inStockTaskBoxRepositories,
IInStockRepositories inStockRepositories, IInStockTaskRepositories inStockTaskRepositories, IBoxInventoryRepositories boxInventoryRepositories, ILogger<InStockService> logger, IServiceScopeFactory serviceScopeFactory) IInStockRepositories inStockRepositories, IInStockTaskRepositories inStockTaskRepositories, IBoxInventoryRepositories boxInventoryRepositories, ILogger<InStockService> logger, IServiceScopeFactory serviceScopeFactory)
{ {
@@ -73,6 +78,9 @@ namespace WMS.Web.Domain.Services
_erpBasicDataExtendService = erpBasicDataExtendService; _erpBasicDataExtendService = erpBasicDataExtendService;
_serialNumbersRepositories = serialNumbersRepositories; _serialNumbersRepositories = serialNumbersRepositories;
_boxInventoryRepositories = boxInventoryRepositories; _boxInventoryRepositories = boxInventoryRepositories;
_options = options?.Value;
redisMultiplexer = ConnectionMultiplexer.Connect(_options.RedisConnectionString);
_redisDb = redisMultiplexer.GetDatabase();
} }
/// <summary> /// <summary>
@@ -133,39 +141,50 @@ namespace WMS.Web.Domain.Services
/// <returns></returns> /// <returns></returns>
public async Task<Result> Shelf(PurchaseShelfRequest instock, LoginInDto loginInfo) public async Task<Result> Shelf(PurchaseShelfRequest instock, LoginInDto loginInfo)
{ {
var taskId= instock.Details.Select(x => x.TaskId).FirstOrDefault(); var taskId = instock.Details.Select(x => x.TaskId).FirstOrDefault();
var taskLock = _locks.GetOrAdd(taskId, _ => new SemaphoreSlim(1, 1)); // 构建 Redis 锁的键名
await taskLock.WaitAsync(); string lockKey = $"lock:taskid{taskId}";
try // 构建 Redis 锁的值,用于标识锁的持有者
string lockValue = Guid.NewGuid().ToString();
// 获取 Redis 锁,设置超时时间为 10 秒
if (await _redisDb.LockTakeAsync(lockKey, lockValue, TimeSpan.FromSeconds(10)))
{ {
IDbContextTransaction _transaction = _basicsRepositories.GetTransaction(); try
bool isRollback = false;
bool isTransaction = false;
//1.添加入库单同步金蝶在save方法里面进行
var save_result = await this.ShelfSave(instock, InstockType.Purchase, loginInfo, isTransaction);
if (!save_result.IsSuccess) isRollback = true;
//实体
var entity = save_result.Data;
//提交事务
var isSuccess = _basicsRepositories.CommitTransaction(isRollback, _transaction);
if (!isSuccess)
return save_result;
//同步金蝶
if (entity.Type == InstockType.Purchase)
{ {
OperateRequest oRequest = new OperateRequest(); IDbContextTransaction _transaction = _basicsRepositories.GetTransaction();
oRequest.Ids.Add(entity.Id); bool isRollback = false;
await Sync(oRequest, loginInfo, false); bool isTransaction = false;
//1.添加入库单同步金蝶在save方法里面进行
var save_result = await this.ShelfSave(instock, InstockType.Purchase, loginInfo, isTransaction);
if (!save_result.IsSuccess) isRollback = true;
//实体
var entity = save_result.Data;
//提交事务
var isSuccess = _basicsRepositories.CommitTransaction(isRollback, _transaction);
if (!isSuccess)
return save_result;
//同步金蝶
if (entity.Type == InstockType.Purchase)
{
OperateRequest oRequest = new OperateRequest();
oRequest.Ids.Add(entity.Id);
await Sync(oRequest, loginInfo, false);
}
return Result.ReSuccess();
}
finally
{
// 释放 Redis 锁
await _redisDb.LockReleaseAsync(lockKey, lockValue);
} }
return Result.ReSuccess();
} }
finally else
{ {
taskLock.Release(); return Result.ReFailure(ResultCodes.Concurrent_Instock);
} }

View File

@@ -37,13 +37,15 @@ namespace WMS.Web.Domain.Services
var delete_ids = new List<int>(); var delete_ids = new List<int>();
var t_boxIds = boxIds.Distinct().ToList(); var t_boxIds = boxIds.Distinct().ToList();
var list= await _inStockTaskBoxRepositories.GetListBy(t_boxIds); var list= await _inStockTaskBoxRepositories.GetListBy(t_boxIds);
var boxInvetList = await _boxInventoryRepositories.GetList(t_boxIds);
foreach (var item in list) delete_ids= list.Select(x => x.Id).ToList();
{ //var boxInvetList = await _boxInventoryRepositories.GetList(t_boxIds);
var isHave= boxInvetList.Where(x => x.BoxId == item.BoxId).Any(); //foreach (var item in list)
if (!isHave) //{
delete_ids.Add(item.Id); // var isHave= boxInvetList.Where(x => x.BoxId == item.BoxId).Any();
} // if (!isHave)
// delete_ids.Add(item.Id);
//}
if (delete_ids.Count != 0) if (delete_ids.Count != 0)
{ {

View File

@@ -22,6 +22,8 @@ namespace WMS.Web.Domain.Services.Public
db = redisMultiplexer.GetDatabase(); db = redisMultiplexer.GetDatabase();
} }
#region String #region String
/// <summary> /// <summary>
/// 保存单个key value /// 保存单个key value

View File

@@ -24,7 +24,7 @@ namespace WMS.Web.Domain.Values
public static ValueTuple<int, string> NoDateError = (40005, "数据不存在"); public static ValueTuple<int, string> NoDateError = (40005, "数据不存在");
public static ValueTuple<int, string> SourceBillNoDateError = (40005, "来源单不存在,请核对后再试"); public static ValueTuple<int, string> SourceBillNoDateError = (40005, "来源单不存在,请核对后再试");
public static ValueTuple<int, string> Concurrent_Instock = (80005, "该任务单正在处理中"); public static ValueTuple<int, string> Concurrent_Instock = (80005, "该来源单正在处理中");
/// <summary> /// <summary>
/// 没有菜单权限,无法登录 /// 没有菜单权限,无法登录