xxyy
2025-03-05 6d578d016127db97d6f981ff18614ef52a2e0ede
添加缓存服务及相关功能支持

- 新增二进制文件。
- 在 `CacheConst.cs` 中定义 Redis 常量。
- 在 `LinqExtension.cs` 中添加 `ContainsAll` 扩展方法。
- 在 `ObjectExtension.cs` 中实现多个 JSON 处理扩展方法。
- 更新 `ISimpleCacheHashService.cs` 和 `ISimpleCacheService.cs` 接口,增加 HashMap 操作方法。
- 添加 `CacheSettingsOptions.cs` 类以配置 Redis 设置。
- 实现内存和 Redis 缓存服务。
- 更新项目引用,确保 `WIDESEA_Cache` 项目被正确引用。
- 在 `Program.cs` 中配置缓存服务的依赖注入和 Redis 连接验证。
- 更新 `appsettings.json` 以包含缓存设置。
已修改8个文件
已添加13个文件
1189 ■■■■■ 文件已修改
Code Management/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/copilot-chat/bef6627e/sessions/85d61362-b687-48eb-8099-932a817719a7 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Const/CacheConst.cs 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/LinqExtension.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/ObjectExtension.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/GlobalUsing.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheHashService.cs 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheService.cs 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Options/CacheSettingsOptions.cs 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheHashService.cs 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheService.cs 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheHashService.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheService.cs 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/WIDESEA_Cache.csproj 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/AspNetCoreSchedule.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/WIDESEA_StorageTaskServices.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/obj/Debug/net6.0/WIDESEA_WMSServer.MvcApplicationPartsAssemblyInfo.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code Management/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/copilot-chat/bef6627e/sessions/85d61362-b687-48eb-8099-932a817719a7
Binary files differ
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Const/CacheConst.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
namespace WIDESEA_Cache;
/// <summary>
/// Redis常量
/// </summary>
public class CacheConst
{
    /// <summary>
    /// Redis Key前缀(可删除)
    /// </summary>
    public const string Cache_Prefix_Web = "WIDESEA_WMSServerWeb:";
    /// <summary>
    /// Redis Key前缀(需要持久化,不随系统重启删除)
    /// </summary>
    public const string Cache_Prefix = "WIDESEA_WMSServer:";
    /// <summary>
    /// Redis Hash类型
    /// </summary>
    public const string Cache_Hash = "Hash";
    /// <summary>
    /// ç³»ç»Ÿé…ç½®è¡¨ç¼“å­˜Key
    /// </summary>
    public const string Cache_DevConfig = Cache_Prefix_Web + "DevConfig:";
    /// <summary>
    /// ç™»å½•验证码缓存Key
    /// </summary>
    public const string Cache_Captcha = Cache_Prefix_Web + "Captcha:";
    /// <summary>
    /// ç”¨æˆ·è¡¨ç¼“å­˜Key
    /// </summary>
    public const string Cache_SysUser = Cache_Prefix_Web + "SysUser";
    /// <summary>
    /// ç”¨æˆ·æ‰‹æœºå·å…³ç³»ç¼“å­˜Key
    /// </summary>
    public const string Cache_SysUserPhone = Cache_Prefix_Web + "SysUserPhone";
    /// <summary>
    /// ç”¨æˆ·Token缓存Key
    /// </summary>
    public const string Cache_UserToken = Cache_Prefix + "UserToken";
    /// <summary>
    /// WMS库存缓存Key
    /// </summary>Cache_AutoModel
    public const string Cache_DtStockInfo = Cache_Prefix + "DtStockInfo";
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/LinqExtension.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
namespace WIDESEA_Cache;
/// <summary>
/// Linq扩展
/// </summary>
public static class LinqExtension
{
    /// <summary>
    /// æ˜¯å¦éƒ½åŒ…含
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="first">第一个列表</param>
    /// <param name="secend">第二个列表</param>
    /// <returns></returns>
    public static bool ContainsAll<T>(this List<T> first, List<T> secend)
    {
        return secend.All(s => first.Any(f => f.Equals(s)));
    }
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/ObjectExtension.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace WIDESEA_Cache;
/// <summary>
/// object拓展
/// </summary>
public static class ObjectExtension
{
    /// <summary>
    /// json字符串序列化
    /// </summary>
    /// <param name="json"></param>
    /// <returns></returns>
    public static object ToObject(this string json)
    {
        return string.IsNullOrEmpty(json) ? null : JsonConvert.DeserializeObject(json);
    }
    /// <summary>
    /// json字符串序列化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="json"></param>
    /// <returns></returns>
    public static T ToObject<T>(this string json)
    {
        if (json != null)
        {
            json = json.Replace("&nbsp;", "");
            return JsonConvert.DeserializeObject<T>(json);
        }
        else return default;
    }
    /// <summary>
    /// json字符串序列化
    /// </summary>
    /// <param name="json"></param>
    /// <returns></returns>
    public static JObject ToJObject(this string json)
    {
        return json == null ? JObject.Parse("{}") : JObject.Parse(json.Replace("&nbsp;", ""));
    }
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/GlobalUsing.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
global using Masuit.Tools;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.Extensions.DependencyInjection;
global using NewLife.Caching;
global using NewLife.Serialization;
global using SimpleRedis;
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheHashService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
namespace WIDESEA_Cache;
/// <summary>
/// ç¼“存服务
/// </summary>
public partial interface ISimpleCacheService
{
    /// <summary>
    /// æ·»åŠ ä¸€æ¡æ•°æ®åˆ°HashMap
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key">键</param>
    /// <param name="hashKey">hash列表里的Key</param>
    /// <param name="value">值</param>
    void HashAdd<T>(string key, string hashKey, T value);
    /// <summary>
    /// æ·»åŠ å¤šæ¡æ•°æ®åˆ°HashMap
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key">键</param>
    /// <param name="dic">键值对字典</param>
    /// <returns></returns>
    bool HashSet<T>(string key, Dictionary<string, T> dic);
    /// <summary>
    /// ä»ŽHashMap中删除数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key">键</param>
    /// <param name="fields">hash键列表</param>
    /// <returns>执行结果</returns>
    int HashDel<T>(string key, params string[] fields);
    /// <summary>
    /// æ ¹æ®é”®èŽ·å–hash列表中的值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key">键</param>
    /// <param name="fields">hash键列表</param>
    /// <returns>数据列表</returns>
    List<T> HashGet<T>(string key, params string[] fields);
    /// <summary>
    /// æ ¹æ®é”®èŽ·å–hash列表中的值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key">键</param>
    /// <param name="field">hash键</param>
    /// <returns></returns>
    T HashGetOne<T>(string key, string field);
    /// <summary>
    /// èŽ·å–æ‰€æœ‰é”®å€¼å¯¹
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key">键</param>
    /// <returns>数据字典</returns>
    IDictionary<string, T> HashGetAll<T>(string key);
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,180 @@
namespace WIDESEA_Cache;
/// <summary>
/// ç¼“存服务
/// </summary>
public partial interface ISimpleCacheService
{
    #region åŸºç¡€æ“ä½œ
    /// <summary>是否包含缓存项</summary>
    /// <param name="key"></param>
    /// <returns></returns>
    bool ContainsKey(string key);
    /// <summary>设置缓存项</summary>
    /// <param name="key">键</param>
    /// <param name="value">值</param>
    /// <param name="expire">过期时间,秒。小于0时采用默认缓存时间</param>
    /// <returns></returns>
    bool Set<T>(string key, T value, int expire = -1);
    /// <summary>设置缓存项</summary>
    /// <param name="key">键</param>
    /// <param name="value">值</param>
    /// <param name="expire">过期时间</param>
    /// <returns></returns>
    bool Set<T>(string key, T value, TimeSpan expire);
    /// <summary>获取缓存项</summary>
    /// <param name="key">键</param>
    /// <returns></returns>
    T Get<T>(string key);
    /// <summary>批量移除缓存项</summary>
    /// <param name="keys">键集合</param>
    /// <returns></returns>
    int Remove(params string[] keys);
    /// <summary>清空所有缓存项</summary>
    void Clear();
    /// <summary>设置缓存项有效期</summary>
    /// <param name="key">键</param>
    /// <param name="expire">过期时间</param>
    bool SetExpire(string key, TimeSpan expire);
    /// <summary>获取缓存项有效期</summary>
    /// <param name="key">键</param>
    /// <returns></returns>
    TimeSpan GetExpire(string key);
    /// <summary>
    /// æ¨¡ç³Šåˆ é™¤
    /// </summary>
    /// <param name="pattern">匹配关键字</param>
    void DelByPattern(string pattern);
    #endregion åŸºç¡€æ“ä½œ
    #region é›†åˆæ“ä½œ
    /// <summary>批量获取缓存项</summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="keys"></param>
    /// <returns></returns>
    IDictionary<string, T> GetAll<T>(IEnumerable<string> keys);
    /// <summary>批量设置缓存项</summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="values"></param>
    /// <param name="expire">过期时间,秒。小于0时采用默认缓存时间</param>
    void SetAll<T>(IDictionary<string, T> values, int expire = -1);
    /// <summary>获取列表</summary>
    /// <typeparam name="T">元素类型</typeparam>
    /// <param name="key">键</param>
    /// <returns></returns>
    IList<T> GetList<T>(string key);
    /// <summary>获取哈希</summary>
    /// <typeparam name="T">元素类型</typeparam>
    /// <param name="key">键</param>
    /// <returns></returns>
    IDictionary<string, T> GetDictionary<T>(string key);
    /// <summary>获取队列</summary>
    /// <typeparam name="T">元素类型</typeparam>
    /// <param name="key">键</param>
    /// <returns></returns>
    IProducerConsumer<T> GetQueue<T>(string key);
    /// <summary>获取栈</summary>
    /// <typeparam name="T">元素类型</typeparam>
    /// <param name="key">键</param>
    /// <returns></returns>
    IProducerConsumer<T> GetStack<T>(string key);
    /// <summary>获取Set</summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key"></param>
    /// <returns></returns>
    ICollection<T> GetSet<T>(string key);
    #endregion é›†åˆæ“ä½œ
    #region é«˜çº§æ“ä½œ
    /// <summary>添加,已存在时不更新</summary>
    /// <typeparam name="T">值类型</typeparam>
    /// <param name="key">键</param>
    /// <param name="value">值</param>
    /// <param name="expire">过期时间,秒。小于0时采用默认缓存时间</param>
    /// <returns></returns>
    bool Add<T>(string key, T value, int expire = -1);
    /// <summary>设置新值并获取旧值,原子操作</summary>
    /// <remarks>
    /// å¸¸å¸¸é…åˆIncrement使用,用于累加到一定数后重置归零,又避免多线程冲突。
    /// </remarks>
    /// <typeparam name="T">值类型</typeparam>
    /// <param name="key">键</param>
    /// <param name="value">值</param>
    /// <returns></returns>
    T Replace<T>(string key, T value);
    /// <summary>尝试获取指定键,返回是否包含值。有可能缓存项刚好是默认值,或者只是反序列化失败,解决缓存穿透问题</summary>
    /// <typeparam name="T">值类型</typeparam>
    /// <param name="key">键</param>
    /// <param name="value">值。即使有值也不一定能够返回,可能缓存项刚好是默认值,或者只是反序列化失败</param>
    /// <returns>返回是否包含值,即使反序列化失败</returns>
    bool TryGetValue<T>(string key, out T value);
    /// <summary>累加,原子操作</summary>
    /// <param name="key">键</param>
    /// <param name="value">变化量</param>
    /// <returns></returns>
    long Increment(string key, long value);
    /// <summary>累加,原子操作</summary>
    /// <param name="key">键</param>
    /// <param name="value">变化量</param>
    /// <returns></returns>
    double Increment(string key, double value);
    /// <summary>递减,原子操作</summary>
    /// <param name="key">键</param>
    /// <param name="value">变化量</param>
    /// <returns></returns>
    long Decrement(string key, long value);
    /// <summary>递减,原子操作</summary>
    /// <param name="key">键</param>
    /// <param name="value">变化量</param>
    /// <returns></returns>
    double Decrement(string key, double value);
    #endregion é«˜çº§æ“ä½œ
    #region äº‹åŠ¡
    /// <summary>提交变更。部分提供者需要刷盘</summary>
    /// <returns></returns>
    int Commit();
    /// <summary>申请分布式锁</summary>
    /// <param name="key">要锁定的key</param>
    /// <param name="msTimeout">锁等待时间,单位毫秒</param>
    /// <returns></returns>
    IDisposable AcquireLock(string key, int msTimeout);
    /// <summary>申请分布式锁</summary>
    /// <param name="key">要锁定的key</param>
    /// <param name="msTimeout">锁等待时间,申请加锁时如果遇到冲突则等待的最大时间,单位毫秒</param>
    /// <param name="msExpire">锁过期时间,超过该时间如果没有主动释放则自动释放锁,必须整数秒,单位毫秒</param>
    /// <param name="throwOnFailure">失败时是否抛出异常,如果不抛出异常,可通过返回null得知申请锁失败</param>
    /// <returns></returns>
    IDisposable AcquireLock(string key, int msTimeout, int msExpire, bool throwOnFailure);
    #endregion äº‹åŠ¡
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Options/CacheSettingsOptions.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
//using Furion.ConfigurableOptions;
using WIDESEA_Core.Core;
namespace WIDESEA_Cache;
/// <summary>
/// ç¼“存设置
/// </summary>
public class CacheSettingsOptions : IConfigurableOptions
{
    /// <summary>
    /// ä½¿ç”¨Redis
    /// </summary>
    public bool UseRedis { get; set; }
    /// <summary>
    /// æ˜¯å¦æ¯æ¬¡å¯åŠ¨éƒ½æ¸…ç©º
    /// </summary>
    public RedisSettings RedisSettings { get; set; }
}
/// <summary>
/// Redis设置
/// </summary>
public class RedisSettings
{
    /// <summary>
    /// è¿žæŽ¥åœ°å€
    /// </summary>
    public string Address { get; set; }
    /// <summary>
    /// å¯†ç 
    /// </summary>
    public string Password { get; set; }
    /// <summary>
    /// æ•°æ®åº“
    /// </summary>
    public int Db { get; set; } = 0;
    /// <summary>
    /// æ˜¯å¦æ¯æ¬¡å¯åŠ¨éƒ½æ¸…ç©º
    /// </summary>
    public bool ClearRedis { get; set; } = false;
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheHashService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,88 @@
namespace WIDESEA_Cache;
/// <summary>
/// <inheritdoc cref="ISimpleCacheService"/>
/// å†…存缓存
/// </summary>
public partial class MemoryCacheService : ISimpleCacheService
{
    /// <inheritdoc/>
    public void HashAdd<T>(string key, string hashKey, T value)
    {
        //获取字典
        var exist = _memoryCache.GetDictionary<T>(key);
        if (exist.ContainsKey(hashKey))//如果包含Key
            exist[hashKey] = value;//重新赋值
        else exist.Add(hashKey, value);//加上新的值
        _memoryCache.Set(key, exist);
    }
    //private IDictionary<string,T> GetDictionary(string key,string)
    /// <inheritdoc/>
    public bool HashSet<T>(string key, Dictionary<string, T> dic)
    {
        //获取字典
        var exist = _memoryCache.GetDictionary<T>(key);
        dic.ForEach(it =>
        {
            if (exist.ContainsKey(it.Key))//如果包含Key
                exist[it.Key] = it.Value;//重新赋值
            else exist.Add(it.Key, it.Value);//加上新的值
        });
        return true;
    }
    /// <inheritdoc/>
    public int HashDel<T>(string key, params string[] fields)
    {
        int result = 0;
        //获取字典
        var exist = _memoryCache.GetDictionary<T>(key);
        foreach (var field in fields)
        {
            if (field != null && exist.ContainsKey(field))//如果包含Key
            {
                exist.Remove(field);//删除
                result++;
            }
        }
        return result;
    }
    /// <inheritdoc/>
    public List<T> HashGet<T>(string key, params string[] fields)
    {
        List<T> list = new List<T>();
        //获取字典
        var exist = _memoryCache.GetDictionary<T>(key);
        foreach (var field in fields)
        {
            if (exist.ContainsKey(field))//如果包含Key
            {
                list.Add(exist[field]);
            }
            else { list.Add(default); }
        }
        return list;
    }
    /// <inheritdoc/>
    public T HashGetOne<T>(string key, string field)
    {
        //获取字典
        var exist = _memoryCache.GetDictionary<T>(key);
        exist.TryGetValue(field, out T result);
        var data = result.DeepClone();
        return data;
    }
    /// <inheritdoc/>
    public IDictionary<string, T> HashGetAll<T>(string key)
    {
        var data = _memoryCache.GetDictionary<T>(key);
        return data;
    }
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
namespace WIDESEA_Cache;
/// <summary>
/// <inheritdoc cref="ISimpleCacheService"/>
/// å†…存缓存
/// </summary>
public partial class MemoryCacheService : ISimpleCacheService
{
    public readonly MemoryCache _memoryCache;
    public MemoryCacheService()
    {
        _memoryCache = new MemoryCache();
    }
    #region æ™®é€šæ“ä½œ
    /// <inheritdoc/>
    public T Get<T>(string key)
    {
        var data = _memoryCache.Get<string>(key);
        return data.ToObject<T>();
    }
    /// <inheritdoc/>
    public int Remove(params string[] keys)
    {
        return _memoryCache.Remove(keys);
    }
    /// <inheritdoc/>
    public bool Set<T>(string key, T value, int expire = -1)
    {
        return _memoryCache.Set(key, value.ToJson(), expire);
    }
    /// <inheritdoc/>
    public bool Set<T>(string key, T value, TimeSpan expire)
    {
        return _memoryCache.Set(key, value.ToJson(), expire);
    }
    /// <inheritdoc/>
    public bool SetExpire(string key, TimeSpan expire)
    {
        return _memoryCache.SetExpire(key, expire);
    }
    /// <inheritdoc/>
    public TimeSpan GetExpire(string key)
    {
        return _memoryCache.GetExpire(key);
    }
    /// <inheritdoc/>
    public bool ContainsKey(string key)
    {
        return _memoryCache.ContainsKey(key);
    }
    /// <inheritdoc/>
    public void Clear()
    {
        _memoryCache.Clear();
    }
    /// <inheritdoc/>
    public void DelByPattern(string pattern)
    {
        var keys = _memoryCache.Keys.ToList();//获取所有key
        keys.ForEach(it =>
        {
            if (it.Contains(pattern))//如果匹配
                _memoryCache.Remove(pattern);
        });
    }
    #endregion æ™®é€šæ“ä½œ
    #region é›†åˆæ“ä½œ
    /// <inheritdoc/>
    public IDictionary<string, T> GetAll<T>(IEnumerable<string> keys)
    {
        IDictionary<string, T>? result = default;//定义集合
        IDictionary<string, string>? data = _memoryCache.GetAll<string>(keys);//获取数据
        data.ForEach(it =>
        {
            result.Add(it.Key, it.Value.ToObject<T>());//遍历数据,格式化并加到新的数据集合
        });
        return result;
    }
    /// <inheritdoc/>
    public void SetAll<T>(IDictionary<string, T> values, int expire = -1)
    {
        IDictionary<string, string>? result = default;//定义集合
        values.ForEach(it =>
        {
            result.Add(it.Key, it.Value.ToJson());//遍历数据,格式化并加到新的数据集合
        });
        _memoryCache.SetAll(values, expire);
    }
    /// <inheritdoc/>
    public IDictionary<string, T> GetDictionary<T>(string key)
    {
        IDictionary<string, T>? result = default;//定义集合
        var data = _memoryCache.GetDictionary<string>(key);
        data.ForEach(it =>
        {
            result.Add(it.Key, it.Value.ToObject<T>());//遍历数据,格式化并加到新的数据集合
        });
        return result;
    }
    /// <inheritdoc/>
    public IProducerConsumer<T> GetQueue<T>(string key)
    {
        return _memoryCache.GetQueue<T>(key);
    }
    /// <inheritdoc/>
    public IProducerConsumer<T> GetStack<T>(string key)
    {
        return _memoryCache.GetStack<T>(key);
    }
    /// <inheritdoc/>
    public ICollection<T> GetSet<T>(string key)
    {
        return _memoryCache.GetSet<T>(key);
    }
    #endregion é›†åˆæ“ä½œ
    #region é«˜çº§æ“ä½œ
    /// <inheritdoc/>
    public bool Add<T>(string key, T value, int expire = -1)
    {
        return _memoryCache.Add(key, value.ToJson(), expire);
    }
    /// <inheritdoc/>
    public IList<T> GetList<T>(string key)
    {
        IList<T> result = default;//定义集合
        var data = _memoryCache.GetList<string>(key);
        data.ForEach(it =>
        {
            result.Add(it.ToObject<T>());//遍历数据,格式化并加到新的数据集合
        });
        return result;
    }
    /// <inheritdoc/>
    public T Replace<T>(string key, T value)
    {
        return _memoryCache.Replace(key, value);
    }
    /// <inheritdoc/>
    public bool TryGetValue<T>(string key, out T value)
    {
        var result = string.Empty;
        _ = _memoryCache.TryGetValue<string>(key, out result);
        value = result.ToObject<T>();
        return value == null;
    }
    /// <inheritdoc/>
    public long Decrement(string key, long value)
    {
        return _memoryCache.Decrement(key, value);
    }
    /// <inheritdoc/>
    public double Decrement(string key, double value)
    {
        return _memoryCache.Decrement(key, value);
    }
    /// <inheritdoc/>
    public long Increment(string key, long value)
    {
        return _memoryCache.Increment(key, value);
    }
    /// <inheritdoc/>
    public double Increment(string key, double value)
    {
        return _memoryCache.Increment(key, value);
    }
    #endregion é«˜çº§æ“ä½œ
    #region äº‹åŠ¡
    /// <inheritdoc/>
    public int Commit()
    {
        return _memoryCache.Commit();
    }
    /// <inheritdoc/>
    public IDisposable AcquireLock(string key, int msTimeout)
    {
        return _memoryCache.AcquireLock(key, msTimeout);
    }
    /// <inheritdoc/>
    public IDisposable AcquireLock(string key, int msTimeout, int msExpire, bool throwOnFailure)
    {
        return _memoryCache.AcquireLock(key, msTimeout, msExpire, throwOnFailure);
    }
    #endregion äº‹åŠ¡
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheHashService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
namespace WIDESEA_Cache;
/// <summary>
/// <inheritdoc cref="ISimpleCacheService"/>
/// Redis缓存
/// </summary>
public partial class RedisCacheService : ISimpleCacheService
{
    /// <inheritdoc/>
    public void HashAdd<T>(string key, string hashKey, T value)
    {
        _simpleRedis.HashAdd<T>(key, hashKey, value);
    }
    /// <inheritdoc/>
    public bool HashSet<T>(string key, Dictionary<string, T> dic)
    {
        return _simpleRedis.HashSet<T>(key, dic);
    }
    /// <inheritdoc/>
    public int HashDel<T>(string key, params string[] fields)
    {
        return _simpleRedis.HashDel<T>(key, fields);
    }
    /// <inheritdoc/>
    public List<T> HashGet<T>(string key, params string[] fields)
    {
        return _simpleRedis.HashGet<T>(key, fields);
    }
    /// <inheritdoc/>
    public T HashGetOne<T>(string key, string field)
    {
        return _simpleRedis.HashGetOne<T>(key, field);
    }
    /// <inheritdoc/>
    public IDictionary<string, T> HashGetAll<T>(string key)
    {
        return _simpleRedis.HashGetAll<T>(key);
    }
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,187 @@
namespace WIDESEA_Cache;
/// <summary>
/// <inheritdoc cref="ISimpleCacheService"/>
/// Redis缓存
/// </summary>
public partial class RedisCacheService : ISimpleCacheService
{
    private readonly ISimpleRedis _simpleRedis;
    public RedisCacheService(ISimpleRedis simpleRedis)
    {
        this._simpleRedis = simpleRedis;
    }
    #region æ™®é€šæ“ä½œ
    /// <inheritdoc/>
    public T Get<T>(string key)
    {
        return _simpleRedis.Get<T>(key);
    }
    /// <inheritdoc/>
    public int Remove(params string[] keys)
    {
        return _simpleRedis.GetFullRedis().Remove(keys);
    }
    /// <inheritdoc/>
    public bool Set<T>(string key, T value, int expire = -1)
    {
        return _simpleRedis.Set(key, value, expire);
    }
    /// <inheritdoc/>
    public bool Set<T>(string key, T value, TimeSpan expire)
    {
        return _simpleRedis.Set(key, value, expire);
    }
    /// <inheritdoc/>
    public bool SetExpire(string key, TimeSpan expire)
    {
        return _simpleRedis.GetFullRedis().SetExpire(key, expire);
    }
    /// <inheritdoc/>
    public TimeSpan GetExpire(string key)
    {
        return _simpleRedis.GetFullRedis().GetExpire(key);
    }
    /// <inheritdoc/>
    public bool ContainsKey(string key)
    {
        return _simpleRedis.ContainsKey(key);
    }
    /// <inheritdoc/>
    public void Clear()
    {
        _simpleRedis.Clear();
    }
    /// <inheritdoc/>
    public void DelByPattern(string pattern)
    {
        _simpleRedis.DelByPattern(pattern);
    }
    #endregion æ™®é€šæ“ä½œ
    #region é›†åˆæ“ä½œ
    /// <inheritdoc/>
    public IDictionary<string, T> GetAll<T>(IEnumerable<string> keys)
    {
        return _simpleRedis.GetFullRedis().GetAll<T>(keys);
    }
    /// <inheritdoc/>
    public void SetAll<T>(IDictionary<string, T> values, int expire = -1)
    {
        _simpleRedis.GetFullRedis().SetAll(values, expire);
    }
    /// <inheritdoc/>
    public IDictionary<string, T> GetDictionary<T>(string key)
    {
        return _simpleRedis.GetFullRedis().GetDictionary<T>(key);
    }
    /// <inheritdoc/>
    public IProducerConsumer<T> GetQueue<T>(string key)
    {
        return _simpleRedis.GetFullRedis().GetQueue<T>(key);
    }
    /// <inheritdoc/>
    public IProducerConsumer<T> GetStack<T>(string key)
    {
        return _simpleRedis.GetFullRedis().GetStack<T>(key);
    }
    /// <inheritdoc/>
    public ICollection<T> GetSet<T>(string key)
    {
        return _simpleRedis.GetFullRedis().GetSet<T>(key);
    }
    #endregion é›†åˆæ“ä½œ
    #region é«˜çº§æ“ä½œ
    /// <inheritdoc/>
    public bool Add<T>(string key, T value, int expire = -1)
    {
        return _simpleRedis.GetFullRedis().Add(key, value, expire);
    }
    /// <inheritdoc/>
    public IList<T> GetList<T>(string key)
    {
        return _simpleRedis.GetFullRedis().GetList<T>(key);
    }
    /// <inheritdoc/>
    public T Replace<T>(string key, T value)
    {
        return _simpleRedis.GetFullRedis().Replace(key, value);
    }
    /// <inheritdoc/>
    public bool TryGetValue<T>(string key, out T value)
    {
        return _simpleRedis.GetFullRedis().TryGetValue(key, out value);
    }
    /// <inheritdoc/>
    public long Decrement(string key, long value)
    {
        return _simpleRedis.GetFullRedis().Decrement(key, value);
    }
    /// <inheritdoc/>
    public double Decrement(string key, double value)
    {
        return _simpleRedis.GetFullRedis().Decrement(key, value);
    }
    /// <inheritdoc/>
    public long Increment(string key, long value)
    {
        return _simpleRedis.GetFullRedis().Increment(key, value);
    }
    /// <inheritdoc/>
    public double Increment(string key, double value)
    {
        return _simpleRedis.GetFullRedis().Increment(key, value);
    }
    #endregion é«˜çº§æ“ä½œ
    #region äº‹åŠ¡
    /// <inheritdoc/>
    public int Commit()
    {
        return _simpleRedis.GetFullRedis().Commit();
    }
    /// <inheritdoc/>
    public IDisposable AcquireLock(string key, int msTimeout)
    {
        return _simpleRedis.GetFullRedis().AcquireLock(key, msTimeout);
    }
    /// <inheritdoc/>
    public IDisposable AcquireLock(string key, int msTimeout, int msExpire, bool throwOnFailure)
    {
        return _simpleRedis.GetFullRedis().AcquireLock(key, msTimeout, msExpire, throwOnFailure);
    }
    #endregion äº‹åŠ¡
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/WIDESEA_Cache.csproj
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="SimpleRedis" Version="1.1.9" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\WIDESEA_Core\WIDESEA_Core.csproj" />
  </ItemGroup>
</Project>
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/AspNetCoreSchedule.cs
@@ -33,7 +33,7 @@
        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoWork, null, 0, 10000);
            _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromMinutes(10));
            return Task.CompletedTask;
        }
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
@@ -1,7 +1,9 @@
using Autofac.Core;
using Mapster;
using Masuit.Tools;
using SqlSugar;
using System.Text.RegularExpressions;
using WIDESEA_Cache;
using WIDESEA_Core.Const;
using WIDESEA_DTO.MOM;
using WIDESEA_DTO.WMS;
@@ -9,7 +11,6 @@
using WIDESEA_IStoragIntegrationServices;
using WIDESEAWCS_BasicInfoRepository;
using WIDESEAWCS_QuartzJob.Models;
namespace WIDESEA_StorageTaskServices;
@@ -31,6 +32,7 @@
    private readonly IAgingInOrOutInputService _agingInOrOutInputService; //静置\陈化
    private readonly IDt_StationManagerRepository _stationManagerRepository;
    private readonly ISys_ConfigService _configService;
    private readonly ISimpleCacheService _simpleCacheService;
    public Dt_TaskService(IDt_TaskRepository BaseDal,
                                IUnitOfWorkManage unitOfWorkManage,
@@ -48,7 +50,8 @@
                                IAgingInOrOutInputService agingInOrOutInputService,
                                IStockInfoDetailRepository stockInfoDetailRepository,
                                IDt_StationManagerRepository stationManagerRepository,
                                ISys_ConfigService configService) : base(BaseDal)
                                ISys_ConfigService configService,
                                ISimpleCacheService simpleCacheService) : base(BaseDal)
    {
        _unitOfWorkManage = unitOfWorkManage;
        _stockInfoRepository = stockInfoRepository;
@@ -65,6 +68,7 @@
        _stockInfoDetailRepository = stockInfoDetailRepository;
        _stationManagerRepository = stationManagerRepository;
        _configService = configService;
        _simpleCacheService = simpleCacheService;
    }
    #region å¤–部接口方法
@@ -1001,7 +1005,6 @@
                    return content.Error(result.MOMMessage);
            }
            if (result.SerialNos.Count <= 0)
            {
                var config = _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_InStacker, SysConfigConst.InboundIsEmpty);
@@ -1118,7 +1121,6 @@
                return content.Error("当前托盘无产线,联系MOM添加产线");
            }
            var stationManagers = _stationManagerRepository.QueryData(x => x.stationType == 6 && x.stationChildCode == input.Position).FirstOrDefault();
            if (stationManagers == null)
            {
@@ -1206,7 +1208,6 @@
            //ConsoleHelper.WriteColorLine(JsonConvert.SerializeObject(stockInfo), ConsoleColor.DarkMagenta);
            // æ–°å¢žé‡å¤ä»»åŠ¡æ ¡éªŒ
            var hasTask = BaseDal.QueryFirst(x => x.PalletCode == stockInfo.PalletCode);
            if (hasTask != null)
@@ -1258,26 +1259,101 @@
        }
        var outBoundMateriel = AppSettings.app<OutBoundMateriel>("OutBoundMateriel");
        List<string> materielCodes = null;
        if (outBoundMateriel.Count != 0)
        List<string>? materielCodes = outBoundMateriel.Count != 0
            ? outBoundMateriel.Where(x => x.ProductionLine == productionLine && x.ProcessCode == area.AreaCode)
                              .Select(x => x.MaterielCode)
                              .ToList()
            : null;
        IDictionary<string, DtStockInfo>? stockInfos = _simpleCacheService.HashGetAll<DtStockInfo>(WIDESEA_Cache.CacheConst.Cache_DtStockInfo);
        List<DtStockInfo> stockInfoList = stockInfos.Values.ToList();
        var result = new DtStockInfo();
        if (stockInfoList.IsNullOrEmpty())
        {
            materielCodes = outBoundMateriel.Where(x => x.ProductionLine == productionLine && x.ProcessCode == area.AreaCode).Select(x => x.MaterielCode).ToList();
            stockInfoList = await _stockInfoRepository.Db.Queryable<DtStockInfo>()
                .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock).IncludesAllFirstLayer().ToListAsync();
        }
        var result = await _stockInfoRepository.Db.Queryable<DtStockInfo>()
            .Includes(x => x.LocationInfo) // é¢„加载LocationInfo
            .Includes(x => x.StockInfoDetails) // é¢„加载StockInfoDetails
            .Where(x => x.AreaCode == areaCode && x.OutboundTime < DateTime.Now && x.IsFull == true) // è¿‡æ»¤æ¡ä»¶
            .WhereIF(!productionLine.IsNullOrEmpty(), x => x.ProductionLine == productionLine)
            .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // è¿‡æ»¤æ¡ä»¶
            .WhereIF(!devices.IsNullOrEmpty(), x => devices.Contains(x.LocationInfo.RoadwayNo))
            .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
            .OrderBy(x => x.OutboundTime) // æŽ’序
            .FirstAsync(); // èŽ·å–ç¬¬ä¸€ä¸ªå…ƒç´ 
        result = stockInfoList.Where(x => x.AreaCode == areaCode && x.OutboundTime < DateTime.Now && x.IsFull)
                          .WhereIF(!productionLine.IsNullOrEmpty(), x => x.ProductionLine == productionLine)
                          .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable)
                          .WhereIF(!devices.IsNullOrEmpty(), x => devices.Contains(x.LocationInfo.RoadwayNo))
                          .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
                          .OrderBy(x => x.OutboundTime)
                          .FirstOrDefault();
        //var firstOrDefault = result.FirstOrDefault(x => roadways.Contains(x.LocationInfo.RoadwayNo)); // æŸ¥æ‰¾ç¬¬ä¸€ä¸ªåŒ¹é…çš„元素
        //var firstOrDefault = result[0]; // æŸ¥æ‰¾ç¬¬ä¸€ä¸ªåŒ¹é…çš„元素
        //return firstOrDefault;
        if (result != null)
        {
            stockInfoList = stockInfoList.Where(x => x != result).ToList();
            if (stockInfos.IsNullOrEmpty())
            {
                foreach (var item in stockInfoList)
                {
                    _simpleCacheService.HashAdd(WIDESEA_Cache.CacheConst.Cache_DtStockInfo, item.PalletCode, item);
                }
            }
            else
            {
                _simpleCacheService.HashDel<DtStockInfo>(WIDESEA_Cache.CacheConst.Cache_DtStockInfo, new string[] { result.PalletCode });
            }
        }
        return result;
        if (stockInfoList.IsNullOrEmpty())
        {
            stockInfoList = await _stockInfoRepository.Db.Queryable<DtStockInfo>().IncludesAllFirstLayer().ToListAsync();
            result = stockInfoList.Where(x => x.AreaCode == areaCode && x.OutboundTime < DateTime.Now && x.IsFull == true)
                .WhereIF(!productionLine.IsNullOrEmpty(), x => x.ProductionLine == productionLine)
                .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // è¿‡æ»¤æ¡ä»¶
                .WhereIF(!devices.IsNullOrEmpty(), x => devices.Contains(x.LocationInfo.RoadwayNo))
                .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
                .OrderBy(x => x.OutboundTime) // æŽ’序
                .FirstOrDefault(); // èŽ·å–ç¬¬ä¸€ä¸ªå…ƒç´ 
            if (result != null)
            {
                // æŽ’除 result ä¸­çš„元素
                stockInfoList = stockInfoList.Where(x => x != result).ToList();
            }
            foreach (var item in stockInfoList)
            {
                _simpleCacheService.HashAdd(WIDESEA_Cache.CacheConst.Cache_DtStockInfo, item.PalletCode, item);
            }
        }
        else
        {
            result = stockInfoList.Where(x => x.AreaCode == areaCode && x.OutboundTime < DateTime.Now && x.IsFull == true)
                .WhereIF(!productionLine.IsNullOrEmpty(), x => x.ProductionLine == productionLine)
                .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // è¿‡æ»¤æ¡ä»¶
                .WhereIF(!devices.IsNullOrEmpty(), x => devices.Contains(x.LocationInfo.RoadwayNo))
                .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
                .OrderBy(x => x.OutboundTime) // æŽ’序
                .FirstOrDefault(); // èŽ·å–ç¬¬ä¸€ä¸ªå…ƒç´ 
            if (result != null)
            {
                // æŽ’除 result ä¸­çš„元素
                stockInfoList = stockInfoList.Where(x => x != result).ToList();
            }
            string[] xfasd = new string[] { result.PalletCode };
            _simpleCacheService.HashDel<DtStockInfo>(WIDESEA_Cache.CacheConst.Cache_DtStockInfo, new string[] { result.PalletCode });
        }
        #region
        //var result = await _stockInfoRepository.Db.Queryable<DtStockInfo>()
        //    .Includes(x => x.LocationInfo) // é¢„加载LocationInfo
        //    .Includes(x => x.StockInfoDetails) // é¢„加载StockInfoDetails
        //    .Where(x => x.AreaCode == areaCode && x.OutboundTime < DateTime.Now && x.IsFull == true) // è¿‡æ»¤æ¡ä»¶
        //    .WhereIF(!productionLine.IsNullOrEmpty(), x => x.ProductionLine == productionLine)
        //    .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // è¿‡æ»¤æ¡ä»¶
        //    .WhereIF(!devices.IsNullOrEmpty(), x => devices.Contains(x.LocationInfo.RoadwayNo))
        //    .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
        //    .OrderBy(x => x.OutboundTime) // æŽ’序
        //    .FirstAsync(); // èŽ·å–ç¬¬ä¸€ä¸ªå…ƒç´ 
        #endregion
        return result;
    }
@@ -1292,7 +1368,6 @@
            ConsoleHelper.WriteErrorLine($"查询常温实盘库存信息时,未找到区域代码为{JsonConvert.SerializeObject(areaCodes)}的数据");
            return null;
        }
        var outBoundMateriel = AppSettings.app<OutBoundMateriel>("OutBoundMateriel");
        List<string> materielCodes = null;
@@ -1317,10 +1392,6 @@
            .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
            .OrderBy(x => x.OutboundTime) // æŽ’序
            .FirstAsync(); // èŽ·å–ç¬¬ä¸€ä¸ªå…ƒç´ 
        //var firstOrDefault = result.FirstOrDefault(x => roadways.Contains(x.LocationInfo.RoadwayNo)); // æŸ¥æ‰¾ç¬¬ä¸€ä¸ªåŒ¹é…çš„元素
        //var firstOrDefault = result[0]; // æŸ¥æ‰¾ç¬¬ä¸€ä¸ªåŒ¹é…çš„元素
        //return firstOrDefault;
        return result;
    }
@@ -1336,7 +1407,6 @@
        ConsoleHelper.WriteColorLine(station.Roadway, ConsoleColor.Magenta);
        var stackers = station.Roadway.Split(',').ToList();
        var devices = SqlSugarHelper.DbWCS.Queryable<Dt_DeviceInfo>()
            .Where(x => x.DeviceStatus == "1")
@@ -1684,7 +1754,7 @@
        //    content.Error(ex.Message);
        //}
        //return content;
        #endregion
        #endregion é™ç½®å¼‚常口入库
        WebResponseContent content = new WebResponseContent();
        try
        {
@@ -1826,7 +1896,6 @@
        return content;
    }
    private WMSTaskDTO CreateWMSTaskDTO(object source)
    {
        if (source is Dt_Task taskOld)
@@ -1870,8 +1939,6 @@
    #endregion é™ç½®å¼‚常口入库
    #endregion å¤–部接口方法
    #region å†…部调用方法
@@ -2152,7 +2219,6 @@
                }
            }
            // æ·»åŠ åŽ†å²ä»»åŠ¡
            var isTaskHtyAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0;
@@ -2185,7 +2251,6 @@
    }
    #region ä»»åŠ¡è¯·æ±‚æ–¹æ³•
    private static readonly SemaphoreSlim _semaphoreUpdate = new SemaphoreSlim(1, 1);
    // æ›´æ–°ä»»åŠ¡è´§ä½
@@ -2273,7 +2338,6 @@
        }
        catch (Exception)
        {
            throw;
        }
        finally { _semaphoreUpdate.Release(); }
@@ -2387,8 +2451,8 @@
        return content;
    }
    private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
    /// <summary>
    /// æŸ¥æ‰¾è´§ä½
    /// </summary>
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/WIDESEA_StorageTaskServices.csproj
@@ -16,6 +16,7 @@
  <ItemGroup>
    <ProjectReference Include="..\LogLibrary\LogLibrary.csproj" />
    <ProjectReference Include="..\WIDESEA_Cache\WIDESEA_Cache.csproj" />
    <ProjectReference Include="..\WIDESEA_IBusinessServices\WIDESEA_IBusinessServices.csproj" />
    <ProjectReference Include="..\WIDESEA_IStorageBasicService\WIDESEA_IStorageBasicServices.csproj" />
    <ProjectReference Include="..\WIDESEA_IStorageOutOrderService\WIDESEA_IStorageOutOrderServices.csproj" />
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln
@@ -78,6 +78,8 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WIDESEA_IStoragIntegrationServices", "WIDESEA_IStoragIntegrationServices\WIDESEA_IStoragIntegrationServices.csproj", "{94D572FA-810E-4897-B673-AF988FD4019E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WIDESEA_Cache", "WIDESEA_Cache\WIDESEA_Cache.csproj", "{461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
@@ -436,6 +438,18 @@
        {94D572FA-810E-4897-B673-AF988FD4019E}.Release|Any CPU.Build.0 = Release|Any CPU
        {94D572FA-810E-4897-B673-AF988FD4019E}.Release|x86.ActiveCfg = Release|Any CPU
        {94D572FA-810E-4897-B673-AF988FD4019E}.Release|x86.Build.0 = Release|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Debug|x86.ActiveCfg = Debug|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Debug|x86.Build.0 = Debug|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Dev|Any CPU.ActiveCfg = Release|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Dev|Any CPU.Build.0 = Release|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Dev|x86.ActiveCfg = Release|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Dev|x86.Build.0 = Release|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Release|Any CPU.Build.0 = Release|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Release|x86.ActiveCfg = Release|Any CPU
        {461A73BF-9FC7-4BFE-9BEB-2AE686CBFEEC}.Release|x86.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs
@@ -20,6 +20,12 @@
using Swashbuckle.AspNetCore.SwaggerGen;
using Microsoft.OpenApi.Models;
using WIDESEA_StorageTaskServices;
using Autofac.Core;
using WIDESEA_Cache;
using SimpleRedis;
using WIDESEA_DTO.WMS;
using static NewLife.Remoting.ApiHttpClient;
using NewLife.Windows;
var builder = WebApplication.CreateBuilder(args);
@@ -112,8 +118,41 @@
builder.Services.AddHostedService<MyBackgroundService>();
//缓存设置配置转实体
builder.Services.AddConfigurableOptions<CacheSettingsOptions>();
//禁止在主机启动时通过 App.GetOptions<TOptions> èŽ·å–é€‰é¡¹ï¼Œå¦‚éœ€èŽ·å–é…ç½®é€‰é¡¹ç†åº”é€šè¿‡ App.GetConfig<TOptions>("配置节点", true)。
var cacheSettings = AppSettings.Configuration.GetSection("CacheSettings").Get<CacheSettingsOptions>();
//如果有redis连接字符串
if (cacheSettings.UseRedis)
{
    var connectionString =
        $"server={cacheSettings.RedisSettings.Address};db={cacheSettings.RedisSettings.Db}";
    //注入redis
    builder.Services.AddSimpleRedis(connectionString);
    builder.Services.AddScoped<ISimpleCacheService, RedisCacheService>();
}
else
{
    builder.Services.AddScoped<ISimpleCacheService, MemoryCacheService>();
}
var app = builder.Build();
// éªŒè¯ Redis æœåŠ¡æ˜¯å¦æˆåŠŸæ³¨å†Œ
using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    var redisService = services.GetService<ISimpleCacheService>();
    if (redisService == null)
    {
        WIDESEA_Core.Helper.ConsoleHelper.WriteErrorLine("Redis æœåŠ¡æœªæˆåŠŸæ³¨å†Œ");
    }
    else
    {
        WIDESEA_Core.Helper.ConsoleHelper.WriteSuccessLine("Redis æœåŠ¡å·²æˆåŠŸæ³¨å†Œ");
    }
}
// 3、配置中间件
app.UseMiniProfiler();//性能分析器
@@ -151,5 +190,15 @@
app.MapControllers();
//通过 App.GetOptions<TOptions> èŽ·å–é€‰é¡¹
var cacheSettingsb = App.GetOptions<CacheSettingsOptions>();
//如果需要清除缓存
if (cacheSettingsb.UseRedis && cacheSettingsb.RedisSettings.ClearRedis)
{
    var redis = app.Services.CreateScope().ServiceProvider.GetService<ISimpleCacheService>(); //获取redis服务
    // åˆ é™¤redis的key
    redis.DelByPattern(CacheConst.Cache_Prefix);
}
app.Run();
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj
@@ -34,6 +34,7 @@
    
    <ItemGroup>
      <ProjectReference Include="..\WIDESEA_BusinessServices\WIDESEA_BusinessServices.csproj" />
      <ProjectReference Include="..\WIDESEA_Cache\WIDESEA_Cache.csproj" />
      <ProjectReference Include="..\WIDESEA_Services\WIDESEA_Services.csproj" />
      <ProjectReference Include="..\WIDESEA_IServices\WIDESEA_IServices.csproj" />
      <ProjectReference Include="..\WIDESEA_StorageBasicServices\WIDESEA_StorageBasicServices.csproj" />
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
@@ -24,6 +24,18 @@
    // æ³¨æ„ï¼Œhttp://127.0.0.1:1818 å’Œ http://localhost:1818 æ˜¯ä¸ä¸€æ ·çš„
    "IPs": "http://127.0.0.1:8080,http://localhost:8080,http://127.0.0.1:8081,http://localhost:8081"
  },
  //缓存设置
  "CacheSettings": {
    "UseRedis": true, //启用redis
    "RedisSettings": {
      "Address": "127.0.0.1:6379", //地址
      "Password": "123456", //Redis服务密码
      "Db": 9, //默认库
      "ClearRedis": true //是否每次启动都清除Redis缓存
    }
  },
  "ApiName": "WIDESEA",
  "ExpMinutes": 120,
@@ -32,10 +44,10 @@
  // å…è®¸å‡ºåº“的编码
  "OutBoundMateriel": [
    {
      "MaterielCode": "CC01050001348",
      "ProductionLine": "ZJ-8",
      "ProcessCode": "CH001"
    }
    //{
    //  "MaterielCode": "CC01050001348",
    //  "ProductionLine": "ZJ-8",
    //  "ProcessCode": "CH001"
    //}
  ]
}
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/obj/Debug/net6.0/WIDESEA_WMSServer.MvcApplicationPartsAssemblyInfo.cs
@@ -17,6 +17,7 @@
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("Swashbuckle.AspNetCore.SwaggerGen")]
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("WIDESEA_BusinessesRepository")]
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("WIDESEA_BusinessServices")]
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("WIDESEA_Cache")]
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("WIDESEA_Core")]
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("WIDESEA_DTO")]
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("WIDESEA_IBusinessesRepository")]