From 6d578d016127db97d6f981ff18614ef52a2e0ede Mon Sep 17 00:00:00 2001
From: xxyy <cathay_xy@163.com>
Date: 星期三, 05 三月 2025 17:19:01 +0800
Subject: [PATCH] 添加缓存服务及相关功能支持

---
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/WIDESEA_Cache.csproj                                                        |   17 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json                                                        |   22 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Options/CacheSettingsOptions.cs                                             |   46 ++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheService.cs                                               |  219 ++++++++++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs                                        |  134 ++++-
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj                                                |    1 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs                                                              |   49 ++
 Code Management/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/copilot-chat/bef6627e/sessions/85d61362-b687-48eb-8099-932a817719a7 |    0 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/WIDESEA_StorageTaskServices.csproj                            |    1 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/obj/Debug/net6.0/WIDESEA_WMSServer.MvcApplicationPartsAssemblyInfo.cs   |    1 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Const/CacheConst.cs                                                         |   52 ++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheHashService.cs                                            |   45 ++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/LinqExtension.cs                                                  |   19 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheHashService.cs                                           |   88 ++++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheService.cs                                                |  187 +++++++++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheHashService.cs                                        |   60 +++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/GlobalUsing.cs                                                              |    7 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln                                                                     |   14 
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheService.cs                                            |  180 +++++++++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/ObjectExtension.cs                                                |   45 ++
 Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/AspNetCoreSchedule.cs                                         |    2 
 21 files changed, 1,148 insertions(+), 41 deletions(-)

diff --git a/Code Management/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/copilot-chat/bef6627e/sessions/85d61362-b687-48eb-8099-932a817719a7 b/Code Management/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/copilot-chat/bef6627e/sessions/85d61362-b687-48eb-8099-932a817719a7
new file mode 100644
index 0000000..8fc9dc5
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/copilot-chat/bef6627e/sessions/85d61362-b687-48eb-8099-932a817719a7
Binary files differ
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Const/CacheConst.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Const/CacheConst.cs
new file mode 100644
index 0000000..47445a2
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Const/CacheConst.cs
@@ -0,0 +1,52 @@
+锘縩amespace 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>
+    /// 绯荤粺閰嶇疆琛ㄧ紦瀛楰ey
+    /// </summary>
+    public const string Cache_DevConfig = Cache_Prefix_Web + "DevConfig:";
+
+    /// <summary>
+    /// 鐧诲綍楠岃瘉鐮佺紦瀛楰ey
+    /// </summary>
+    public const string Cache_Captcha = Cache_Prefix_Web + "Captcha:";
+
+    /// <summary>
+    /// 鐢ㄦ埛琛ㄧ紦瀛楰ey
+    /// </summary>
+    public const string Cache_SysUser = Cache_Prefix_Web + "SysUser";
+
+    /// <summary>
+    /// 鐢ㄦ埛鎵嬫満鍙峰叧绯荤紦瀛楰ey
+    /// </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";
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/LinqExtension.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/LinqExtension.cs
new file mode 100644
index 0000000..b733b7d
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/LinqExtension.cs
@@ -0,0 +1,19 @@
+锘縩amespace 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)));
+    }
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/ObjectExtension.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/ObjectExtension.cs
new file mode 100644
index 0000000..cf2b20e
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Extension/ObjectExtension.cs
@@ -0,0 +1,45 @@
+锘縰sing 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;", ""));
+    }
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/GlobalUsing.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/GlobalUsing.cs
new file mode 100644
index 0000000..45ad6b4
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/GlobalUsing.cs
@@ -0,0 +1,7 @@
+锘縢lobal 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;
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheHashService.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheHashService.cs
new file mode 100644
index 0000000..a15f099
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheHashService.cs
@@ -0,0 +1,60 @@
+锘縩amespace 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>
+    /// 娣诲姞澶氭潯鏁版嵁鍒癏ashMap
+    /// </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>
+    /// 浠嶩ashMap涓垹闄ゆ暟鎹�
+    /// </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>
+    /// 鏍规嵁閿幏鍙杊ash鍒楄〃涓殑鍊�
+    /// </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>
+    /// 鏍规嵁閿幏鍙杊ash鍒楄〃涓殑鍊�
+    /// </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);
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheService.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheService.cs
new file mode 100644
index 0000000..fc55623
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Interface/ISimpleCacheService.cs
@@ -0,0 +1,180 @@
+锘縩amespace 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>灏濊瘯鑾峰彇鎸囧畾閿紝杩斿洖鏄惁鍖呭惈鍊笺�傛湁鍙兘缂撳瓨椤瑰垰濂芥槸榛樿鍊硷紝鎴栬�呭彧鏄弽搴忓垪鍖栧け璐ワ紝瑙e喅缂撳瓨绌块�忛棶棰�</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 浜嬪姟
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Options/CacheSettingsOptions.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Options/CacheSettingsOptions.cs
new file mode 100644
index 0000000..f1b2e25
--- /dev/null
+++ b/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;
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheHashService.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheHashService.cs
new file mode 100644
index 0000000..4d96f71
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheHashService.cs
@@ -0,0 +1,88 @@
+锘縩amespace 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;
+    }
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheService.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheService.cs
new file mode 100644
index 0000000..78a2b6d
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/MemoryCacheService.cs
@@ -0,0 +1,219 @@
+锘縩amespace 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();//鑾峰彇鎵�鏈塳ey
+        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 浜嬪姟
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheHashService.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheHashService.cs
new file mode 100644
index 0000000..93e9b10
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheHashService.cs
@@ -0,0 +1,45 @@
+锘縩amespace 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);
+    }
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheService.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheService.cs
new file mode 100644
index 0000000..bfb225c
--- /dev/null
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/Service/RedisCacheService.cs
@@ -0,0 +1,187 @@
+锘縩amespace 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 浜嬪姟
+}
\ No newline at end of file
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/WIDESEA_Cache.csproj b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_Cache/WIDESEA_Cache.csproj
new file mode 100644
index 0000000..1cde5b8
--- /dev/null
+++ b/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>
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/AspNetCoreSchedule.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/AspNetCoreSchedule.cs
index 2146ea2..61f1f85 100644
--- a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/AspNetCoreSchedule.cs
+++ b/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;
         }
 
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
index cad83fa..7f139ed 100644
--- a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
@@ -1,7 +1,9 @@
 锘縰sing 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) // 棰勫姞杞絃ocationInfo
-            .Includes(x => x.StockInfoDetails) // 棰勫姞杞絊tockInfoDetails
-            .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) // 棰勫姞杞絃ocationInfo
+        //    .Includes(x => x.StockInfoDetails) // 棰勫姞杞絊tockInfoDetails
+        //    .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 闈欑疆寮傚父鍙e叆搴�
         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 闈欑疆寮傚父鍙e叆搴�
 
     #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>
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/WIDESEA_StorageTaskServices.csproj b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/WIDESEA_StorageTaskServices.csproj
index 8b2f84d..1c51ae2 100644
--- a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/WIDESEA_StorageTaskServices.csproj
+++ b/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" />
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln
index bb25daf..ddc6e1e 100644
--- a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln
+++ b/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
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs
index c7403ba..1e38ec0 100644
--- a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs
+++ b/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();
 
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj
index 6091c76..66cde40 100644
--- a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj
+++ b/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" />
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
index 5731809..8460061 100644
--- a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
+++ b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
@@ -24,6 +24,18 @@
     // 娉ㄦ剰锛宧ttp://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 //鏄惁姣忔鍚姩閮芥竻闄edis缂撳瓨
+    }
+  },
+
   "ApiName": "WIDESEA",
   "ExpMinutes": 120,
 
@@ -32,10 +44,10 @@
 
   // 鍏佽鍑哄簱鐨勭紪鐮�
   "OutBoundMateriel": [
-    {
-      "MaterielCode": "CC01050001348",
-      "ProductionLine": "ZJ-8",
-      "ProcessCode": "CH001"
-    }
+    //{
+    //  "MaterielCode": "CC01050001348",
+    //  "ProductionLine": "ZJ-8",
+    //  "ProcessCode": "CH001"
+    //}
   ]
 }
diff --git a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/obj/Debug/net6.0/WIDESEA_WMSServer.MvcApplicationPartsAssemblyInfo.cs b/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/obj/Debug/net6.0/WIDESEA_WMSServer.MvcApplicationPartsAssemblyInfo.cs
index c85e30c..cd44a9d 100644
--- a/Code Management/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/obj/Debug/net6.0/WIDESEA_WMSServer.MvcApplicationPartsAssemblyInfo.cs
+++ b/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")]

--
Gitblit v1.9.3