diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Antiforgery.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Antiforgery.dll
new file mode 100644
index 0000000..9112f68
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Antiforgery.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authentication.Core.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authentication.Core.dll
new file mode 100644
index 0000000..9124c45
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authentication.Core.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authentication.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authentication.dll
new file mode 100644
index 0000000..d8e663c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authentication.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authorization.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authorization.dll
new file mode 100644
index 0000000..7619714
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Authorization.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Forms.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Forms.dll
new file mode 100644
index 0000000..1810c94
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Forms.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Server.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Server.dll
new file mode 100644
index 0000000..d009001
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Server.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Web.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Web.dll
new file mode 100644
index 0000000..ecaabdf
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.Web.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.dll
new file mode 100644
index 0000000..4bf194c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Components.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.CookiePolicy.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.CookiePolicy.dll
new file mode 100644
index 0000000..8b8b22a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.CookiePolicy.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Cors.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Cors.dll
new file mode 100644
index 0000000..76d63ff
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Cors.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.DataProtection.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.DataProtection.dll
new file mode 100644
index 0000000..90b0f8f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.DataProtection.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Diagnostics.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Diagnostics.dll
new file mode 100644
index 0000000..b0796ef
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Diagnostics.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HostFiltering.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HostFiltering.dll
new file mode 100644
index 0000000..586a895
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HostFiltering.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Hosting.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Hosting.dll
new file mode 100644
index 0000000..c36868c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Hosting.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Html.Abstractions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Html.Abstractions.dll
new file mode 100644
index 0000000..0b607c6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Html.Abstractions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Abstractions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Abstractions.dll
new file mode 100644
index 0000000..ff97f71
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Abstractions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Connections.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Connections.dll
new file mode 100644
index 0000000..c173473
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Connections.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Extensions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Extensions.dll
new file mode 100644
index 0000000..da9e0b9
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Extensions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Features.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Features.dll
new file mode 100644
index 0000000..8de4ad8
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Features.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Results.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Results.dll
new file mode 100644
index 0000000..7dcffcc
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.Results.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.dll
new file mode 100644
index 0000000..f40500c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Http.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpLogging.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpLogging.dll
new file mode 100644
index 0000000..4e4e38f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpLogging.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpOverrides.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpOverrides.dll
new file mode 100644
index 0000000..1af5717
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpOverrides.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpsPolicy.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpsPolicy.dll
new file mode 100644
index 0000000..dc326f1
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.HttpsPolicy.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Identity.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Identity.dll
new file mode 100644
index 0000000..0a459ae
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Identity.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Localization.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Localization.dll
new file mode 100644
index 0000000..eddb9f6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Localization.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Metadata.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Metadata.dll
new file mode 100644
index 0000000..9e6cf43
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Metadata.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Abstractions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Abstractions.dll
new file mode 100644
index 0000000..c43a768
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Abstractions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.ApiExplorer.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.ApiExplorer.dll
new file mode 100644
index 0000000..4e4b4be
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.ApiExplorer.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Core.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Core.dll
new file mode 100644
index 0000000..f016d8f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Core.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Cors.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Cors.dll
new file mode 100644
index 0000000..07cf2d5
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Cors.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.DataAnnotations.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.DataAnnotations.dll
new file mode 100644
index 0000000..b0a2d06
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.DataAnnotations.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Formatters.Json.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Formatters.Json.dll
new file mode 100644
index 0000000..d3e1a43
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Formatters.Json.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Formatters.Xml.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Formatters.Xml.dll
new file mode 100644
index 0000000..f963c6f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Formatters.Xml.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Localization.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Localization.dll
new file mode 100644
index 0000000..3c7bc10
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Localization.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Razor.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Razor.dll
new file mode 100644
index 0000000..4ce21dd
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.Razor.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.RazorPages.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.RazorPages.dll
new file mode 100644
index 0000000..e0af794
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.RazorPages.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.TagHelpers.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.TagHelpers.dll
new file mode 100644
index 0000000..545b6d1
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.TagHelpers.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.ViewFeatures.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.ViewFeatures.dll
new file mode 100644
index 0000000..a995561
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.ViewFeatures.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.dll
new file mode 100644
index 0000000..5bb5780
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Mvc.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.OutputCaching.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.OutputCaching.dll
new file mode 100644
index 0000000..84db4f6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.OutputCaching.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.RateLimiting.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.RateLimiting.dll
new file mode 100644
index 0000000..b41a020
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.RateLimiting.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Razor.Runtime.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Razor.Runtime.dll
new file mode 100644
index 0000000..a912eae
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Razor.Runtime.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Razor.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Razor.dll
new file mode 100644
index 0000000..47864e0
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Razor.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.ResponseCaching.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.ResponseCaching.dll
new file mode 100644
index 0000000..3d62f21
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.ResponseCaching.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.ResponseCompression.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.ResponseCompression.dll
new file mode 100644
index 0000000..b88498a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.ResponseCompression.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Rewrite.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Rewrite.dll
new file mode 100644
index 0000000..ff7afb5
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Rewrite.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Routing.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Routing.dll
new file mode 100644
index 0000000..980473b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Routing.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.HttpSys.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.HttpSys.dll
new file mode 100644
index 0000000..df18136
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.HttpSys.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.IIS.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.IIS.dll
new file mode 100644
index 0000000..62673bd
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.IIS.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.Kestrel.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.Kestrel.dll
new file mode 100644
index 0000000..62d909a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Server.Kestrel.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Session.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Session.dll
new file mode 100644
index 0000000..56fa070
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.Session.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.Common.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.Common.dll
new file mode 100644
index 0000000..fa216c7
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.Common.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.Core.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.Core.dll
new file mode 100644
index 0000000..fe6d96f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.Core.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.dll
new file mode 100644
index 0000000..12b5de8
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.SignalR.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.StaticFiles.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.StaticFiles.dll
new file mode 100644
index 0000000..a6b15f6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.StaticFiles.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.WebSockets.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.WebSockets.dll
new file mode 100644
index 0000000..c857ace
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.WebSockets.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.WebUtilities.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.WebUtilities.dll
new file mode 100644
index 0000000..6d13ab0
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.WebUtilities.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.dll
new file mode 100644
index 0000000..6784a1d
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.AspNetCore.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.CSharp.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.CSharp.dll
new file mode 100644
index 0000000..254f778
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.CSharp.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Data.SqlClient.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Data.SqlClient.dll
new file mode 100644
index 0000000..ee9c5f5
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Data.SqlClient.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Caching.Memory.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Caching.Memory.dll
new file mode 100644
index 0000000..75fae80
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Caching.Memory.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Ini.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Ini.dll
new file mode 100644
index 0000000..1cab587
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Ini.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Json.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Json.dll
new file mode 100644
index 0000000..a3dfe02
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Json.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Xml.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Xml.dll
new file mode 100644
index 0000000..d28fead
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.Xml.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.dll
new file mode 100644
index 0000000..35f05d5
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Configuration.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Diagnostics.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Diagnostics.dll
new file mode 100644
index 0000000..6919fc2
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Diagnostics.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Features.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Features.dll
new file mode 100644
index 0000000..9a7ca5c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Features.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.FileSystemGlobbing.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.FileSystemGlobbing.dll
new file mode 100644
index 0000000..7930731
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.FileSystemGlobbing.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Hosting.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Hosting.dll
new file mode 100644
index 0000000..765c980
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Hosting.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Http.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Http.dll
new file mode 100644
index 0000000..b66feb6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Http.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Identity.Core.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Identity.Core.dll
new file mode 100644
index 0000000..b51545d
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Identity.Core.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Identity.Stores.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Identity.Stores.dll
new file mode 100644
index 0000000..ddba40a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Identity.Stores.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Localization.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Localization.dll
new file mode 100644
index 0000000..e58bf4b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Localization.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.Console.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.Console.dll
new file mode 100644
index 0000000..c2d643a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.Console.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.Debug.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.Debug.dll
new file mode 100644
index 0000000..a92d2e3
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.Debug.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.EventLog.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.EventLog.dll
new file mode 100644
index 0000000..037557b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.EventLog.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.dll
new file mode 100644
index 0000000..3252659
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Logging.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.ObjectPool.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.ObjectPool.dll
new file mode 100644
index 0000000..e6e587a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.ObjectPool.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Options.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Options.dll
new file mode 100644
index 0000000..e5247b5
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Options.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Primitives.dll
new file mode 100644
index 0000000..38033f6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.WebEncoders.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.WebEncoders.dll
new file mode 100644
index 0000000..f2b40e6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Extensions.WebEncoders.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.JSInterop.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.JSInterop.dll
new file mode 100644
index 0000000..036f2c6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.JSInterop.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Net.Http.Headers.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Net.Http.Headers.dll
new file mode 100644
index 0000000..7612d1a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Net.Http.Headers.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.VisualBasic.Core.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.VisualBasic.Core.dll
new file mode 100644
index 0000000..58eb6f6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.VisualBasic.Core.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.VisualBasic.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.VisualBasic.dll
new file mode 100644
index 0000000..0d703cd
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.VisualBasic.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Win32.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Win32.Primitives.dll
new file mode 100644
index 0000000..e0f9053
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Win32.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Win32.Registry.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Win32.Registry.dll
new file mode 100644
index 0000000..36d5f2b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/Microsoft.Win32.Registry.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.AppContext.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.AppContext.dll
new file mode 100644
index 0000000..a7e6dd0
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.AppContext.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Buffers.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Buffers.dll
new file mode 100644
index 0000000..9f017b1
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Buffers.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Concurrent.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Concurrent.dll
new file mode 100644
index 0000000..e1da608
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Concurrent.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Immutable.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Immutable.dll
new file mode 100644
index 0000000..169f862
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Immutable.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.NonGeneric.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.NonGeneric.dll
new file mode 100644
index 0000000..697853b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.NonGeneric.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Specialized.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Specialized.dll
new file mode 100644
index 0000000..e869990
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.Specialized.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.dll
new file mode 100644
index 0000000..82e6aba
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Collections.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.Annotations.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.Annotations.dll
new file mode 100644
index 0000000..f5708d2
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.Annotations.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.DataAnnotations.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.DataAnnotations.dll
new file mode 100644
index 0000000..4fa8f4b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.DataAnnotations.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.EventBasedAsync.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.EventBasedAsync.dll
new file mode 100644
index 0000000..44e761a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.EventBasedAsync.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.Primitives.dll
new file mode 100644
index 0000000..1508fe8
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.TypeConverter.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.TypeConverter.dll
new file mode 100644
index 0000000..776b17a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.TypeConverter.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.dll
new file mode 100644
index 0000000..2b64f60
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ComponentModel.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Configuration.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Configuration.dll
new file mode 100644
index 0000000..782d3bf
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Configuration.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Console.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Console.dll
new file mode 100644
index 0000000..5b6e1f9
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Console.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Core.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Core.dll
new file mode 100644
index 0000000..64d4621
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Core.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.Common.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.Common.dll
new file mode 100644
index 0000000..721c36d
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.Common.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.DataSetExtensions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.DataSetExtensions.dll
new file mode 100644
index 0000000..24a10a8
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.DataSetExtensions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.dll
new file mode 100644
index 0000000..01bbd8c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Data.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Contracts.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Contracts.dll
new file mode 100644
index 0000000..5a76fb5
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Contracts.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Debug.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Debug.dll
new file mode 100644
index 0000000..3204c5f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Debug.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.DiagnosticSource.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.DiagnosticSource.dll
new file mode 100644
index 0000000..3c17704
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.DiagnosticSource.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.EventLog.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.EventLog.dll
new file mode 100644
index 0000000..63fe9d3
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.EventLog.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.FileVersionInfo.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.FileVersionInfo.dll
new file mode 100644
index 0000000..b929800
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.FileVersionInfo.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Process.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Process.dll
new file mode 100644
index 0000000..57f6b89
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Process.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.StackTrace.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.StackTrace.dll
new file mode 100644
index 0000000..459d208
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.StackTrace.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Tools.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Tools.dll
new file mode 100644
index 0000000..4bc3799
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Tools.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.TraceSource.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.TraceSource.dll
new file mode 100644
index 0000000..3d51452
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.TraceSource.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Tracing.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Tracing.dll
new file mode 100644
index 0000000..90ba0ad
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Diagnostics.Tracing.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Drawing.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Drawing.Primitives.dll
new file mode 100644
index 0000000..0428585
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Drawing.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Drawing.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Drawing.dll
new file mode 100644
index 0000000..2e3c775
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Drawing.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Dynamic.Runtime.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Dynamic.Runtime.dll
new file mode 100644
index 0000000..d9e24c5
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Dynamic.Runtime.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Formats.Asn1.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Formats.Asn1.dll
new file mode 100644
index 0000000..b75618b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Formats.Asn1.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Formats.Tar.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Formats.Tar.dll
new file mode 100644
index 0000000..91bda08
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Formats.Tar.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.Calendars.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.Calendars.dll
new file mode 100644
index 0000000..9b3821b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.Calendars.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.Extensions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.Extensions.dll
new file mode 100644
index 0000000..8d1e39b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.Extensions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.dll
new file mode 100644
index 0000000..aceb317
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Globalization.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.Brotli.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.Brotli.dll
new file mode 100644
index 0000000..dcacee3
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.Brotli.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.FileSystem.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.FileSystem.dll
new file mode 100644
index 0000000..6adbf64
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.FileSystem.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.ZipFile.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.ZipFile.dll
new file mode 100644
index 0000000..67c4bbb
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.ZipFile.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.dll
new file mode 100644
index 0000000..c736398
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Compression.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.AccessControl.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.AccessControl.dll
new file mode 100644
index 0000000..944de2f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.AccessControl.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.DriveInfo.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.DriveInfo.dll
new file mode 100644
index 0000000..dea7620
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.DriveInfo.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.Primitives.dll
new file mode 100644
index 0000000..902567f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.Watcher.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.Watcher.dll
new file mode 100644
index 0000000..8df053c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.Watcher.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.dll
new file mode 100644
index 0000000..ef3f38f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.FileSystem.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.IsolatedStorage.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.IsolatedStorage.dll
new file mode 100644
index 0000000..bd35b97
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.IsolatedStorage.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.MemoryMappedFiles.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.MemoryMappedFiles.dll
new file mode 100644
index 0000000..f9dda20
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.MemoryMappedFiles.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipelines.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipelines.dll
new file mode 100644
index 0000000..342228f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipelines.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipes.AccessControl.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipes.AccessControl.dll
new file mode 100644
index 0000000..9e77902
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipes.AccessControl.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipes.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipes.dll
new file mode 100644
index 0000000..5af9878
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.Pipes.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.UnmanagedMemoryStream.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.UnmanagedMemoryStream.dll
new file mode 100644
index 0000000..91ade0c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.UnmanagedMemoryStream.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.dll
new file mode 100644
index 0000000..3529768
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.IO.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Expressions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Expressions.dll
new file mode 100644
index 0000000..f491951
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Expressions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Parallel.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Parallel.dll
new file mode 100644
index 0000000..b138bad
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Parallel.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Queryable.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Queryable.dll
new file mode 100644
index 0000000..49a7137
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.Queryable.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.dll
new file mode 100644
index 0000000..204e63d
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Linq.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Memory.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Memory.dll
new file mode 100644
index 0000000..9dd3b57
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Memory.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Http.Json.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Http.Json.dll
new file mode 100644
index 0000000..ad73e22
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Http.Json.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Http.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Http.dll
new file mode 100644
index 0000000..8982a47
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Http.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.HttpListener.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.HttpListener.dll
new file mode 100644
index 0000000..a963342
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.HttpListener.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Mail.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Mail.dll
new file mode 100644
index 0000000..92fc8ff
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Mail.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.NameResolution.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.NameResolution.dll
new file mode 100644
index 0000000..c2953a0
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.NameResolution.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.NetworkInformation.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.NetworkInformation.dll
new file mode 100644
index 0000000..0aa5607
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.NetworkInformation.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Ping.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Ping.dll
new file mode 100644
index 0000000..e793a14
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Ping.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Primitives.dll
new file mode 100644
index 0000000..504b004
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Quic.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Quic.dll
new file mode 100644
index 0000000..ca67309
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Quic.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Requests.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Requests.dll
new file mode 100644
index 0000000..fbf9983
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Requests.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Security.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Security.dll
new file mode 100644
index 0000000..b41f301
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Security.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.ServicePoint.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.ServicePoint.dll
new file mode 100644
index 0000000..48a2f4b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.ServicePoint.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Sockets.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Sockets.dll
new file mode 100644
index 0000000..aa018c8
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.Sockets.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebClient.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebClient.dll
new file mode 100644
index 0000000..7d3546b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebClient.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebHeaderCollection.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebHeaderCollection.dll
new file mode 100644
index 0000000..565f62b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebHeaderCollection.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebProxy.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebProxy.dll
new file mode 100644
index 0000000..2171369
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebProxy.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebSockets.Client.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebSockets.Client.dll
new file mode 100644
index 0000000..8bfc807
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebSockets.Client.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebSockets.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebSockets.dll
new file mode 100644
index 0000000..37d949f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.WebSockets.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.dll
new file mode 100644
index 0000000..784b9a6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Net.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Numerics.Vectors.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Numerics.Vectors.dll
new file mode 100644
index 0000000..bb50aea
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Numerics.Vectors.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Numerics.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Numerics.dll
new file mode 100644
index 0000000..25d0431
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Numerics.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ObjectModel.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ObjectModel.dll
new file mode 100644
index 0000000..1fde223
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ObjectModel.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.DispatchProxy.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.DispatchProxy.dll
new file mode 100644
index 0000000..00aaa40
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.DispatchProxy.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.ILGeneration.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.ILGeneration.dll
new file mode 100644
index 0000000..bd507d4
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.ILGeneration.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.Lightweight.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.Lightweight.dll
new file mode 100644
index 0000000..090f988
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.Lightweight.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.dll
new file mode 100644
index 0000000..11b7cd9
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Emit.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Extensions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Extensions.dll
new file mode 100644
index 0000000..c3a8857
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Extensions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Metadata.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Metadata.dll
new file mode 100644
index 0000000..031160e
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Metadata.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Primitives.dll
new file mode 100644
index 0000000..fb847be
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.TypeExtensions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.TypeExtensions.dll
new file mode 100644
index 0000000..19d3473
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.TypeExtensions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.dll
new file mode 100644
index 0000000..c59a93c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Reflection.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.Reader.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.Reader.dll
new file mode 100644
index 0000000..4d822aa
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.Reader.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.ResourceManager.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.ResourceManager.dll
new file mode 100644
index 0000000..4b23690
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.ResourceManager.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.Writer.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.Writer.dll
new file mode 100644
index 0000000..b45b238
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Resources.Writer.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.CompilerServices.Unsafe.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.CompilerServices.Unsafe.dll
new file mode 100644
index 0000000..ff0dc2f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.CompilerServices.Unsafe.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.CompilerServices.VisualC.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.CompilerServices.VisualC.dll
new file mode 100644
index 0000000..7536561
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.CompilerServices.VisualC.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Extensions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Extensions.dll
new file mode 100644
index 0000000..1833bfd
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Extensions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Handles.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Handles.dll
new file mode 100644
index 0000000..6f38e17
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Handles.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.InteropServices.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.InteropServices.dll
new file mode 100644
index 0000000..60b01ee
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.InteropServices.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Intrinsics.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Intrinsics.dll
new file mode 100644
index 0000000..643873e
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Intrinsics.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Loader.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Loader.dll
new file mode 100644
index 0000000..515a8a9
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Loader.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Numerics.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Numerics.dll
new file mode 100644
index 0000000..87de102
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Numerics.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Formatters.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Formatters.dll
new file mode 100644
index 0000000..f18ad26
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Formatters.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Json.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Json.dll
new file mode 100644
index 0000000..d8a5cfe
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Json.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Primitives.dll
new file mode 100644
index 0000000..6e19a2b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Xml.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Xml.dll
new file mode 100644
index 0000000..de2730a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.Xml.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.dll
new file mode 100644
index 0000000..8190f35
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.Serialization.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.dll
new file mode 100644
index 0000000..a5e76d4
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Runtime.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.AccessControl.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.AccessControl.dll
new file mode 100644
index 0000000..d999990
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.AccessControl.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Claims.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Claims.dll
new file mode 100644
index 0000000..7031fdf
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Claims.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Algorithms.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Algorithms.dll
new file mode 100644
index 0000000..dbbbf89
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Algorithms.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Cng.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Cng.dll
new file mode 100644
index 0000000..22102fb
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Cng.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Csp.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Csp.dll
new file mode 100644
index 0000000..a1df139
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Csp.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Encoding.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Encoding.dll
new file mode 100644
index 0000000..6dd3126
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Encoding.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.OpenSsl.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.OpenSsl.dll
new file mode 100644
index 0000000..4982518
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.OpenSsl.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Primitives.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Primitives.dll
new file mode 100644
index 0000000..1460f3a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Primitives.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Xml.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Xml.dll
new file mode 100644
index 0000000..e17e675
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.Xml.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.dll
new file mode 100644
index 0000000..179f66d
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Cryptography.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Principal.Windows.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Principal.Windows.dll
new file mode 100644
index 0000000..019c537
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Principal.Windows.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Principal.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Principal.dll
new file mode 100644
index 0000000..f23385d
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.Principal.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.SecureString.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.SecureString.dll
new file mode 100644
index 0000000..b63afdb
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.SecureString.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.dll
new file mode 100644
index 0000000..1162897
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Security.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ServiceModel.Web.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ServiceModel.Web.dll
new file mode 100644
index 0000000..5f068f0
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ServiceModel.Web.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ServiceProcess.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ServiceProcess.dll
new file mode 100644
index 0000000..6cd3c48
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ServiceProcess.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.CodePages.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.CodePages.dll
new file mode 100644
index 0000000..2b98629
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.CodePages.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.Extensions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.Extensions.dll
new file mode 100644
index 0000000..31fdd34
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.Extensions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.dll
new file mode 100644
index 0000000..1692a09
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encoding.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encodings.Web.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encodings.Web.dll
new file mode 100644
index 0000000..5c91d37
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Encodings.Web.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Json.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Json.dll
new file mode 100644
index 0000000..c8aae20
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.Json.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.RegularExpressions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.RegularExpressions.dll
new file mode 100644
index 0000000..eee0c8c
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Text.RegularExpressions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Channels.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Channels.dll
new file mode 100644
index 0000000..594a40d
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Channels.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Overlapped.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Overlapped.dll
new file mode 100644
index 0000000..0886f4f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Overlapped.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.RateLimiting.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.RateLimiting.dll
new file mode 100644
index 0000000..6b05688
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.RateLimiting.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Dataflow.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Dataflow.dll
new file mode 100644
index 0000000..eeb417b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Dataflow.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Extensions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Extensions.dll
new file mode 100644
index 0000000..382799b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Extensions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Parallel.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Parallel.dll
new file mode 100644
index 0000000..77209f9
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.Parallel.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.dll
new file mode 100644
index 0000000..af8605e
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Tasks.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Thread.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Thread.dll
new file mode 100644
index 0000000..a2ada0f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Thread.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.ThreadPool.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.ThreadPool.dll
new file mode 100644
index 0000000..a54ac53
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.ThreadPool.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Timer.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Timer.dll
new file mode 100644
index 0000000..aa09082
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.Timer.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.dll
new file mode 100644
index 0000000..efeb234
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Threading.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Transactions.Local.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Transactions.Local.dll
new file mode 100644
index 0000000..bf0512f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Transactions.Local.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Transactions.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Transactions.dll
new file mode 100644
index 0000000..aef014e
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Transactions.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ValueTuple.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ValueTuple.dll
new file mode 100644
index 0000000..a8011a9
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.ValueTuple.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Web.HttpUtility.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Web.HttpUtility.dll
new file mode 100644
index 0000000..203ae8d
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Web.HttpUtility.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Web.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Web.dll
new file mode 100644
index 0000000..ef0e4fb
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Web.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Windows.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Windows.dll
new file mode 100644
index 0000000..ed41971
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Windows.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.Linq.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.Linq.dll
new file mode 100644
index 0000000..f0e5359
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.Linq.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.ReaderWriter.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.ReaderWriter.dll
new file mode 100644
index 0000000..afe811a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.ReaderWriter.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.Serialization.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.Serialization.dll
new file mode 100644
index 0000000..03b1af8
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.Serialization.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XDocument.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XDocument.dll
new file mode 100644
index 0000000..c91851e
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XDocument.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XPath.XDocument.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XPath.XDocument.dll
new file mode 100644
index 0000000..c3588a3
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XPath.XDocument.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XPath.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XPath.dll
new file mode 100644
index 0000000..13b9c26
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XPath.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XmlDocument.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XmlDocument.dll
new file mode 100644
index 0000000..1e89458
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XmlDocument.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XmlSerializer.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XmlSerializer.dll
new file mode 100644
index 0000000..56e5b79
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.XmlSerializer.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.dll
new file mode 100644
index 0000000..86de56b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.Xml.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.dll
new file mode 100644
index 0000000..d9ec03f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/System.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/WindowsBase.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/WindowsBase.dll
new file mode 100644
index 0000000..e0f769f
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/WindowsBase.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/mscorlib.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/mscorlib.dll
new file mode 100644
index 0000000..0ec6e6b
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/mscorlib.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/netstandard.dll b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/netstandard.dll
new file mode 100644
index 0000000..e54daa6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/_publish-test/refs/netstandard.dll
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/LabelMultipleOption/LabelMultipleOptionCreateInputVo.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/LabelMultipleOption/LabelMultipleOptionCreateInputVo.cs
new file mode 100644
index 0000000..007d8b5
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/LabelMultipleOption/LabelMultipleOptionCreateInputVo.cs
@@ -0,0 +1,36 @@
+namespace FoodLabeling.Application.Contracts.Dtos.LabelMultipleOption;
+
+public class LabelMultipleOptionCreateInputVo
+{
+ /// 多选项编码(可选;未传或空字符串时存空,列表/详情出参为「无」)
+ public string? OptionCode { get; set; }
+
+ public string OptionName { get; set; } = string.Empty;
+
+ public string? OptionValuesJson { get; set; }
+
+ public bool State { get; set; } = true;
+
+ ///
+ /// 门店可用范围:ALL / SPECIFIED;传了 或 时自动为 SPECIFIED
+ ///
+ public string AvailabilityType { get; set; } = "ALL";
+
+ ///
+ /// 适用 Region(多选),fl_group.Id;与 合并去重
+ ///
+ public List? RegionIds { get; set; }
+
+ ///
+ /// 适用 Region(多选),与 相同
+ ///
+ public List? GroupIds { get; set; }
+
+ ///
+ /// 适用门店(多选),location.Id;与 Region 合并后写入 fl_label_multiple_option_location
+ ///
+ public List? LocationIds { get; set; }
+
+ public int OrderNum { get; set; }
+}
+
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Partner/PartnerAddressFieldsDto.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Partner/PartnerAddressFieldsDto.cs
new file mode 100644
index 0000000..f218990
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Partner/PartnerAddressFieldsDto.cs
@@ -0,0 +1,20 @@
+namespace FoodLabeling.Application.Contracts.Dtos.Partner;
+
+///
+/// 合作伙伴地址字段(与 location 门店地址命名对齐)
+///
+public class PartnerAddressFieldsDto
+{
+ public string? Street { get; set; }
+
+ public string? City { get; set; }
+
+ ///
+ /// 州/省代码(如 NY)。JSON 字段名为 stateCode,与启用状态 state(boolean)不同。
+ ///
+ public string? StateCode { get; set; }
+
+ public string? Country { get; set; }
+
+ public string? ZipCode { get; set; }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductCreateInputVo.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductCreateInputVo.cs
new file mode 100644
index 0000000..623f4cb
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductCreateInputVo.cs
@@ -0,0 +1,47 @@
+using System.Collections.Generic;
+
+namespace FoodLabeling.Application.Contracts.Dtos.Product;
+
+public class ProductCreateInputVo
+{
+ ///
+ /// 可选。不传或空则创建时由后端生成唯一编码(如 PRD_xxxxxxxx)。
+ ///
+ public string? ProductCode { get; set; }
+
+ public string ProductName { get; set; } = string.Empty;
+
+ public string? CategoryId { get; set; }
+
+ public string? ProductImageUrl { get; set; }
+
+ /// 按钮展示文案(可选)
+ public string? DisplayText { get; set; }
+
+ /// 条码/编码值(可选)
+ public string? CodeValue { get; set; }
+
+ /// 按钮外观:TEXT / COLOR / IMAGE 或 JSON 数组(与 同序)
+ public string? ButtonAppearance { get; set; }
+
+ /// 展示值 JSON 或与 buttonAppearance 同序的色值/图片 URL
+ public string? CategoryPhotoUrl { get; set; }
+
+ public bool State { get; set; } = true;
+
+ ///
+ /// 适用 Company(fl_partner.Id,UI 称 Company);展开该公司下全部门店后与 Region/门店合并写入 fl_location_product
+ ///
+ public string? PartnerId { get; set; }
+
+ ///
+ /// 适用 Region(fl_group.Id,UI 称 Region;库字段为 location.GroupName)
+ ///
+ public List? GroupIds { get; set; }
+
+ ///
+ /// 适用门店 Id 列表;与 合并后写入 fl_location_product。
+ /// 不传则不在本接口写入门店关联。
+ ///
+ public List? LocationIds { get; set; }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductGetListOutputDto.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductGetListOutputDto.cs
new file mode 100644
index 0000000..0795955
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductGetListOutputDto.cs
@@ -0,0 +1,31 @@
+namespace FoodLabeling.Application.Contracts.Dtos.Product;
+
+public class ProductGetListOutputDto
+{
+ public string Id { get; set; } = string.Empty;
+
+ public string ProductCode { get; set; } = string.Empty;
+
+ public string ProductName { get; set; } = string.Empty;
+
+ public string? CategoryId { get; set; }
+
+ public string? CategoryName { get; set; }
+
+ public string? ProductImageUrl { get; set; }
+
+ public string? DisplayText { get; set; }
+
+ public string? CodeValue { get; set; }
+
+ public string ButtonAppearance { get; set; } = """["TEXT"]""";
+
+ public string? CategoryPhotoUrl { get; set; }
+
+ public bool State { get; set; }
+
+ ///
+ /// 该产品关联的标签数量(fl_label_product + fl_label)
+ ///
+ public long NoOfLabels { get; set; }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductGetOutputDto.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductGetOutputDto.cs
new file mode 100644
index 0000000..2d36fb4
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Product/ProductGetOutputDto.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+
+namespace FoodLabeling.Application.Contracts.Dtos.Product;
+
+public class ProductGetOutputDto
+{
+ public string Id { get; set; } = string.Empty;
+
+ public string ProductCode { get; set; } = string.Empty;
+
+ public string ProductName { get; set; } = string.Empty;
+
+ public string? CategoryId { get; set; }
+
+ public string? CategoryName { get; set; }
+
+ public string? ProductImageUrl { get; set; }
+
+ public string? DisplayText { get; set; }
+
+ public string? CodeValue { get; set; }
+
+ public string ButtonAppearance { get; set; } = """["TEXT"]""";
+
+ public string? CategoryPhotoUrl { get; set; }
+
+ public bool State { get; set; }
+
+ /// 适用 Company Id(fl_partner.Id,由关联门店反推;多公司时取第一个)
+ public string? PartnerId { get; set; }
+
+ /// 适用 Company Id 列表(去重)
+ public List PartnerIds { get; set; } = new();
+
+ /// 适用 Region Id(fl_group.Id,由关联门店反推)
+ public List GroupIds { get; set; } = new();
+
+ ///
+ /// 适用门店 Id 列表(来自 fl_location_product)
+ ///
+ public List LocationIds { get; set; } = new();
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs
new file mode 100644
index 0000000..41d380a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs
@@ -0,0 +1,41 @@
+namespace FoodLabeling.Application.Contracts.Dtos.RbacRole;
+
+///
+/// 新增角色入参(美国版对外)
+///
+public class RbacRoleCreateInputVo
+{
+ public string RoleName { get; set; } = string.Empty;
+
+ public string RoleCode { get; set; } = string.Empty;
+
+ public string? Remark { get; set; }
+
+ ///
+ /// 数据范围(与 rbac 的 DataScope 含义一致,int 存储)
+ ///
+ public int DataScope { get; set; } = 0;
+
+ public bool State { get; set; } = true;
+
+ ///
+ /// 排序号;不传或传 null 时新增默认为 0,编辑时保留原值
+ ///
+ public int? OrderNum { get; set; }
+
+ ///
+ /// 绑定菜单 Id;与 accessPermissions 同时传时以本字段为准
+ ///
+ public List? MenuIds { get; set; }
+
+ ///
+ /// 按 PermissionCode 绑定菜单(英文逗号分隔);传空字符串表示清空绑定;不传则不修改已有绑定(仅编辑时)
+ ///
+ public string? AccessPermissions { get; set; }
+
+ ///
+ /// 访问权限码列表;与 合并去重后落库
+ ///
+ public List? AccessPermissionCodes { get; set; }
+}
+
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs
new file mode 100644
index 0000000..1268350
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs
@@ -0,0 +1,32 @@
+namespace FoodLabeling.Application.Contracts.Dtos.RbacRole;
+
+///
+/// 角色列表输出(美国版对外)
+///
+public class RbacRoleGetListOutputDto
+{
+ public Guid Id { get; set; }
+
+ public string RoleName { get; set; } = string.Empty;
+
+ public string RoleCode { get; set; } = string.Empty;
+
+ public string? Remark { get; set; }
+
+ public int DataScope { get; set; }
+
+ public bool State { get; set; }
+
+ public int OrderNum { get; set; }
+
+ ///
+ /// 已绑定菜单的 PermissionCode 汇总(英文逗号+空格拼接,与 /api/app/role 一致)
+ ///
+ public string AccessPermissions { get; set; } = string.Empty;
+
+ ///
+ /// 角色访问权限码列表(与库字段 AccessPermissionCodesJson 对应)
+ ///
+ public List AccessPermissionCodes { get; set; } = new();
+}
+
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Reports/ReportsTemplatePrintStatGetListInputVo.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Reports/ReportsTemplatePrintStatGetListInputVo.cs
new file mode 100644
index 0000000..2f4fe7a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Reports/ReportsTemplatePrintStatGetListInputVo.cs
@@ -0,0 +1,27 @@
+using Volo.Abp.Application.Dtos;
+
+namespace FoodLabeling.Application.Contracts.Dtos.Reports;
+
+///
+/// 按模板统计打印数量 — 分页列表入参(筛选与 Label Report 一致)
+///
+public class ReportsTemplatePrintStatGetListInputVo : PagedAndSortedResultRequestDto
+{
+ /// Company(fl_partner.Id)
+ public string? PartnerId { get; set; }
+
+ /// Region(fl_group.Id)
+ public string? GroupId { get; set; }
+
+ /// 门店(location.Id)
+ public string? LocationId { get; set; }
+
+ /// 统计开始日期(含);未传时与 组成默认近 30 天
+ public DateTime? StartDate { get; set; }
+
+ /// 统计结束日期(含);未传时默认为今天
+ public DateTime? EndDate { get; set; }
+
+ /// 模板名称模糊匹配(fl_label_template.TemplateName)
+ public string? Keyword { get; set; }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Reports/ReportsTemplatePrintStatListItemDto.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Reports/ReportsTemplatePrintStatListItemDto.cs
new file mode 100644
index 0000000..5b02f88
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Reports/ReportsTemplatePrintStatListItemDto.cs
@@ -0,0 +1,16 @@
+namespace FoodLabeling.Application.Contracts.Dtos.Reports;
+
+///
+/// 按模板汇总的打印标签数量
+///
+public class ReportsTemplatePrintStatListItemDto
+{
+ /// 模板 Id(fl_label_template.Id)
+ public string? TemplateId { get; set; }
+
+ /// 模板名称
+ public string TemplateName { get; set; } = string.Empty;
+
+ /// 打印标签数量(fl_label_print_task 行数)
+ public int PrintedCount { get; set; }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/UsAppLabeling/UsAppLabelReportQueryInputVo.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/UsAppLabeling/UsAppLabelReportQueryInputVo.cs
new file mode 100644
index 0000000..897db5a
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/UsAppLabeling/UsAppLabelReportQueryInputVo.cs
@@ -0,0 +1,17 @@
+namespace FoodLabeling.Application.Contracts.Dtos.UsAppLabeling;
+
+///
+/// App Label Report 统计入参(单门店)
+///
+public class UsAppLabelReportQueryInputVo
+{
+ /// 当前门店 Id(必填,须为 userlocation 绑定门店)
+ public string LocationId { get; set; } = string.Empty;
+
+ public DateTime? StartDate { get; set; }
+
+ public DateTime? EndDate { get; set; }
+
+ /// 产品名 / 分类名模糊匹配(可选)
+ public string? Keyword { get; set; }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/UsAppLabeling/UsAppLabelingProductNodeDto.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/UsAppLabeling/UsAppLabelingProductNodeDto.cs
new file mode 100644
index 0000000..4d752c6
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/UsAppLabeling/UsAppLabelingProductNodeDto.cs
@@ -0,0 +1,44 @@
+namespace FoodLabeling.Application.Contracts.Dtos.UsAppLabeling;
+
+///
+/// 第三级:产品卡片(同一产品 Id 若存在多套标签模板,按 TemplateId 拆成多条,便于端上多卡展示)
+///
+public class UsAppLabelingProductNodeDto
+{
+ public string ProductId { get; set; } = string.Empty;
+
+ /// 当前卡片对应 fl_label.TemplateId;与 ProductId 共同唯一标识一张卡
+ public string TemplateId { get; set; } = string.Empty;
+
+ /// 当前卡片所用模板编码(与四级节点一致)
+ public string? TemplateCode { get; set; }
+
+ /// 当前卡片模板尺寸文案(如 6.00x12.00cm)
+ public string? TemplateLabelSizeText { get; set; }
+
+ public string ProductName { get; set; } = string.Empty;
+
+ public string ProductCode { get; set; } = string.Empty;
+
+ public string? ProductImageUrl { get; set; }
+
+ /// 按钮展示文案(fl_product.DisplayText)
+ public string? DisplayText { get; set; }
+
+ /// 条码/编码展示(fl_product.CodeValue;空为「无」)
+ public string CodeValue { get; set; } = string.Empty;
+
+ /// 按钮外观 JSON(fl_product.ButtonAppearance)
+ public string ButtonAppearance { get; set; } = """["TEXT"]""";
+
+ /// 展示值 JSON(fl_product.CategoryPhotoUrl,与 buttonAppearance 同序)
+ public string? CategoryPhotoUrl { get; set; }
+
+ /// 副标题(无独立业务字段时:有编码显示编码,否则「无」)
+ public string Subtitle { get; set; } = string.Empty;
+
+ public int LabelTypeCount { get; set; }
+
+ /// 第四级:该产品在当前标签分类+门店下可选的标签种类
+ public List LabelTypes { get; set; } = new();
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlGroupDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlGroupDbEntity.cs
index 912d853..4b4356e 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlGroupDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlGroupDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// 组织/分组(Account Management / Group,表 fl_group)
+/// 组织/分组(Account Management / Group,表 fl_group�?
///
[SugarTable("fl_group")]
public class FlGroupDbEntity
@@ -22,17 +22,17 @@ public class FlGroupDbEntity
public DateTime? LastModificationTime { get; set; }
///
- /// 组织名称(Group Name)
+ /// 组织名称(Group Name�?
///
public string GroupName { get; set; } = string.Empty;
///
- /// 所属合作伙伴 Id(fl_partner.Id)
+ /// 所属合作伙�?Id(fl_partner.Id�?
///
public string PartnerId { get; set; } = string.Empty;
///
- /// 是否启用(对应 UI Active)
+ /// 是否启用(对�?UI Active�?
///
public bool State { get; set; }
}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelCategoryDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelCategoryDbEntity.cs
index b89ab82..2c2cee4 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelCategoryDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelCategoryDbEntity.cs
@@ -25,12 +25,12 @@ public class FlLabelCategoryDbEntity
public string CategoryName { get; set; } = string.Empty;
///
- /// 按钮展示文案(为空则默认使用 CategoryName)
+ /// 按钮展示文案(为空则默认使用 CategoryName�?
///
public string? DisplayText { get; set; }
///
- /// 分类图/展示值:TEXT 可为图或空;COLOR 存色值(如 #409EFF);IMAGE 存图片 URL(与 ButtonAppearance 配合)
+ /// 分类�?展示值:TEXT 可为图或空;COLOR 存色值(�?#409EFF);IMAGE 存图�?URL(与 ButtonAppearance 配合�?
///
public string? CategoryPhotoUrl { get; set; }
@@ -39,7 +39,7 @@ public class FlLabelCategoryDbEntity
public bool State { get; set; }
///
- /// 按钮外观:TEXT / COLOR / IMAGE(展示数据见 CategoryPhotoUrl)
+ /// 按钮外观:TEXT / COLOR / IMAGE(展示数据见 CategoryPhotoUrl�?
///
public string ButtonAppearance { get; set; } = "TEXT";
@@ -48,4 +48,3 @@ public class FlLabelCategoryDbEntity
///
public string AvailabilityType { get; set; } = "ALL";
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelDbEntity.cs
index 23f6f20..f4a10e1 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelDbEntity.cs
@@ -37,8 +37,6 @@ public class FlLabelDbEntity
public bool State { get; set; }
///
- /// json 字段,直接保存为字符串(入参/出参自行序列化/反序列化)
- ///
+ /// json 字段,直接保存为字符串(入参/出参自行序列�?反序列化�? ///
public string? LabelInfoJson { get; set; }
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelMultipleOptionDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelMultipleOptionDbEntity.cs
index 231f746..9aba516 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelMultipleOptionDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelMultipleOptionDbEntity.cs
@@ -35,4 +35,3 @@ public class FlLabelMultipleOptionDbEntity
///
public string AvailabilityType { get; set; } = "ALL";
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelMultipleOptionLocationDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelMultipleOptionLocationDbEntity.cs
new file mode 100644
index 0000000..1057f97
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelMultipleOptionLocationDbEntity.cs
@@ -0,0 +1,21 @@
+using SqlSugar;
+
+namespace FoodLabeling.Application.Services.DbModels;
+
+///
+/// 标签多选项适用门店关联(对应表:fl_label_multiple_option_location�?
+///
+[SugarTable("fl_label_multiple_option_location")]
+public class FlLabelMultipleOptionLocationDbEntity
+{
+ [SugarColumn(IsPrimaryKey = true)]
+ public string Id { get; set; } = string.Empty;
+
+ public string MultipleOptionId { get; set; } = string.Empty;
+
+ public string LocationId { get; set; } = string.Empty;
+
+ public DateTime CreationTime { get; set; }
+
+ public string? CreatorId { get; set; }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelPrintDataDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelPrintDataDbEntity.cs
index 2bfa4bf..a58ba47 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelPrintDataDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelPrintDataDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// 标签打印数据明细(对应表:fl_label_print_data)
+/// 标签打印数据明细(对应表:fl_label_print_data�?
///
[SugarTable("fl_label_print_data")]
public class FlLabelPrintDataDbEntity
@@ -21,4 +21,3 @@ public class FlLabelPrintDataDbEntity
public string? RenderConfigJson { get; set; }
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelPrintTaskDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelPrintTaskDbEntity.cs
index dd56f1d..9ea5c1d 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelPrintTaskDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelPrintTaskDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// 标签打印任务(对应表:fl_label_print_task)
+/// 标签打印任务(对应表:fl_label_print_task�?
///
[SugarTable("fl_label_print_task")]
public class FlLabelPrintTaskDbEntity
@@ -51,4 +51,3 @@ public class FlLabelPrintTaskDbEntity
public DateTime CreationTime { get; set; }
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelProductDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelProductDbEntity.cs
index 42033ca..1109bbe 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelProductDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelProductDbEntity.cs
@@ -12,4 +12,3 @@ public class FlLabelProductDbEntity
public string ProductId { get; set; } = string.Empty;
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTemplateDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTemplateDbEntity.cs
index 6ca3be8..d98d173 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTemplateDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTemplateDbEntity.cs
@@ -42,4 +42,3 @@ public class FlLabelTemplateDbEntity
public bool State { get; set; }
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTemplateElementDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTemplateElementDbEntity.cs
index 3f20d9f..e9f9061 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTemplateElementDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTemplateElementDbEntity.cs
@@ -48,4 +48,3 @@ public class FlLabelTemplateElementDbEntity
public string? ConfigJson { get; set; }
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTypeDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTypeDbEntity.cs
index aa92f95..671bb4f 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTypeDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTypeDbEntity.cs
@@ -33,4 +33,3 @@ public class FlLabelTypeDbEntity
///
public string AvailabilityType { get; set; } = "ALL";
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTypeLocationDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTypeLocationDbEntity.cs
index f4da7dd..b88a881 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTypeLocationDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLabelTypeLocationDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// 标签类型适用门店关联(对应表:fl_label_type_location)
+/// 标签类型适用门店关联(对应表:fl_label_type_location�?
///
[SugarTable("fl_label_type_location")]
public class FlLabelTypeLocationDbEntity
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLocationProductDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLocationProductDbEntity.cs
index 1b2d1ad..6fd6dd7 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLocationProductDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLocationProductDbEntity.cs
@@ -12,4 +12,3 @@ public class FlLocationProductDbEntity
public string ProductId { get; set; } = string.Empty;
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLocationSupportDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLocationSupportDbEntity.cs
index 746ba5a..f21fbad 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLocationSupportDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlLocationSupportDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// 门店 Support 联系方式(每个门店仅一条,对 App Support 页展示)
+/// 门店 Support 联系方式(每个门店仅一条,�?App Support 页展示)
///
[SugarTable("fl_location_support")]
public class FlLocationSupportDbEntity
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlProductCategoryDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlProductCategoryDbEntity.cs
index 2852756..a1e74b4 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlProductCategoryDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlProductCategoryDbEntity.cs
@@ -25,17 +25,17 @@ public class FlProductCategoryDbEntity
public string CategoryName { get; set; } = string.Empty;
///
- /// 按钮展示文案(为空则默认使用 CategoryName)
+ /// 按钮展示文案(为空则默认使用 CategoryName�?
///
public string? DisplayText { get; set; }
///
- /// 分类图/展示值:TEXT 可为图或空;COLOR 存色值;IMAGE 存图片 URL(与 ButtonAppearance 配合)
+ /// 分类�?展示值:TEXT 可为图或空;COLOR 存色值;IMAGE 存图�?URL(与 ButtonAppearance 配合�?
///
public string? CategoryPhotoUrl { get; set; }
///
- /// 按钮外观:TEXT / COLOR / IMAGE(展示数据见 CategoryPhotoUrl)
+ /// 按钮外观:TEXT / COLOR / IMAGE(展示数据见 CategoryPhotoUrl�?
///
public string ButtonAppearance { get; set; } = "TEXT";
@@ -48,4 +48,3 @@ public class FlProductCategoryDbEntity
public int OrderNum { get; set; }
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlProductDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlProductDbEntity.cs
index 345f18f..cc58c8d 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlProductDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/FlProductDbEntity.cs
@@ -18,16 +18,16 @@ public class FlProductDbEntity
public string? ProductImageUrl { get; set; }
- /// 按钮展示文案(为空则客户端可回退 ProductName)
+ /// ???????????????? ProductName?
public string? DisplayText { get; set; }
- /// 条码/编码值(打印模板条形码、二维码数据源等)
+ /// ??/????????????????????
public string? CodeValue { get; set; }
- /// 按钮外观 JSON,如 ["TEXT","COLOR"] 或 ["IMAGE"]
+ /// ???? JSON?? ["TEXT","COLOR"] ? ["IMAGE"]
public string ButtonAppearance { get; set; } = """["TEXT"]""";
- /// 与 ButtonAppearance 同序的展示值 JSON(TEXT/COLOR/IMAGE)
+ /// ? ButtonAppearance ?????? JSON?TEXT/COLOR/IMAGE?
public string? CategoryPhotoUrl { get; set; }
public bool State { get; set; }
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/MenuDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/MenuDbEntity.cs
index b5ed547..3b6c9f7 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/MenuDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/MenuDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// menu 表映射(兼容数字/字符串类型的 Id、ParentId)
+/// menu 表映射(兼容数字/字符串类型的 Id、ParentId�?
///
[SugarTable("menu")]
public class MenuDbEntity
@@ -55,4 +55,3 @@ public class MenuDbEntity
public string? ConcurrencyStamp { get; set; }
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/RoleDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/RoleDbEntity.cs
index ac70bf9..fad1e74 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/RoleDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/RoleDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// Role 表映射(用于 SqlSugar 直查,避免走仓储 IDataPermission)
+/// Role 表映射(用于 SqlSugar 直查,避免走仓储 IDataPermission�?
///
[SugarTable("Role")]
public class RoleDbEntity
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/RoleMenuDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/RoleMenuDbEntity.cs
index 30e81d7..6851779 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/RoleMenuDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/RoleMenuDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// rolemenu 表映射(兼容字符串类型 RoleId/MenuId)
+/// rolemenu 表映射(兼容字符串类�?RoleId/MenuId�?
///
[SugarTable("rolemenu")]
public class RoleMenuDbEntity
@@ -15,4 +15,3 @@ public class RoleMenuDbEntity
public string MenuId { get; set; } = string.Empty;
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/UserLocationDbEntity.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/UserLocationDbEntity.cs
index 32a7db0..a6552f9 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/UserLocationDbEntity.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/UserLocationDbEntity.cs
@@ -3,7 +3,7 @@ using SqlSugar;
namespace FoodLabeling.Application.Services.DbModels;
///
-/// userlocation 表映射(成员-门店关联)
+/// userlocation 表映射(成员-门店关联�?
///
[SugarTable("userlocation")]
public class UserLocationDbEntity
@@ -27,4 +27,3 @@ public class UserLocationDbEntity
public string? ConcurrencyStamp { get; set; }
}
-
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LabelMultipleOptionAppService.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LabelMultipleOptionAppService.cs
new file mode 100644
index 0000000..a126fa3
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LabelMultipleOptionAppService.cs
@@ -0,0 +1,484 @@
+using FoodLabeling.Application.Helpers;
+using FoodLabeling.Application.Contracts.Dtos.Common;
+using FoodLabeling.Application.Contracts.Dtos.LabelMultipleOption;
+using FoodLabeling.Application.Contracts.IServices;
+using FoodLabeling.Application.Services.DbModels;
+using FoodLabeling.Domain.Entities;
+using SqlSugar;
+using Volo.Abp;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Guids;
+using Yi.Framework.SqlSugarCore.Abstractions;
+
+namespace FoodLabeling.Application.Services;
+
+public class LabelMultipleOptionAppService : ApplicationService, ILabelMultipleOptionAppService
+{
+ private readonly ISqlSugarDbContext _dbContext;
+ private readonly IGuidGenerator _guidGenerator;
+
+ public LabelMultipleOptionAppService(ISqlSugarDbContext dbContext, IGuidGenerator guidGenerator)
+ {
+ _dbContext = dbContext;
+ _guidGenerator = guidGenerator;
+ }
+
+ public async Task> GetListAsync(LabelMultipleOptionGetListInputVo input)
+ {
+ RefAsync total = 0;
+ var keyword = input.Keyword?.Trim();
+ var scopedLocationIds = await LocationScopeBindingHelper.ResolveScopedLocationIdsAsync(
+ _dbContext.SqlSugarClient, input.GroupId, input.LocationId);
+
+ var query = _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted)
+ .WhereIF(!string.IsNullOrWhiteSpace(keyword), x => x.OptionCode.Contains(keyword!) || x.OptionName.Contains(keyword!))
+ .WhereIF(input.State != null, x => x.State == input.State);
+
+ query = ApplyMultipleOptionScopeFilter(query, scopedLocationIds);
+
+ if (!string.IsNullOrWhiteSpace(input.Sorting))
+ {
+ query = query.OrderBy(input.Sorting);
+ }
+ else
+ {
+ query = query.OrderByDescending(x => x.OrderNum).OrderByDescending(x => x.CreationTime);
+ }
+
+ var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
+ var scopeMap = await BuildMultipleOptionScopeMapAsync(entities);
+
+ var items = entities.Select(x =>
+ {
+ scopeMap.TryGetValue(x.Id, out var scope);
+ return new LabelMultipleOptionGetListOutputDto
+ {
+ Id = x.Id,
+ OptionCode = FormatOptionCodeDisplay(x.OptionCode),
+ OptionName = x.OptionName,
+ OptionValuesJson = x.OptionValuesJson,
+ State = x.State,
+ AvailabilityType = x.AvailabilityType,
+ OrderNum = x.OrderNum,
+ LastEdited = x.LastModificationTime ?? x.CreationTime,
+ Region = scope?.Region ?? EmptyDisplay,
+ Location = scope?.Location ?? EmptyDisplay,
+ RegionIds = scope?.RegionIds ?? new List(),
+ LocationIds = scope?.LocationIds ?? new List()
+ };
+ }).ToList();
+
+ return BuildPagedResult(input.SkipCount, input.MaxResultCount, total, items);
+ }
+
+ public async Task GetAsync(string id)
+ {
+ var entity = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => x.Id == id && !x.IsDeleted);
+ if (entity is null)
+ {
+ throw new UserFriendlyException("多选项不存在");
+ }
+
+ var dto = MapToGetOutput(entity);
+ if (string.Equals(entity.AvailabilityType, "SPECIFIED", StringComparison.OrdinalIgnoreCase))
+ {
+ var locationIds = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => x.MultipleOptionId == entity.Id)
+ .Select(x => x.LocationId)
+ .ToListAsync();
+ dto.LocationIds = LocationScopeBindingHelper.NormalizeIds(locationIds);
+ var regionIds = await LocationScopeBindingHelper.ResolveGroupIdsFromLocationIdsAsync(
+ _dbContext.SqlSugarClient, locationIds);
+ dto.RegionIds = regionIds;
+ dto.GroupIds = regionIds;
+ }
+
+ return dto;
+ }
+
+ public async Task CreateAsync(LabelMultipleOptionCreateInputVo input)
+ {
+ var code = NormalizeOptionCode(input.OptionCode);
+ var name = input.OptionName?.Trim();
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new UserFriendlyException("多选项名称不能为空");
+ }
+
+ var (availabilityType, mergedLocationIds) = await ResolveMultipleOptionScopeForSaveAsync(input);
+
+ if (await IsMultipleOptionDuplicatedAsync(code, name, excludeId: null))
+ {
+ throw new UserFriendlyException("多选项编码或名称已存在");
+ }
+
+ var now = DateTime.Now;
+ var currentUserId = CurrentUser?.Id?.ToString();
+ var entity = new FlLabelMultipleOptionDbEntity
+ {
+ Id = _guidGenerator.Create().ToString(),
+ IsDeleted = false,
+ CreationTime = now,
+ CreatorId = currentUserId,
+ LastModificationTime = now,
+ LastModifierId = currentUserId,
+ ConcurrencyStamp = _guidGenerator.Create().ToString("N"),
+ OptionCode = code,
+ OptionName = name,
+ OptionValuesJson = input.OptionValuesJson?.Trim(),
+ State = input.State,
+ AvailabilityType = availabilityType,
+ OrderNum = input.OrderNum
+ };
+
+ await _dbContext.SqlSugarClient.Insertable(entity).ExecuteCommandAsync();
+ await SaveMultipleOptionLocationsAsync(entity.Id, availabilityType, mergedLocationIds, currentUserId, now);
+ return await GetAsync(entity.Id);
+ }
+
+ public async Task UpdateAsync(string id, LabelMultipleOptionUpdateInputVo input)
+ {
+ var entity = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => x.Id == id && !x.IsDeleted);
+ if (entity is null)
+ {
+ throw new UserFriendlyException("多选项不存在");
+ }
+
+ var code = NormalizeOptionCode(input.OptionCode);
+ var name = input.OptionName?.Trim();
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new UserFriendlyException("多选项名称不能为空");
+ }
+
+ var (availabilityType, mergedLocationIds) = await ResolveMultipleOptionScopeForSaveAsync(input);
+
+ if (await IsMultipleOptionDuplicatedAsync(code, name, excludeId: id))
+ {
+ throw new UserFriendlyException("多选项编码或名称已存在");
+ }
+
+ entity.OptionCode = code;
+ entity.OptionName = name;
+ entity.OptionValuesJson = input.OptionValuesJson?.Trim();
+ entity.State = input.State;
+ entity.AvailabilityType = availabilityType;
+ entity.OrderNum = input.OrderNum;
+ entity.LastModificationTime = DateTime.Now;
+ entity.LastModifierId = CurrentUser?.Id?.ToString();
+
+ await _dbContext.SqlSugarClient.Updateable(entity).ExecuteCommandAsync();
+ await SaveMultipleOptionLocationsAsync(entity.Id, availabilityType, mergedLocationIds, entity.LastModifierId,
+ entity.LastModificationTime ?? DateTime.Now);
+ return await GetAsync(id);
+ }
+
+ public async Task DeleteAsync(string id)
+ {
+ var entity = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => x.Id == id && !x.IsDeleted);
+ if (entity is null)
+ {
+ return;
+ }
+
+ await _dbContext.SqlSugarClient.Deleteable()
+ .Where(x => x.MultipleOptionId == id)
+ .ExecuteCommandAsync();
+
+ entity.IsDeleted = true;
+ entity.LastModificationTime = DateTime.Now;
+ entity.LastModifierId = CurrentUser?.Id?.ToString();
+ await _dbContext.SqlSugarClient.Updateable(entity).ExecuteCommandAsync();
+ }
+
+ private const string EmptyDisplay = "无";
+ private const string AllRegionsDisplay = "All Regions";
+ private const string AllLocationsDisplay = "All Locations";
+
+ private async Task<(string AvailabilityType, List LocationIds)> ResolveMultipleOptionScopeForSaveAsync(
+ LabelMultipleOptionCreateInputVo input)
+ {
+ var regionIds = NormalizeRegionIds(input);
+ var explicitLocationIds = LocationScopeBindingHelper.NormalizeIds(input.LocationIds);
+ var availabilityType = (input.AvailabilityType ?? "ALL").Trim().ToUpperInvariant();
+
+ var hasScopeArrays = input.RegionIds is not null || input.GroupIds is not null || input.LocationIds is not null;
+ if (regionIds.Count > 0 || explicitLocationIds.Count > 0)
+ {
+ availabilityType = "SPECIFIED";
+ }
+ else if (hasScopeArrays && string.Equals(availabilityType, "ALL", StringComparison.OrdinalIgnoreCase))
+ {
+ availabilityType = "ALL";
+ }
+
+ if (availabilityType != "ALL" && availabilityType != "SPECIFIED")
+ {
+ throw new UserFriendlyException("门店可用范围不合法(ALL/SPECIFIED)");
+ }
+
+ if (availabilityType == "ALL")
+ {
+ return ("ALL", new List());
+ }
+
+ var merged = await LocationScopeBindingHelper.MergeToLocationIdsAsync(
+ _dbContext.SqlSugarClient, (IReadOnlyList?)null, regionIds, explicitLocationIds);
+ if (merged.Count == 0)
+ {
+ throw new UserFriendlyException("指定适用区域或门店时,至少需要匹配到一个有效门店");
+ }
+
+ await LocationScopeBindingHelper.ValidateLocationIdsExistAsync(_dbContext.SqlSugarClient, merged);
+ return ("SPECIFIED", merged);
+ }
+
+ private static List NormalizeRegionIds(LabelMultipleOptionCreateInputVo input)
+ {
+ var merged = new HashSet(StringComparer.Ordinal);
+ foreach (var id in LocationScopeBindingHelper.NormalizeIds(input.RegionIds))
+ {
+ merged.Add(id);
+ }
+
+ foreach (var id in LocationScopeBindingHelper.NormalizeIds(input.GroupIds))
+ {
+ merged.Add(id);
+ }
+
+ return merged.OrderBy(x => x, StringComparer.Ordinal).ToList();
+ }
+
+ private async Task SaveMultipleOptionLocationsAsync(
+ string multipleOptionId,
+ string availabilityType,
+ List locationIds,
+ string? currentUserId,
+ DateTime now)
+ {
+ await _dbContext.SqlSugarClient.Deleteable()
+ .Where(x => x.MultipleOptionId == multipleOptionId)
+ .ExecuteCommandAsync();
+
+ if (availabilityType != "SPECIFIED" || locationIds.Count == 0)
+ {
+ return;
+ }
+
+ var rows = locationIds.Select(locId => new FlLabelMultipleOptionLocationDbEntity
+ {
+ Id = _guidGenerator.Create().ToString(),
+ MultipleOptionId = multipleOptionId,
+ LocationId = locId,
+ CreationTime = now,
+ CreatorId = currentUserId
+ }).ToList();
+
+ await _dbContext.SqlSugarClient.Insertable(rows).ExecuteCommandAsync();
+ }
+
+ private static string NormalizeOptionCode(string? optionCode) => optionCode?.Trim() ?? string.Empty;
+
+ private static string FormatOptionCodeDisplay(string? optionCode) =>
+ string.IsNullOrWhiteSpace(optionCode) ? EmptyDisplay : optionCode.Trim();
+
+ private async Task IsMultipleOptionDuplicatedAsync(string code, string name, string? excludeId)
+ {
+ var query = _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted);
+ if (!string.IsNullOrWhiteSpace(excludeId))
+ {
+ query = query.Where(x => x.Id != excludeId);
+ }
+
+ if (string.IsNullOrEmpty(code))
+ {
+ return await query.AnyAsync(x => x.OptionName == name);
+ }
+
+ return await query.AnyAsync(x => x.OptionCode == code || x.OptionName == name);
+ }
+
+ private static LabelMultipleOptionGetOutputDto MapToGetOutput(FlLabelMultipleOptionDbEntity x)
+ {
+ return new LabelMultipleOptionGetOutputDto
+ {
+ Id = x.Id,
+ OptionCode = FormatOptionCodeDisplay(x.OptionCode),
+ OptionName = x.OptionName,
+ OptionValuesJson = x.OptionValuesJson,
+ State = x.State,
+ OrderNum = x.OrderNum,
+ AvailabilityType = x.AvailabilityType
+ };
+ }
+
+ private static ISugarQueryable ApplyMultipleOptionScopeFilter(
+ ISugarQueryable query,
+ List? scopedLocationIds)
+ {
+ if (scopedLocationIds is null)
+ {
+ return query;
+ }
+
+ if (scopedLocationIds.Count == 0)
+ {
+ return query.Where(o => o.AvailabilityType == "ALL");
+ }
+
+ return query.Where(o =>
+ o.AvailabilityType == "ALL" ||
+ SqlFunc.Subqueryable()
+ .Where(ol => ol.MultipleOptionId == o.Id && scopedLocationIds.Contains(ol.LocationId))
+ .Any());
+ }
+
+ private async Task> BuildMultipleOptionScopeMapAsync(
+ List entities)
+ {
+ var result = new Dictionary(StringComparer.Ordinal);
+ if (entities.Count == 0)
+ {
+ return result;
+ }
+
+ foreach (var e in entities.Where(x =>
+ !string.Equals(x.AvailabilityType, "SPECIFIED", StringComparison.OrdinalIgnoreCase)))
+ {
+ result[e.Id] = new MultipleOptionScopeData
+ {
+ Region = AllRegionsDisplay,
+ Location = AllLocationsDisplay,
+ RegionIds = new List(),
+ LocationIds = new List()
+ };
+ }
+
+ var specifiedIds = entities
+ .Where(x => string.Equals(x.AvailabilityType, "SPECIFIED", StringComparison.OrdinalIgnoreCase))
+ .Select(x => x.Id)
+ .ToList();
+ if (specifiedIds.Count == 0)
+ {
+ return result;
+ }
+
+ var links = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => specifiedIds.Contains(x.MultipleOptionId))
+ .ToListAsync();
+
+ var locIdSet = links
+ .Select(x => x.LocationId)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x.Trim())
+ .Distinct(StringComparer.Ordinal)
+ .ToList();
+
+ var locById = new Dictionary(StringComparer.Ordinal);
+ if (locIdSet.Count > 0)
+ {
+ var guidList = locIdSet.Where(x => Guid.TryParse(x, out _)).Select(Guid.Parse).ToList();
+ if (guidList.Count > 0)
+ {
+ var locs = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted && guidList.Contains(x.Id))
+ .ToListAsync();
+ foreach (var loc in locs)
+ {
+ locById[loc.Id.ToString()] = loc;
+ }
+ }
+ }
+
+ foreach (var optionId in specifiedIds)
+ {
+ var optionLinks = links.Where(x => x.MultipleOptionId == optionId).ToList();
+ var locationIds = LocationScopeBindingHelper.NormalizeIds(
+ optionLinks.Select(x => x.LocationId).ToList());
+
+ if (optionLinks.Count == 0)
+ {
+ result[optionId] = new MultipleOptionScopeData
+ {
+ Region = EmptyDisplay,
+ Location = EmptyDisplay,
+ RegionIds = new List(),
+ LocationIds = new List()
+ };
+ continue;
+ }
+
+ var regions = new HashSet(StringComparer.OrdinalIgnoreCase);
+ var locationNames = new HashSet(StringComparer.OrdinalIgnoreCase);
+ foreach (var lid in locationIds)
+ {
+ if (!locById.TryGetValue(lid, out var loc))
+ {
+ continue;
+ }
+
+ var groupName = loc.GroupName?.Trim();
+ if (!string.IsNullOrEmpty(groupName))
+ {
+ regions.Add(groupName);
+ }
+
+ var locName = loc.LocationName?.Trim();
+ if (string.IsNullOrEmpty(locName))
+ {
+ locName = loc.LocationCode?.Trim();
+ }
+
+ if (!string.IsNullOrEmpty(locName))
+ {
+ locationNames.Add(locName);
+ }
+ }
+
+ var regionIds = await LocationScopeBindingHelper.ResolveGroupIdsFromLocationIdsAsync(
+ _dbContext.SqlSugarClient, locationIds);
+
+ result[optionId] = new MultipleOptionScopeData
+ {
+ Region = regions.Count > 0
+ ? string.Join(", ", regions.OrderBy(x => x, StringComparer.OrdinalIgnoreCase))
+ : EmptyDisplay,
+ Location = locationNames.Count > 0
+ ? string.Join(", ", locationNames.OrderBy(x => x, StringComparer.OrdinalIgnoreCase))
+ : EmptyDisplay,
+ RegionIds = regionIds,
+ LocationIds = locationIds
+ };
+ }
+
+ return result;
+ }
+
+ private sealed class MultipleOptionScopeData
+ {
+ public string Region { get; init; } = string.Empty;
+ public string Location { get; init; } = string.Empty;
+ public List RegionIds { get; init; } = new();
+ public List LocationIds { get; init; } = new();
+ }
+
+ private static PagedResultWithPageDto BuildPagedResult(int skipCount, int maxResultCount, int total, List items)
+ {
+ var pageSize = maxResultCount <= 0 ? items.Count : maxResultCount;
+ var pageIndex = pageSize <= 0 ? 1 : PagedQueryConvention.PageIndexFromSkipCount(skipCount);
+ var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize);
+ return new PagedResultWithPageDto
+ {
+ PageIndex = pageIndex,
+ PageSize = pageSize,
+ TotalCount = total,
+ TotalPages = totalPages,
+ Items = items
+ };
+ }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/ProductAppService.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/ProductAppService.cs
new file mode 100644
index 0000000..2a2bd20
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/ProductAppService.cs
@@ -0,0 +1,840 @@
+using System.IO;
+using FoodLabeling.Application.Contracts.Dtos.Common;
+using FoodLabeling.Application.Contracts.Dtos.Product;
+using FoodLabeling.Application.Contracts.IServices;
+using FoodLabeling.Application.Helpers;
+using FoodLabeling.Application.Options;
+using FoodLabeling.Application.Services.DbModels;
+using FoodLabeling.Domain.Entities;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Options;
+using SqlSugar;
+using Volo.Abp;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Guids;
+using Volo.Abp.Uow;
+using Yi.Framework.SqlSugarCore.Abstractions;
+
+namespace FoodLabeling.Application.Services;
+
+///
+/// 产品管理(Products)
+///
+public class ProductAppService : ApplicationService, IProductAppService
+{
+ private readonly ISqlSugarDbContext _dbContext;
+ private readonly IGuidGenerator _guidGenerator;
+ private readonly IOptionsSnapshot _batchImportOptions;
+
+ public ProductAppService(
+ ISqlSugarDbContext dbContext,
+ IGuidGenerator guidGenerator,
+ IOptionsSnapshot batchImportOptions)
+ {
+ _dbContext = dbContext;
+ _guidGenerator = guidGenerator;
+ _batchImportOptions = batchImportOptions;
+ }
+
+ ///
+ public async Task> GetListAsync(ProductGetListInputVo input)
+ {
+ RefAsync total = 0;
+
+ var query = await BuildFilteredProductQueryAsync(input);
+ if (!string.IsNullOrWhiteSpace(input.Sorting))
+ {
+ query = query.OrderBy(input.Sorting);
+ }
+ else
+ {
+ query = query.OrderByDescending(x => x.ProductName);
+ }
+
+ var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
+ var ids = entities.Select(x => x.Id).ToList();
+
+ // Count labels for each product
+ var countMap = new Dictionary();
+ if (ids.Count > 0)
+ {
+ var countRows = await _dbContext.SqlSugarClient.Queryable(
+ (lp, l) => lp.LabelId == l.Id)
+ .Where((lp, l) => !l.IsDeleted && ids.Contains(lp.ProductId))
+ .GroupBy((lp, l) => lp.ProductId)
+ .Select((lp, l) => new { ProductId = lp.ProductId, Count = SqlFunc.AggregateCount(lp.Id) })
+ .ToListAsync();
+
+ countMap = countRows.ToDictionary(x => x.ProductId, x => (long)x.Count);
+ }
+
+ var categoryIds = entities
+ .Select(x => x.CategoryId)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x!.Trim())
+ .Distinct()
+ .ToList();
+
+ var categoryMap = new Dictionary();
+ if (categoryIds.Count > 0)
+ {
+ var categories = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted && categoryIds.Contains(x.Id))
+ .ToListAsync();
+ categoryMap = categories.ToDictionary(x => x.Id, x => x);
+ }
+
+ var items = entities.Select(x =>
+ {
+ var categoryName = "无";
+ if (!string.IsNullOrWhiteSpace(x.CategoryId) && categoryMap.TryGetValue(x.CategoryId.Trim(), out var c))
+ {
+ categoryName = string.IsNullOrWhiteSpace(c.CategoryName) ? "无" : c.CategoryName.Trim();
+ }
+
+ return new ProductGetListOutputDto
+ {
+ Id = x.Id,
+ ProductCode = x.ProductCode,
+ ProductName = x.ProductName,
+ CategoryId = x.CategoryId,
+ CategoryName = categoryName,
+ ProductImageUrl = x.ProductImageUrl,
+ DisplayText = x.DisplayText,
+ CodeValue = FormatCodeValueDisplay(x.CodeValue),
+ ButtonAppearance = x.ButtonAppearance,
+ CategoryPhotoUrl = x.CategoryPhotoUrl,
+ State = x.State,
+ NoOfLabels = countMap.TryGetValue(x.Id, out var count) ? count : 0
+ };
+ }).ToList();
+
+ return BuildPagedResult(input.SkipCount, input.MaxResultCount, (int)total, items);
+ }
+
+ public async Task GetAsync(Guid id)
+ {
+ if (id == Guid.Empty)
+ {
+ throw new UserFriendlyException("产品Id不能为空");
+ }
+
+ var productId = id.ToString();
+ var entity = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.Id == productId);
+
+ if (entity is null)
+ {
+ throw new UserFriendlyException("产品不存在");
+ }
+
+ string? categoryName = "无";
+ if (!string.IsNullOrWhiteSpace(entity.CategoryId))
+ {
+ var c = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.Id == entity.CategoryId);
+ if (c is not null && !string.IsNullOrWhiteSpace(c.CategoryName))
+ {
+ categoryName = c.CategoryName.Trim();
+ }
+ }
+
+ var locationIds = LocationScopeBindingHelper.NormalizeIds(
+ await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => x.ProductId == productId)
+ .Select(x => x.LocationId)
+ .ToListAsync());
+ var partnerIds = await LocationScopeBindingHelper.ResolvePartnerIdsFromLocationIdsAsync(
+ _dbContext.SqlSugarClient, locationIds);
+ var groupIds = await LocationScopeBindingHelper.ResolveGroupIdsFromLocationIdsAsync(
+ _dbContext.SqlSugarClient, locationIds);
+
+ return new ProductGetOutputDto
+ {
+ Id = entity.Id,
+ ProductCode = entity.ProductCode,
+ ProductName = entity.ProductName,
+ CategoryId = entity.CategoryId,
+ CategoryName = categoryName,
+ ProductImageUrl = entity.ProductImageUrl,
+ DisplayText = entity.DisplayText,
+ CodeValue = FormatCodeValueDisplay(entity.CodeValue),
+ ButtonAppearance = entity.ButtonAppearance,
+ CategoryPhotoUrl = entity.CategoryPhotoUrl,
+ State = entity.State,
+ PartnerId = partnerIds.Count > 0 ? partnerIds[0] : null,
+ PartnerIds = partnerIds,
+ GroupIds = groupIds,
+ LocationIds = locationIds
+ };
+ }
+
+ [UnitOfWork]
+ public async Task CreateAsync(ProductCreateInputVo input)
+ {
+ var name = input.ProductName?.Trim();
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new UserFriendlyException("产品名称不能为空");
+ }
+
+ var code = input.ProductCode?.Trim();
+ if (string.IsNullOrWhiteSpace(code))
+ {
+ code = await GenerateUniqueProductCodeAsync();
+ }
+ else
+ {
+ var duplicated = await _dbContext.SqlSugarClient.Queryable()
+ .AnyAsync(x => !x.IsDeleted && x.ProductCode == code);
+ if (duplicated)
+ {
+ throw new UserFriendlyException("产品编码已存在");
+ }
+ }
+
+ var entity = new FlProductDbEntity
+ {
+ Id = _guidGenerator.Create().ToString(),
+ IsDeleted = false,
+ ProductCode = code,
+ ProductName = name,
+ CategoryId = input.CategoryId?.Trim(),
+ ProductImageUrl = input.ProductImageUrl?.Trim(),
+ State = input.State
+ };
+ ApplyProductAppearanceToEntity(entity, input);
+
+ await _dbContext.SqlSugarClient.Insertable(entity).ExecuteCommandAsync();
+
+ if (HasProductScopeBinding(input))
+ {
+ var locIds = await ResolveProductLocationIdsForSaveAsync(input);
+ await ReplaceProductLocationLinksAsync(entity.Id, locIds);
+ }
+
+ return await GetAsync(Guid.Parse(entity.Id));
+ }
+
+ [UnitOfWork]
+ public async Task UpdateAsync(Guid id, ProductUpdateInputVo input)
+ {
+ if (id == Guid.Empty)
+ {
+ throw new UserFriendlyException("产品Id不能为空");
+ }
+
+ var productId = id.ToString();
+ var entity = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.Id == productId);
+ if (entity is null)
+ {
+ throw new UserFriendlyException("产品不存在");
+ }
+
+ var name = input.ProductName?.Trim();
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new UserFriendlyException("产品名称不能为空");
+ }
+
+ var codeInput = input.ProductCode?.Trim();
+ var code = string.IsNullOrWhiteSpace(codeInput) ? entity.ProductCode : codeInput;
+ if (string.IsNullOrWhiteSpace(code))
+ {
+ code = await GenerateUniqueProductCodeAsync();
+ }
+
+ if (code != entity.ProductCode)
+ {
+ var duplicated = await _dbContext.SqlSugarClient.Queryable()
+ .AnyAsync(x => !x.IsDeleted && x.Id != productId && x.ProductCode == code);
+ if (duplicated)
+ {
+ throw new UserFriendlyException("产品编码已存在");
+ }
+ }
+
+ entity.ProductCode = code;
+ entity.ProductName = name;
+ entity.CategoryId = input.CategoryId?.Trim();
+ entity.ProductImageUrl = input.ProductImageUrl?.Trim();
+ entity.State = input.State;
+ ApplyProductAppearanceToEntity(entity, input);
+
+ await _dbContext.SqlSugarClient.Updateable(entity).ExecuteCommandAsync();
+
+ if (HasProductScopeBinding(input))
+ {
+ var locIds = await ResolveProductLocationIdsForSaveAsync(input);
+ await ReplaceProductLocationLinksAsync(productId, locIds);
+ }
+
+ return await GetAsync(id);
+ }
+
+ [UnitOfWork]
+ public async Task DeleteAsync(Guid id)
+ {
+ if (id == Guid.Empty)
+ {
+ throw new UserFriendlyException("产品Id不能为空");
+ }
+
+ var productId = id.ToString();
+ var entity = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.Id == productId);
+ if (entity is null)
+ {
+ throw new UserFriendlyException("产品不存在");
+ }
+
+ entity.IsDeleted = true;
+ await _dbContext.SqlSugarClient.Updateable(entity).ExecuteCommandAsync();
+ }
+
+ ///
+ [HttpGet]
+ public Task DownloadProductImportTemplateAsync()
+ {
+ var opt = _batchImportOptions.Value;
+ var dir = opt.TemplateDirectory?.Trim();
+ if (string.IsNullOrWhiteSpace(dir))
+ {
+ throw new UserFriendlyException("未配置批量导入模板目录 FoodLabeling:BatchImport:TemplateDirectory");
+ }
+
+ var fileName = opt.ProductTemplateFileName?.Trim();
+ if (string.IsNullOrWhiteSpace(fileName))
+ {
+ throw new UserFriendlyException("未配置模板文件名 FoodLabeling:BatchImport:ProductTemplateFileName");
+ }
+
+ var fullPath = Path.Combine(dir, fileName);
+ if (!File.Exists(fullPath))
+ {
+ throw new UserFriendlyException($"模板文件不存在:{fullPath}");
+ }
+
+ var stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+ return Task.FromResult(new FileStreamResult(stream, contentType)
+ {
+ FileDownloadName = fileName
+ });
+ }
+
+ ///
+ [HttpGet]
+ public async Task ExportProductsExcelAsync([FromQuery] ProductGetListInputVo input)
+ {
+ var exportFilter = new ProductGetListInputVo
+ {
+ Sorting = input.Sorting,
+ Keyword = input.Keyword,
+ State = input.State,
+ PartnerId = input.PartnerId,
+ GroupId = input.GroupId,
+ LocationId = input.LocationId
+ };
+
+ var query = await BuildFilteredProductQueryAsync(exportFilter);
+ if (!string.IsNullOrWhiteSpace(exportFilter.Sorting))
+ {
+ query = query.OrderBy(exportFilter.Sorting);
+ }
+ else
+ {
+ query = query.OrderByDescending(x => x.ProductName);
+ }
+
+ var entities = await query.ToListAsync();
+ var exportRows = await BuildProductExcelExportRowsAsync(entities);
+ var ms = ProductBatchExcelHelper.BuildExportWorkbook(exportRows);
+ const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+ var downloadName = $"products-export-{Clock.Now:yyyyMMdd-HHmmss}.xlsx";
+ return new FileStreamResult(ms, contentType) { FileDownloadName = downloadName };
+ }
+
+ ///
+ [HttpPost]
+ public async Task ImportProductsBatchAsync(
+ [FromForm] ProductBatchImportInputVo input)
+ {
+ if (input?.File is null || input.File.Length == 0)
+ {
+ throw new UserFriendlyException("请上传 Excel 文件(form 字段名:file)");
+ }
+
+ var opt = _batchImportOptions.Value;
+ if (input.File.Length > opt.MaxUploadBytes)
+ {
+ throw new UserFriendlyException($"文件过大,最大允许 {opt.MaxUploadBytes / 1024 / 1024} MB");
+ }
+
+ var ext = Path.GetExtension(input.File.FileName)?.ToLowerInvariant();
+ if (ext != ".xlsx")
+ {
+ throw new UserFriendlyException("仅支持 .xlsx 格式的 Excel 文件");
+ }
+
+ await using var uploadStream = input.File.OpenReadStream();
+ var parseErrors = new List();
+ var rows = ProductBatchExcelHelper.ParseImportWorkbook(
+ uploadStream,
+ opt.MaxImportRows <= 0 ? 5000 : opt.MaxImportRows,
+ out var headerErrors);
+ parseErrors.AddRange(headerErrors);
+
+ var result = new ProductBatchImportResultDto();
+ if (rows.Count == 0 && parseErrors.Count > 0)
+ {
+ result.Errors = parseErrors;
+ result.FailCount = parseErrors.Count;
+ return result;
+ }
+
+ foreach (var (rowNum, locCell, catName, prodName, codeStr) in rows)
+ {
+ try
+ {
+ var categoryId = await ResolveCategoryIdByNameAsync(catName);
+ List? locationIds = null;
+ if (!string.IsNullOrWhiteSpace(locCell))
+ {
+ locationIds = await ResolveLocationIdsFromImportDisplayCellAsync(locCell);
+ }
+
+ await CreateAsync(new ProductCreateInputVo
+ {
+ ProductName = prodName,
+ CategoryId = categoryId,
+ ProductCode = string.IsNullOrWhiteSpace(codeStr) ? null : codeStr,
+ State = true,
+ LocationIds = locationIds
+ });
+ result.SuccessCount++;
+ }
+ catch (UserFriendlyException ex)
+ {
+ result.FailCount++;
+ result.Errors.Add(new ProductBatchImportErrorDto
+ {
+ RowNumber = rowNum,
+ ProductName = prodName,
+ Message = ex.Message
+ });
+ }
+ }
+
+ result.Errors.InsertRange(0, parseErrors);
+ return result;
+ }
+
+ ///
+ public async Task UpdateProductsBulkAsync(
+ [FromBody] ProductBulkUpdateInputVo input)
+ {
+ if (input?.Items is null || input.Items.Count == 0)
+ {
+ throw new UserFriendlyException("请至少提交一条编辑数据(items 不能为空)");
+ }
+
+ var opt = _batchImportOptions.Value;
+ var maxItems = opt.MaxBulkUpdateItems <= 0 ? 500 : opt.MaxBulkUpdateItems;
+ if (input.Items.Count > maxItems)
+ {
+ throw new UserFriendlyException($"单次批量编辑最多允许 {maxItems} 条,请分批提交");
+ }
+
+ var effectiveCount = input.Items.Count(static x =>
+ x is not null &&
+ !string.IsNullOrWhiteSpace(x.Id) &&
+ Guid.TryParse(x.Id!.Trim(), out var g) &&
+ g != Guid.Empty);
+ if (effectiveCount == 0)
+ {
+ throw new UserFriendlyException("没有有效的产品 Id(请为待保存行填写 Guid 格式 id)");
+ }
+
+ var result = new ProductBulkUpdateResultDto();
+ for (var i = 0; i < input.Items.Count; i++)
+ {
+ var item = input.Items[i];
+ if (item is null || string.IsNullOrWhiteSpace(item.Id))
+ {
+ continue;
+ }
+
+ if (!Guid.TryParse(item.Id.Trim(), out var productGuid) || productGuid == Guid.Empty)
+ {
+ continue;
+ }
+
+ try
+ {
+ await UpdateAsync(productGuid, item);
+ result.SuccessCount++;
+ }
+ catch (UserFriendlyException ex)
+ {
+ result.FailCount++;
+ result.Errors.Add(new ProductBulkUpdateErrorDto
+ {
+ RowNumber = i + 1,
+ Id = item.Id.Trim(),
+ Message = ex.Message
+ });
+ }
+ }
+
+ return result;
+ }
+
+ private async Task> BuildFilteredProductQueryAsync(ProductGetListInputVo input)
+ {
+ var keyword = input.Keyword?.Trim();
+
+ var query = _dbContext.SqlSugarClient
+ .Queryable()
+ .Where(x => !x.IsDeleted)
+ .WhereIF(input.State != null, x => x.State == input.State);
+
+ var locationIds = await ResolveFilteredLocationIdsAsync(input.PartnerId, input.GroupId, input.LocationId);
+ if (locationIds is not null)
+ {
+ if (locationIds.Count == 0)
+ {
+ query = query.Where(_ => false);
+ }
+ else
+ {
+ query = query.Where(p =>
+ SqlFunc.Subqueryable()
+ .Where(lp => lp.ProductId == p.Id && locationIds.Contains(lp.LocationId))
+ .Any());
+ }
+ }
+
+ if (!string.IsNullOrWhiteSpace(keyword))
+ {
+ query = query
+ .LeftJoin((p, c) => p.CategoryId == c.Id)
+ .Where((p, c) =>
+ p.ProductCode.Contains(keyword!) ||
+ p.ProductName.Contains(keyword!) ||
+ (c.CategoryName != null && c.CategoryName.Contains(keyword!)))
+ .Select((p, c) => p);
+ }
+
+ return query;
+ }
+
+ ///
+ /// 与 Reports 列表一致:按门店 Id 优先,否则按 Region(groupId)或公司(partnerId)解析 location 主键集合。
+ ///
+ private async Task?> ResolveFilteredLocationIdsAsync(string? partnerId, string? groupId,
+ string? locationId)
+ {
+ var locId = locationId?.Trim();
+ if (!string.IsNullOrWhiteSpace(locId))
+ {
+ if (!Guid.TryParse(locId, out var locationGuid))
+ {
+ return new List();
+ }
+
+ var exists = await _dbContext.SqlSugarClient.Queryable()
+ .AnyAsync(x => !x.IsDeleted && x.Id == locationGuid);
+ return exists ? new List { locId } : new List();
+ }
+
+ var gid = groupId?.Trim();
+ var pid = partnerId?.Trim();
+
+ if (string.IsNullOrWhiteSpace(pid) && string.IsNullOrWhiteSpace(gid))
+ {
+ return null;
+ }
+
+ var q = _dbContext.SqlSugarClient.Queryable().Where(x => !x.IsDeleted);
+
+ if (!string.IsNullOrWhiteSpace(gid))
+ {
+ var g = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.Id == gid);
+ if (g is null)
+ {
+ return new List();
+ }
+
+ var gName = g.GroupName?.Trim() ?? string.Empty;
+ var partner = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.Id == g.PartnerId);
+ var pName = partner?.PartnerName?.Trim() ?? string.Empty;
+ q = q.Where(x => x.GroupName == gName && x.Partner == pName);
+ }
+ else if (!string.IsNullOrWhiteSpace(pid))
+ {
+ var partner = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.Id == pid);
+ if (partner is null)
+ {
+ return new List();
+ }
+
+ var pName = partner.PartnerName?.Trim() ?? string.Empty;
+ q = q.Where(x => x.Partner == pName);
+ }
+
+ return await q.Select(x => SqlFunc.ToString(x.Id)).ToListAsync();
+ }
+
+ private async Task> BuildProductExcelExportRowsAsync(
+ List entities)
+ {
+ if (entities.Count == 0)
+ {
+ return new List();
+ }
+
+ var categoryIds = entities
+ .Select(x => x.CategoryId)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x!.Trim())
+ .Distinct()
+ .ToList();
+
+ var categoryMap = new Dictionary();
+ if (categoryIds.Count > 0)
+ {
+ var cats = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted && categoryIds.Contains(x.Id))
+ .ToListAsync();
+ categoryMap = cats.ToDictionary(x => x.Id, x => x);
+ }
+
+ var productIds = entities.Select(x => x.Id).ToList();
+ var links = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => productIds.Contains(x.ProductId))
+ .ToListAsync();
+
+ var locIdSet = links
+ .Select(x => x.LocationId)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x.Trim())
+ .Distinct()
+ .ToList();
+
+ var locs = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted && locIdSet.Contains(x.Id.ToString()))
+ .Select(x => new { x.Id, x.LocationName })
+ .ToListAsync();
+
+ var locNameById = locs.ToDictionary(x => x.Id.ToString(), x => x.LocationName?.Trim() ?? string.Empty);
+
+ var locDisplayByProduct = links
+ .GroupBy(x => x.ProductId)
+ .ToDictionary(
+ g => g.Key,
+ g => string.Join(", ",
+ g.Select(y => y.LocationId.Trim())
+ .Distinct()
+ .Select(lid => locNameById.GetValueOrDefault(lid, lid))
+ .Where(s => !string.IsNullOrEmpty(s))
+ .Distinct()));
+
+ var rows = new List();
+ foreach (var e in entities)
+ {
+ var catName = "无";
+ if (!string.IsNullOrWhiteSpace(e.CategoryId) && categoryMap.TryGetValue(e.CategoryId.Trim(), out var c))
+ {
+ catName = string.IsNullOrWhiteSpace(c.CategoryName) ? "无" : c.CategoryName.Trim();
+ }
+
+ locDisplayByProduct.TryGetValue(e.Id, out var locDisp);
+ var locationDisplay = string.IsNullOrWhiteSpace(locDisp) ? string.Empty : locDisp;
+ rows.Add(new ProductBatchExcelHelper.ExportRow(
+ locationDisplay,
+ catName,
+ e.ProductName ?? string.Empty,
+ e.ProductCode ?? string.Empty));
+ }
+
+ return rows;
+ }
+
+ private async Task ResolveCategoryIdByNameAsync(string categoryName)
+ {
+ var n = categoryName.Trim();
+ if (string.IsNullOrWhiteSpace(n))
+ {
+ throw new UserFriendlyException("产品分类名称不能为空");
+ }
+
+ var lowered = n.ToLowerInvariant();
+ var matches = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted && x.CategoryName.ToLower() == lowered)
+ .ToListAsync();
+
+ if (matches.Count == 0)
+ {
+ throw new UserFriendlyException($"未找到产品分类「{n}」");
+ }
+
+ if (matches.Count > 1)
+ {
+ throw new UserFriendlyException($"产品分类「{n}」存在多条记录,请在系统中使用唯一名称");
+ }
+
+ return matches[0].Id;
+ }
+
+ private async Task> ResolveLocationIdsFromImportDisplayCellAsync(string cell)
+ {
+ var tokens = cell.Split(new[] { ',', ',', ';', ';', '|', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(x => x.Trim())
+ .Where(x => !string.IsNullOrEmpty(x))
+ .Distinct(StringComparer.Ordinal)
+ .ToList();
+
+ var result = new List();
+ foreach (var t in tokens)
+ {
+ var idStr = await ResolveSingleLocationTokenToIdStringAsync(t);
+ result.Add(idStr);
+ }
+
+ return result.Distinct(StringComparer.Ordinal).ToList();
+ }
+
+ private async Task ResolveSingleLocationTokenToIdStringAsync(string token)
+ {
+ var t = token.Trim();
+ if (Guid.TryParse(t, out var gid))
+ {
+ var byIdList = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted && x.Id == gid)
+ .Take(1)
+ .ToListAsync();
+ var byId = byIdList.FirstOrDefault();
+ if (byId is null)
+ {
+ throw new UserFriendlyException($"未找到门店 Id:{t}");
+ }
+
+ return byId.Id.ToString();
+ }
+
+ var lowered = t.ToLowerInvariant();
+ var matches = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted &&
+ (x.LocationCode == t ||
+ x.LocationName.ToLower() == lowered))
+ .ToListAsync();
+
+ if (matches.Count == 0)
+ {
+ throw new UserFriendlyException($"未找到门店:{t}");
+ }
+
+ if (matches.Count > 1)
+ {
+ throw new UserFriendlyException($"门店「{t}」存在多条匹配,请使用 Location Code 或 Guid");
+ }
+
+ return matches[0].Id.ToString();
+ }
+
+ ///
+ /// 生成未删除数据中不重复的 PRD_ 前缀产品编码。
+ ///
+ private async Task GenerateUniqueProductCodeAsync()
+ {
+ for (var i = 0; i < 8; i++)
+ {
+ var code = $"PRD_{_guidGenerator.Create():N}";
+ var exists = await _dbContext.SqlSugarClient.Queryable()
+ .AnyAsync(x => !x.IsDeleted && x.ProductCode == code);
+ if (!exists)
+ {
+ return code;
+ }
+ }
+
+ throw new UserFriendlyException("无法生成唯一产品编码,请稍后重试或手动填写产品编码");
+ }
+
+ private static void ApplyProductAppearanceToEntity(FlProductDbEntity entity, ProductCreateInputVo input)
+ {
+ var displayText = input.DisplayText?.Trim();
+ entity.DisplayText = string.IsNullOrWhiteSpace(displayText) ? null : displayText;
+ entity.CodeValue = string.IsNullOrWhiteSpace(input.CodeValue) ? null : input.CodeValue.Trim();
+ entity.ButtonAppearance =
+ CategoryAppearanceStorageHelper.NormalizeButtonAppearanceForStorage(input.ButtonAppearance);
+ entity.CategoryPhotoUrl =
+ CategoryAppearanceStorageHelper.NormalizeCategoryPhotoUrlForStorage(input.CategoryPhotoUrl);
+ }
+
+ private static string FormatCodeValueDisplay(string? codeValue) =>
+ string.IsNullOrWhiteSpace(codeValue) ? "无" : codeValue.Trim();
+
+ private static bool HasProductScopeBinding(ProductCreateInputVo input) =>
+ !string.IsNullOrWhiteSpace(input.PartnerId) ||
+ input.GroupIds is not null ||
+ input.LocationIds is not null;
+
+ ///
+ /// 合并 Company(partnerId)、Region(groupIds)、门店(locationIds)并校验存在性。
+ ///
+ private async Task> ResolveProductLocationIdsForSaveAsync(ProductCreateInputVo input)
+ {
+ var merged = await LocationScopeBindingHelper.MergeToLocationIdsAsync(
+ _dbContext.SqlSugarClient,
+ input.PartnerId,
+ input.GroupIds,
+ input.LocationIds);
+ await LocationScopeBindingHelper.ValidateLocationIdsExistAsync(_dbContext.SqlSugarClient, merged);
+ return merged;
+ }
+
+ ///
+ /// 按产品维度替换 fl_location_product:先删本产品全部关联,再按列表插入(每门店一行)。
+ ///
+ private async Task ReplaceProductLocationLinksAsync(string productId, List locationIds)
+ {
+ await _dbContext.SqlSugarClient.Deleteable()
+ .Where(x => x.ProductId == productId)
+ .ExecuteCommandAsync();
+
+ if (locationIds.Count == 0)
+ {
+ return;
+ }
+
+ var rows = locationIds.Select(lid => new FlLocationProductDbEntity
+ {
+ Id = _guidGenerator.Create().ToString(),
+ LocationId = lid,
+ ProductId = productId
+ }).ToList();
+
+ await _dbContext.SqlSugarClient.Insertable(rows).ExecuteCommandAsync();
+ }
+
+ private static PagedResultWithPageDto BuildPagedResult(int skipCount, int maxResultCount, int total, List items)
+ {
+ var pageSize = maxResultCount <= 0 ? items.Count : maxResultCount;
+ var pageIndex = pageSize <= 0 ? 1 : PagedQueryConvention.PageIndexFromSkipCount(skipCount);
+ var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize);
+ return new PagedResultWithPageDto
+ {
+ PageIndex = pageIndex,
+ PageSize = pageSize,
+ TotalCount = total,
+ TotalPages = totalPages,
+ Items = items
+ };
+ }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs
new file mode 100644
index 0000000..ea0ad84
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs
@@ -0,0 +1,459 @@
+using System.Text.Json;
+using FoodLabeling.Application.Contracts.Constants;
+using FoodLabeling.Application.Helpers;
+using FoodLabeling.Application.Contracts.Dtos.RbacRole;
+using FoodLabeling.Application.Contracts.Dtos.Common;
+using FoodLabeling.Application.Contracts.IServices;
+using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
+using Volo.Abp;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Uow;
+using Yi.Framework.Rbac.Domain.Entities;
+using Yi.Framework.SqlSugarCore.Abstractions;
+
+namespace FoodLabeling.Application.Services;
+
+///
+/// 角色管理(食品标签-美国版对外)
+///
+public class RbacRoleAppService : ApplicationService, IRbacRoleAppService
+{
+ private readonly ISqlSugarDbContext _dbContext;
+ private readonly ISqlSugarRepository _roleRepository;
+ private readonly ISqlSugarRepository _menuRepository;
+ private readonly ISqlSugarRepository _roleMenuRepository;
+ private readonly ISqlSugarRepository _roleDeptRepository;
+ private readonly ISqlSugarRepository _userRoleRepository;
+
+ public RbacRoleAppService(
+ ISqlSugarDbContext dbContext,
+ ISqlSugarRepository roleRepository,
+ ISqlSugarRepository menuRepository,
+ ISqlSugarRepository roleMenuRepository,
+ ISqlSugarRepository roleDeptRepository,
+ ISqlSugarRepository userRoleRepository)
+ {
+ _dbContext = dbContext;
+ _roleRepository = roleRepository;
+ _menuRepository = menuRepository;
+ _roleMenuRepository = roleMenuRepository;
+ _roleDeptRepository = roleDeptRepository;
+ _userRoleRepository = userRoleRepository;
+ }
+
+ ///
+ public async Task> GetListAsync([FromQuery] RbacRoleGetListInputVo input)
+ {
+ RefAsync total = 0;
+
+ var query = _roleRepository._DbQueryable
+ .Where(x => x.IsDeleted == false)
+ .WhereIF(!string.IsNullOrWhiteSpace(input.RoleCode), x => x.RoleCode.Contains(input.RoleCode!.Trim()))
+ .WhereIF(!string.IsNullOrWhiteSpace(input.RoleName), x => x.RoleName.Contains(input.RoleName!.Trim()))
+ .WhereIF(input.State is not null, x => x.State == input.State);
+
+ if (!string.IsNullOrWhiteSpace(input.Sorting))
+ {
+ query = query.OrderBy(input.Sorting);
+ }
+ else
+ {
+ query = query.OrderBy(x => x.OrderNum, OrderByType.Desc);
+ }
+
+ var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
+
+ var items = entities.Select(x => new RbacRoleGetListOutputDto
+ {
+ Id = x.Id,
+ RoleName = x.RoleName ?? string.Empty,
+ RoleCode = x.RoleCode ?? string.Empty,
+ Remark = x.Remark,
+ DataScope = (int)x.DataScope,
+ State = x.State,
+ OrderNum = x.OrderNum,
+ AccessPermissionCodes = DeserializeAccessPermissionCodes(x.AccessPermissionCodesJson)
+ }).ToList();
+
+ await FillAccessPermissionsAsync(items);
+
+ var totalCount = (int)total;
+ var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount;
+ var pageIndex = pageSize <= 0 ? 1 : PagedQueryConvention.PageIndexFromSkipCount(input.SkipCount);
+ var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(totalCount / (double)pageSize);
+
+ return new PagedResultWithPageDto
+ {
+ PageIndex = pageIndex,
+ PageSize = pageSize,
+ TotalCount = totalCount,
+ TotalPages = totalPages,
+ Items = items
+ };
+ }
+
+ ///
+ public async Task GetAsync(Guid id)
+ {
+ var entity = await _roleRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
+ if (entity is null)
+ {
+ throw new UserFriendlyException("角色不存在");
+ }
+
+ var menuIds = await _roleMenuRepository._DbQueryable
+ .Where(x => x.RoleId == id)
+ .Select(x => x.MenuId)
+ .ToListAsync();
+
+ var dto = new RbacRoleGetOutputDto
+ {
+ Id = entity.Id,
+ RoleName = entity.RoleName ?? string.Empty,
+ RoleCode = entity.RoleCode ?? string.Empty,
+ Remark = entity.Remark,
+ DataScope = (int)entity.DataScope,
+ State = entity.State,
+ OrderNum = entity.OrderNum,
+ AccessPermissionCodes = DeserializeAccessPermissionCodes(entity.AccessPermissionCodesJson),
+ MenuIds = menuIds.Select(x => x.ToString()).ToList()
+ };
+ await FillAccessPermissionsAsync(new List { dto });
+ return dto;
+ }
+
+ ///
+ [UnitOfWork]
+ public async Task CreateAsync([FromBody] RbacRoleCreateInputVo input)
+ {
+ var roleName = input.RoleName?.Trim();
+ var roleCode = input.RoleCode?.Trim();
+ if (string.IsNullOrWhiteSpace(roleName))
+ {
+ throw new UserFriendlyException("角色名称不能为空");
+ }
+
+ if (string.IsNullOrWhiteSpace(roleCode))
+ {
+ throw new UserFriendlyException("角色编码不能为空");
+ }
+
+ var isExist = await _roleRepository.IsAnyAsync(x => x.RoleCode == roleCode || x.RoleName == roleName);
+ if (isExist)
+ {
+ throw new UserFriendlyException("角色名称或编码已存在");
+ }
+
+ var entity = new RoleAggregateRoot
+ {
+ RoleName = roleName,
+ RoleCode = roleCode,
+ Remark = input.Remark?.Trim(),
+ DataScope = (Yi.Framework.Rbac.Domain.Shared.Enums.DataScopeEnum)input.DataScope,
+ State = input.State,
+ OrderNum = input.OrderNum ?? 0
+ };
+ EntityHelper.TrySetId(entity, () => GuidGenerator.Create());
+
+ await _roleRepository.InsertAsync(entity);
+
+ await ApplyRoleMenuBindingsAsync(entity.Id, input);
+
+ return await GetAsync(entity.Id);
+ }
+
+ ///
+ [UnitOfWork]
+ public async Task UpdateAsync(Guid id, [FromBody] RbacRoleUpdateInputVo input)
+ {
+ var entity = await _roleRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
+ if (entity is null)
+ {
+ throw new UserFriendlyException("角色不存在");
+ }
+
+ var roleName = input.RoleName?.Trim();
+ var roleCode = input.RoleCode?.Trim();
+ if (string.IsNullOrWhiteSpace(roleName))
+ {
+ throw new UserFriendlyException("角色名称不能为空");
+ }
+
+ if (string.IsNullOrWhiteSpace(roleCode))
+ {
+ throw new UserFriendlyException("角色编码不能为空");
+ }
+
+ var isExist = await _roleRepository._DbQueryable
+ .Where(x => x.Id != entity.Id && x.IsDeleted == false)
+ .AnyAsync(x => x.RoleCode == roleCode || x.RoleName == roleName);
+ if (isExist)
+ {
+ throw new UserFriendlyException("角色名称或编码已存在");
+ }
+
+ entity.RoleName = roleName;
+ entity.RoleCode = roleCode;
+ entity.Remark = input.Remark?.Trim();
+ entity.DataScope = (Yi.Framework.Rbac.Domain.Shared.Enums.DataScopeEnum)input.DataScope;
+ entity.State = input.State;
+ if (input.OrderNum is not null)
+ {
+ entity.OrderNum = input.OrderNum.Value;
+ }
+
+ await _roleRepository.UpdateAsync(entity);
+
+ await ApplyRoleMenuBindingsAsync(entity.Id, input);
+
+ return await GetAsync(entity.Id);
+ }
+
+ ///
+ /// 新增/编辑时按 menuIds 或 accessPermissions 绑定角色菜单(RoleMenu 表)。
+ ///
+ private async Task ApplyRoleMenuBindingsAsync(Guid roleId, RbacRoleCreateInputVo input)
+ {
+ var hasMenuIds = input.MenuIds is not null;
+ var hasAccessPermissions = input.AccessPermissions is not null;
+
+ if (hasMenuIds && input.MenuIds!.Count > 0)
+ {
+ await SetRoleMenusAsync(roleId, input.MenuIds);
+ return;
+ }
+
+ if (hasAccessPermissions)
+ {
+ if (string.IsNullOrWhiteSpace(input.AccessPermissions))
+ {
+ await SetRoleMenusAsync(roleId, new List());
+ return;
+ }
+
+ var menuIds = await ResolveMenuIdsFromAccessPermissionsAsync(input.AccessPermissions);
+ if (menuIds.Count == 0)
+ {
+ throw new UserFriendlyException(
+ "accessPermissions 未匹配到任何菜单,请确认 PermissionCode 与菜单一致,或先执行 menu_backfill_permission_code.sql 回填 Menu.PermissionCode");
+ }
+
+ await SetRoleMenusAsync(roleId, menuIds);
+ return;
+ }
+
+ if (hasMenuIds && input.MenuIds!.Count == 0)
+ {
+ await SetRoleMenusAsync(roleId, new List());
+ }
+ }
+
+ private async Task SetRoleMenusAsync(Guid roleId, List menuIds)
+ {
+ var distinct = menuIds?.Distinct().ToList() ?? new List();
+ await _roleMenuRepository.DeleteAsync(x => x.RoleId == roleId);
+
+ if (distinct.Count == 0)
+ {
+ return;
+ }
+
+ var existMenuIds = await _menuRepository._DbQueryable
+ .Where(x => x.IsDeleted == false)
+ .Where(x => distinct.Contains(x.Id))
+ .Select(x => x.Id)
+ .ToListAsync();
+
+ if (existMenuIds.Count == 0)
+ {
+ return;
+ }
+
+ var entities = existMenuIds.Select(menuId =>
+ {
+ var entity = new RoleMenuEntity
+ {
+ RoleId = roleId,
+ MenuId = menuId
+ };
+ EntityHelper.TrySetId(entity, () => GuidGenerator.Create());
+ return entity;
+ }).ToList();
+
+ await _roleMenuRepository.InsertRangeAsync(entities);
+ }
+
+ private async Task> ResolveMenuIdsFromAccessPermissionsAsync(string accessPermissions)
+ {
+ var codes = RbacAccessPermissionHelper.ParseAccessPermissionCodes(accessPermissions);
+ if (codes.Count == 0)
+ {
+ return new List();
+ }
+
+ var codeSet = new HashSet(codes, StringComparer.OrdinalIgnoreCase);
+
+ var menus = await _menuRepository._DbQueryable
+ .Where(m => m.IsDeleted == false)
+ .Select(m => new { m.Id, m.PermissionCode, m.Router })
+ .ToListAsync();
+
+ return menus
+ .Where(m =>
+ {
+ var effective = RbacAccessPermissionHelper.GetEffectivePermissionCode(m.PermissionCode, m.Router);
+ return effective is not null && codeSet.Contains(effective);
+ })
+ .Select(m => m.Id)
+ .Distinct()
+ .ToList();
+ }
+
+ private async Task FillAccessPermissionsAsync(List items)
+ {
+ if (items.Count == 0)
+ {
+ return;
+ }
+
+ var map = await GetAccessPermissionsByRoleIdsAsync(items.Select(x => x.Id).ToList());
+ foreach (var item in items)
+ {
+ item.AccessPermissions = map.GetValueOrDefault(item.Id, string.Empty);
+ }
+ }
+
+ ///
+ /// Role → RoleMenu → Menu.PermissionCode(空则按 Router 推导)汇总 accessPermissions。
+ ///
+ private async Task> GetAccessPermissionsByRoleIdsAsync(List roleIds)
+ {
+ var result = roleIds.Distinct().ToDictionary(id => id, _ => string.Empty);
+ if (result.Count == 0)
+ {
+ return result;
+ }
+
+ var distinctRoleIds = result.Keys.ToList();
+ var links = await _roleMenuRepository._DbQueryable
+ .Where(rm => distinctRoleIds.Contains(rm.RoleId))
+ .Select(rm => new { rm.RoleId, rm.MenuId })
+ .ToListAsync();
+ if (links.Count == 0)
+ {
+ return result;
+ }
+
+ var menuIds = links.Select(x => x.MenuId).Distinct().ToList();
+ var menus = await _menuRepository._DbQueryable
+ .Where(m => menuIds.Contains(m.Id) && m.IsDeleted == false)
+ .Select(m => new { m.Id, m.PermissionCode, m.Router })
+ .ToListAsync();
+ var permByMenuId = menus.ToDictionary(
+ x => x.Id,
+ x => RbacAccessPermissionHelper.GetEffectivePermissionCode(x.PermissionCode, x.Router));
+
+ var byRole = distinctRoleIds.ToDictionary(id => id, _ => new HashSet(StringComparer.OrdinalIgnoreCase));
+ foreach (var link in links)
+ {
+ if (!permByMenuId.TryGetValue(link.MenuId, out var code) || string.IsNullOrWhiteSpace(code))
+ {
+ continue;
+ }
+
+ if (byRole.TryGetValue(link.RoleId, out var set))
+ {
+ set.Add(code.Trim());
+ }
+ }
+
+ foreach (var kv in byRole)
+ {
+ if (kv.Value.Count == 0)
+ {
+ continue;
+ }
+
+ result[kv.Key] = string.Join(", ", kv.Value.OrderBy(x => x, StringComparer.Ordinal));
+ }
+
+ return result;
+ }
+
+ ///
+ [UnitOfWork]
+ public async Task DeleteAsync([FromBody] List ids)
+ {
+ var idList = ids?.Distinct().ToList() ?? new List();
+ if (idList.Count == 0)
+ {
+ return;
+ }
+
+ await _roleMenuRepository.DeleteAsync(x => idList.Contains(x.RoleId));
+ await _roleDeptRepository.DeleteAsync(x => idList.Contains(x.RoleId));
+ await _userRoleRepository.DeleteAsync(x => idList.Contains(x.RoleId));
+
+ await _roleRepository.DeleteAsync(x => idList.Contains(x.Id));
+ }
+
+ private static List DeserializeAccessPermissionCodes(string? json)
+ {
+ if (string.IsNullOrWhiteSpace(json))
+ {
+ return new List();
+ }
+
+ try
+ {
+ var raw = JsonSerializer.Deserialize>(json);
+ return NormalizeAccessPermissionCodes(raw);
+ }
+ catch
+ {
+ return new List();
+ }
+ }
+
+ private static string? SerializeAccessPermissionCodes(List codes)
+ {
+ if (codes == null || codes.Count == 0)
+ {
+ return null;
+ }
+
+ return JsonSerializer.Serialize(codes);
+ }
+
+ private static List ResolveAccessPermissions(RbacRoleCreateInputVo input)
+ {
+ var merged = new List();
+ if (!string.IsNullOrWhiteSpace(input.AccessPermissions))
+ {
+ merged.AddRange(DeserializeAccessPermissionCodes(input.AccessPermissions));
+ }
+
+ if (input.AccessPermissionCodes is { Count: > 0 })
+ {
+ merged.AddRange(input.AccessPermissionCodes);
+ }
+
+ return NormalizeAccessPermissionCodes(merged.Count > 0 ? merged : null);
+ }
+
+ private static List NormalizeAccessPermissionCodes(List? input)
+ {
+ if (input == null || input.Count == 0)
+ {
+ return new List();
+ }
+
+ return input
+ .Select(x => x?.Trim() ?? "")
+ .Where(x => x.Length > 0 && RoleAccessPermissionCodes.IsKnown(x))
+ .Distinct(StringComparer.Ordinal)
+ .ToList();
+ }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/UsAppLabelingAppService.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/UsAppLabelingAppService.cs
new file mode 100644
index 0000000..bca5437
--- /dev/null
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/UsAppLabelingAppService.cs
@@ -0,0 +1,1294 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text.Json;
+using System.Threading.Tasks;
+using FoodLabeling.Application.Contracts.Dtos.Common;
+using FoodLabeling.Application.Contracts.Dtos.Label;
+using FoodLabeling.Application.Contracts.Dtos.LabelTemplate;
+using FoodLabeling.Application.Contracts.Dtos.Reports;
+using FoodLabeling.Application.Contracts.Dtos.UsAppLabeling;
+using FoodLabeling.Application.Contracts.IServices;
+using FoodLabeling.Application.Helpers;
+using FoodLabeling.Application.Services.DbModels;
+using FoodLabeling.Domain.Entities;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
+using Volo.Abp;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Guids;
+using Volo.Abp.Uow;
+using Yi.Framework.Rbac.Domain.Entities;
+using Yi.Framework.SqlSugarCore.Abstractions;
+
+namespace FoodLabeling.Application.Services;
+
+///
+/// App Labeling:四级列表(标签分类 → 产品分类 → 产品 → 标签种类)
+///
+public class UsAppLabelingAppService : ApplicationService, IUsAppLabelingAppService
+{
+ private readonly ISqlSugarDbContext _dbContext;
+ private readonly ILabelAppService _labelAppService;
+ private readonly IGuidGenerator _guidGenerator;
+ private readonly ISqlSugarRepository _userRepository;
+
+ public UsAppLabelingAppService(
+ ISqlSugarDbContext dbContext,
+ ILabelAppService labelAppService,
+ IGuidGenerator guidGenerator,
+ ISqlSugarRepository userRepository)
+ {
+ _dbContext = dbContext;
+ _labelAppService = labelAppService;
+ _guidGenerator = guidGenerator;
+ _userRepository = userRepository;
+ }
+
+ ///
+ /// 获取当前门店下四级嵌套数据
+ ///
+ ///
+ /// L1 标签分类 fl_label_category(含 buttonAppearance;COLOR/IMAGE 展示值在 categoryPhotoUrl);仅对当前门店可用:ALL 或 SPECIFIED 且在 fl_label_category_location;
+ /// L2 产品分类 fl_product.CategoryId join fl_product_category(同上,展示值在 categoryPhotoUrl);
+ /// L3 产品卡片:按「产品 + 标签模板」拆分;出参含 fl_product 的 codeValue、buttonAppearance、categoryPhotoUrl;L4 为标签种类(fl_label + fl_label_type)。
+ /// L2 产品分类展示名来自 fl_product_category;产品范围已由 fl_location_product 限定当前门店,
+ /// 不再因产品分类 SPECIFIED 未配 fl_product_category_location 而整行过滤(避免 App 全店空数据)。
+ /// 未归类或分类行未关联到 fl_product_category 时仍归入「无」节点。
+ ///
+ [Authorize]
+ public virtual async Task> GetLabelingTreeAsync(UsAppLabelingTreeInputVo input)
+ {
+ if (string.IsNullOrWhiteSpace(input.LocationId))
+ {
+ throw new UserFriendlyException("门店Id不能为空");
+ }
+
+ var locationId = input.LocationId.Trim();
+ var keyword = input.Keyword?.Trim();
+ var filterCategoryId = input.LabelCategoryId?.Trim();
+
+ await UsAppPrintLogScopeHelper.EnsureUserBoundToLocationAsync(
+ CurrentUser, _dbContext.SqlSugarClient, locationId);
+
+ var productIds = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => x.LocationId == locationId)
+ .Select(x => x.ProductId)
+ .ToListAsync();
+
+ if (productIds.Count == 0)
+ {
+ return new List();
+ }
+
+ var query = BuildLabelingJoinQuery(locationId, productIds, filterCategoryId, keyword);
+
+ var raw = await query
+ .Select((lp, l, p, c, t, tpl, pc) => new LabelingTreeRow
+ {
+ LabelCategoryId = c.Id,
+ LabelCategoryName = c.CategoryName,
+ LabelCategoryPhotoUrl = c.CategoryPhotoUrl,
+ LabelCategoryButtonAppearance = c.ButtonAppearance,
+ LabelCategoryOrderNum = c.OrderNum,
+ ProductCategoryId = p.CategoryId,
+ ProductCategoryName = pc.CategoryName,
+ ProductCategoryPhotoUrl = pc.CategoryPhotoUrl,
+ ProductCategoryDisplayText = pc.DisplayText,
+ ProductCategoryButtonAppearance = pc.ButtonAppearance,
+ ProductCategoryAvailabilityType = pc.AvailabilityType,
+ ProductCategoryOrderNum = pc.OrderNum,
+ ProductId = p.Id,
+ ProductName = p.ProductName,
+ ProductCode = p.ProductCode,
+ ProductImageUrl = p.ProductImageUrl,
+ ProductDisplayText = p.DisplayText,
+ ProductCodeValue = p.CodeValue,
+ ProductButtonAppearance = p.ButtonAppearance,
+ ProductAppearancePhotoUrl = p.CategoryPhotoUrl,
+ LabelTypeId = t.Id,
+ TypeName = t.TypeName,
+ TypeOrderNum = t.OrderNum,
+ LabelCode = l.LabelCode ?? string.Empty,
+ TemplateId = tpl.Id,
+ TemplateCode = tpl.TemplateCode,
+ TemplateWidth = tpl.Width,
+ TemplateHeight = tpl.Height,
+ TemplateUnit = tpl.Unit
+ })
+ .ToListAsync();
+
+ if (raw.Count == 0)
+ {
+ return new List();
+ }
+
+ var byL1 = raw.GroupBy(x => new
+ {
+ x.LabelCategoryId,
+ x.LabelCategoryName,
+ x.LabelCategoryPhotoUrl,
+ x.LabelCategoryButtonAppearance,
+ x.LabelCategoryOrderNum
+ }).OrderBy(g => g.Key.LabelCategoryOrderNum).ThenBy(g => g.Key.LabelCategoryName);
+
+ var result = new List();
+ foreach (var g1 in byL1)
+ {
+ var l1Appearance = string.IsNullOrWhiteSpace(g1.Key.LabelCategoryButtonAppearance)
+ ? "TEXT"
+ : g1.Key.LabelCategoryButtonAppearance.Trim();
+ var l1 = new UsAppLabelCategoryTreeNodeDto
+ {
+ Id = g1.Key.LabelCategoryId,
+ CategoryName = g1.Key.LabelCategoryName ?? string.Empty,
+ CategoryPhotoUrl = g1.Key.LabelCategoryPhotoUrl,
+ ButtonAppearance = l1Appearance,
+ OrderNum = g1.Key.LabelCategoryOrderNum,
+ ProductCategories = new List()
+ };
+
+ var byL2 = g1.GroupBy(x =>
+ {
+ var categoryId = NormalizeNullableId(x.ProductCategoryId);
+ if (categoryId is null)
+ {
+ return new
+ {
+ CategoryId = (string?)null,
+ CategoryName = "无",
+ CategoryPhotoUrl = (string?)null,
+ DisplayText = (string?)null,
+ ButtonAppearance = (string?)null,
+ AvailabilityType = (string?)null,
+ CategoryOrderNum = int.MaxValue
+ };
+ }
+
+ var categoryName = NormalizeCategoryName(x.ProductCategoryName);
+ var categoryPhotoUrl = NormalizeNullableUrl(x.ProductCategoryPhotoUrl);
+ return new
+ {
+ CategoryId = (string?)categoryId,
+ CategoryName = categoryName,
+ CategoryPhotoUrl = categoryPhotoUrl,
+ DisplayText = NormalizeNullableUrl(x.ProductCategoryDisplayText),
+ ButtonAppearance = NormalizeNullableId(x.ProductCategoryButtonAppearance),
+ AvailabilityType = NormalizeNullableId(x.ProductCategoryAvailabilityType),
+ CategoryOrderNum = x.ProductCategoryOrderNum
+ };
+ })
+ .OrderBy(g => g.Key.CategoryOrderNum)
+ .ThenBy(g => g.Key.CategoryName);
+
+ foreach (var g2 in byL2)
+ {
+ var productsGrouped = g2
+ .GroupBy(x => new { x.ProductId, x.TemplateId })
+ .OrderBy(pg => pg.First().ProductName)
+ .ThenBy(pg => pg.Key.TemplateId);
+ var appearance = string.IsNullOrWhiteSpace(g2.Key.ButtonAppearance)
+ ? "TEXT"
+ : g2.Key.ButtonAppearance.Trim();
+ var availability = string.IsNullOrWhiteSpace(g2.Key.AvailabilityType)
+ ? "ALL"
+ : g2.Key.AvailabilityType.Trim().ToUpperInvariant();
+ var l2 = new UsAppProductCategoryNodeDto
+ {
+ CategoryId = g2.Key.CategoryId,
+ CategoryPhotoUrl = g2.Key.CategoryPhotoUrl,
+ Name = g2.Key.CategoryName,
+ DisplayText = g2.Key.DisplayText,
+ ButtonAppearance = appearance,
+ AvailabilityType = availability,
+ OrderNum = g2.Key.CategoryOrderNum == int.MaxValue ? 0 : g2.Key.CategoryOrderNum,
+ ItemCount = productsGrouped.Count(),
+ Products = new List()
+ };
+
+ foreach (var g3 in productsGrouped)
+ {
+ var first = g3.First();
+ var typeNodes = g3
+ .GroupBy(r => r.LabelCode)
+ .Select(gr => BuildLabelTypeNode(gr.First()))
+ .OrderBy(t => t.OrderNum)
+ .ThenBy(t => t.TypeName)
+ .ToList();
+
+ var subtitle = string.IsNullOrWhiteSpace(first.ProductCode?.Trim())
+ ? "无"
+ : first.ProductCode!.Trim();
+ var templateLabelSizeText = FormatLabelSize(
+ first.TemplateWidth,
+ first.TemplateHeight,
+ first.TemplateUnit);
+
+ var productAppearance = string.IsNullOrWhiteSpace(first.ProductButtonAppearance)
+ ? CategoryAppearanceStorageHelper.DefaultButtonAppearanceJson
+ : first.ProductButtonAppearance.Trim();
+
+ l2.Products.Add(new UsAppLabelingProductNodeDto
+ {
+ ProductId = first.ProductId,
+ TemplateId = first.TemplateId,
+ TemplateCode = first.TemplateCode,
+ TemplateLabelSizeText = templateLabelSizeText,
+ ProductName = first.ProductName ?? string.Empty,
+ ProductCode = first.ProductCode ?? string.Empty,
+ ProductImageUrl = first.ProductImageUrl,
+ DisplayText = first.ProductDisplayText,
+ CodeValue = FormatProductCodeValueDisplay(first.ProductCodeValue),
+ ButtonAppearance = productAppearance,
+ CategoryPhotoUrl = first.ProductAppearancePhotoUrl,
+ Subtitle = subtitle,
+ LabelTypeCount = typeNodes.Count,
+ LabelTypes = typeNodes
+ });
+ }
+
+ l1.ProductCategories.Add(l2);
+ }
+
+ result.Add(l1);
+ }
+
+ return result;
+ }
+
+ ///
+ /// App 打印预览:按标签编码解析模板并返回顶部展示字段 + 预览模板结构
+ ///
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "locationId": "LOC001",
+ /// "labelCode": "LBL0001",
+ /// "productId": "PROD001",
+ /// "baseTime": "2026-03-26T10:30:00",
+ /// "printInputJson": {
+ /// "price": "12.99"
+ /// }
+ /// }
+ /// ```
+ ///
+ /// 预览入参
+ /// 顶部字段 + 预览模板结构
+ /// 成功
+ /// 参数错误/数据不存在
+ /// 服务器错误
+ [Authorize]
+ public virtual async Task PreviewAsync(UsAppLabelPreviewInputVo input)
+ {
+ if (input is null)
+ {
+ throw new UserFriendlyException("入参不能为空");
+ }
+
+ var locationId = input.LocationId?.Trim();
+ if (string.IsNullOrWhiteSpace(locationId))
+ {
+ throw new UserFriendlyException("门店Id不能为空");
+ }
+
+ var labelCode = input.LabelCode?.Trim();
+ if (string.IsNullOrWhiteSpace(labelCode))
+ {
+ throw new UserFriendlyException("labelCode不能为空");
+ }
+
+ var labelRow = await _dbContext.SqlSugarClient
+ .Queryable(
+ (l, c, t, tpl) => l.LabelCategoryId == c.Id && l.LabelTypeId == t.Id && l.TemplateId == tpl.Id)
+ .Where((l, c, t, tpl) => !l.IsDeleted && l.State)
+ .Where((l, c, t, tpl) => !c.IsDeleted && c.State)
+ .Where((l, c, t, tpl) => !t.IsDeleted && t.State)
+ .Where((l, c, t, tpl) => !tpl.IsDeleted)
+ .Where((l, c, t, tpl) => l.LabelCode == labelCode)
+ .Select((l, c, t, tpl) => new
+ {
+ l.Id,
+ l.LabelCode,
+ l.LocationId,
+ l.LabelTypeId,
+ l.TemplateId,
+ l.LastModificationTime,
+ l.CreationTime,
+ LabelCategoryName = c.CategoryName,
+ TypeName = t.TypeName,
+ TemplateCode = tpl.TemplateCode,
+ TemplateWidth = tpl.Width,
+ TemplateHeight = tpl.Height,
+ TemplateUnit = tpl.Unit
+ })
+ .FirstAsync();
+
+ if (labelRow is null)
+ {
+ throw new UserFriendlyException("标签不存在或不可用");
+ }
+
+ if (!string.Equals(labelRow.LocationId?.Trim(), locationId, StringComparison.OrdinalIgnoreCase))
+ {
+ throw new UserFriendlyException("该标签不属于当前门店");
+ }
+
+ var previewProductId = await ResolvePreviewProductIdAsync(labelRow.Id, input.ProductId);
+
+ var template = await _labelAppService.PreviewAsync(new LabelPreviewResolveInputVo
+ {
+ LabelCode = labelCode,
+ ProductId = previewProductId,
+ BaseTime = input.BaseTime,
+ PrintInputJson = input.PrintInputJson?.ToDictionary(x => x.Key, x => (object?)x.Value)
+ });
+
+ Dictionary? templateProductDefaultValues = null;
+ if (!string.IsNullOrWhiteSpace(previewProductId))
+ {
+ var productDefault = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => x.TemplateId == labelRow.TemplateId)
+ .Where(x => x.ProductId == previewProductId)
+ .Where(x => x.LabelTypeId == labelRow.LabelTypeId)
+ .OrderBy(x => x.OrderNum)
+ .FirstAsync();
+
+ if (!string.IsNullOrWhiteSpace(productDefault?.DefaultValuesJson))
+ {
+ try
+ {
+ templateProductDefaultValues =
+ JsonSerializer.Deserialize>(productDefault.DefaultValuesJson!);
+ }
+ catch
+ {
+ templateProductDefaultValues = null;
+ }
+ }
+ }
+
+ var productName = string.Empty;
+ var productCategoryName = "无";
+ if (!string.IsNullOrWhiteSpace(previewProductId))
+ {
+ var p = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.State && x.Id == previewProductId);
+ if (p is not null)
+ {
+ productName = p.ProductName ?? string.Empty;
+ if (!string.IsNullOrWhiteSpace(p.CategoryId))
+ {
+ var pc = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => !x.IsDeleted && x.State && x.Id == p.CategoryId);
+ productCategoryName = NormalizeCategoryName(pc?.CategoryName);
+ }
+ }
+ }
+
+ return new UsAppLabelPreviewDto
+ {
+ LabelId = labelRow.Id,
+ LocationId = locationId,
+ LabelCode = labelCode,
+ TemplateCode = labelRow.TemplateCode,
+ LabelSizeText = FormatLabelSize(labelRow.TemplateWidth, labelRow.TemplateHeight, labelRow.TemplateUnit),
+ TypeName = labelRow.TypeName,
+ ProductName = string.IsNullOrWhiteSpace(productName) ? null : productName,
+ ProductCategoryName = productCategoryName,
+ LabelCategoryName = labelRow.LabelCategoryName,
+ LabelLastEdited = labelRow.LastModificationTime ?? labelRow.CreationTime,
+ PreviewImageBase64Png = null,
+ Template = template,
+ TemplateProductDefaultValues = templateProductDefaultValues
+ };
+ }
+
+ ///
+ /// App 打印:创建打印任务并落库打印明细(fl_label_print_task / fl_label_print_data)
+ ///
+ /// 打印入参
+ /// 任务Id
+ [Authorize]
+ [UnitOfWork]
+ public virtual async Task PrintAsync(UsAppLabelPrintInputVo input)
+ {
+ if (input is null)
+ {
+ throw new UserFriendlyException("入参不能为空");
+ }
+
+ var locationId = input.LocationId?.Trim();
+ if (string.IsNullOrWhiteSpace(locationId))
+ {
+ throw new UserFriendlyException("门店Id不能为空");
+ }
+
+ var labelCode = input.LabelCode?.Trim();
+ if (string.IsNullOrWhiteSpace(labelCode))
+ {
+ throw new UserFriendlyException("labelCode不能为空");
+ }
+
+ var quantity = input.PrintQuantity <= 0 ? 1 : input.PrintQuantity;
+ var clientRequestId = input.ClientRequestId?.Trim();
+ if (!string.IsNullOrWhiteSpace(clientRequestId))
+ {
+ // 幂等:同一个 clientRequestId 重复调用,直接返回首次创建的任务集合
+ var existed = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => x.ClientRequestId == clientRequestId)
+ .OrderBy(x => x.CopyIndex)
+ .ToListAsync();
+
+ if (existed is not null && existed.Count > 0)
+ {
+ var existedBatchId = existed.First().BatchId;
+ var existedTaskIds = existed.Select(x => x.Id).ToList();
+ return new UsAppLabelPrintOutputDto
+ {
+ TaskId = existedTaskIds.FirstOrDefault() ?? string.Empty,
+ PrintQuantity = existedTaskIds.Count,
+ BatchId = existedBatchId,
+ TaskIds = existedTaskIds
+ };
+ }
+ }
+
+ // 校验 label + location,并补齐一些顶部字段用于任务表落库
+ var labelRow = await _dbContext.SqlSugarClient
+ .Queryable(
+ (l, t, tpl) => l.LabelTypeId == t.Id && l.TemplateId == tpl.Id)
+ .Where((l, t, tpl) => !l.IsDeleted && l.State)
+ .Where((l, t, tpl) => !t.IsDeleted && t.State)
+ .Where((l, t, tpl) => !tpl.IsDeleted)
+ .Where((l, t, tpl) => l.LabelCode == labelCode)
+ .Select((l, t, tpl) => new
+ {
+ l.Id,
+ l.LocationId,
+ l.LabelTypeId,
+ l.TemplateId
+ })
+ .FirstAsync();
+
+ if (labelRow is null)
+ {
+ throw new UserFriendlyException("标签不存在或不可用");
+ }
+
+ if (!string.Equals(labelRow.LocationId?.Trim(), locationId, StringComparison.OrdinalIgnoreCase))
+ {
+ throw new UserFriendlyException("该标签不属于当前门店");
+ }
+
+ var previewProductId = await ResolvePreviewProductIdAsync(labelRow.Id, input.ProductId);
+ var normalizedPrintInput = ParsePrintInputJsonToDictionary(input.PrintInputJson);
+
+ // 解析模板 elements(与预览一致的渲染数据)
+ var resolvedTemplate = await _labelAppService.PreviewAsync(new LabelPreviewResolveInputVo
+ {
+ LabelCode = labelCode,
+ ProductId = previewProductId,
+ BaseTime = input.BaseTime,
+ PrintInputJson = normalizedPrintInput
+ });
+
+ var templateProductDefaultValuesJson = await ResolveTemplateProductDefaultValuesJsonAsync(
+ labelRow.TemplateId,
+ previewProductId,
+ labelRow.LabelTypeId);
+
+ var printInputJsonStr = input.PrintInputJson is null
+ ? null
+ : JsonSerializer.Serialize(input.PrintInputJson);
+ var renderTemplateJsonStr = JsonSerializer.Serialize(resolvedTemplate);
+
+ var now = DateTime.Now;
+ var currentUserId = CurrentUser?.Id?.ToString();
+ var batchId = _guidGenerator.Create().ToString();
+ var taskIds = new List();
+
+ for (var i = 1; i <= quantity; i++)
+ {
+ var taskId = _guidGenerator.Create().ToString();
+ taskIds.Add(taskId);
+
+ var task = new FlLabelPrintTaskDbEntity
+ {
+ Id = taskId,
+ BatchId = batchId,
+ CopyIndex = i,
+ ClientRequestId = string.IsNullOrWhiteSpace(clientRequestId) ? null : clientRequestId,
+ LabelId = labelRow.Id,
+ TemplateId = labelRow.TemplateId,
+ LabelTypeId = labelRow.LabelTypeId,
+ ProductId = previewProductId,
+ LocationId = locationId,
+ BaseTime = input.BaseTime,
+ PrintInputJson = printInputJsonStr,
+ TemplateProductDefaultValuesJson = templateProductDefaultValuesJson,
+ RenderTemplateJson = renderTemplateJsonStr,
+ PrinterId = input.PrinterId?.Trim(),
+ PrinterMac = input.PrinterMac?.Trim(),
+ PrinterAddress = input.PrinterAddress?.Trim(),
+ Status = "CREATED",
+ PrintedAt = null,
+ ErrorMessage = null,
+ CreatedBy = currentUserId,
+ CreationTime = now
+ };
+
+ await _dbContext.SqlSugarClient.Insertable(task).ExecuteCommandAsync();
+
+ var rows = resolvedTemplate.Elements.Select(e =>
+ {
+ var cfgJson = e.ConfigJson is null ? null : JsonSerializer.Serialize(e.ConfigJson);
+ string? renderValue = null;
+ if (e.ConfigJson is JsonElement je && je.ValueKind == JsonValueKind.Object && je.TryGetProperty("text", out var tv))
+ {
+ renderValue = tv.ValueKind == JsonValueKind.String ? tv.GetString() : tv.ToString();
+ }
+ else if (e.ConfigJson is Dictionary dict && dict.TryGetValue("text", out var v))
+ {
+ renderValue = v?.ToString();
+ }
+
+ return new FlLabelPrintDataDbEntity
+ {
+ Id = _guidGenerator.Create().ToString(),
+ PrintTaskId = taskId,
+ ElementId = e.Id?.Trim() ?? string.Empty,
+ ElementName = e.ElementName?.Trim(),
+ RenderValue = renderValue,
+ RenderConfigJson = cfgJson
+ };
+ }).Where(x => !string.IsNullOrWhiteSpace(x.ElementId)).ToList();
+
+ if (rows.Count > 0)
+ {
+ await _dbContext.SqlSugarClient.Insertable(rows).ExecuteCommandAsync();
+ }
+ }
+
+ return new UsAppLabelPrintOutputDto
+ {
+ TaskId = taskIds.FirstOrDefault() ?? string.Empty,
+ PrintQuantity = quantity,
+ BatchId = batchId,
+ TaskIds = taskIds
+ };
+ }
+
+ ///
+ /// App 重新打印:根据历史任务Id重打(创建新任务与明细)
+ ///
+ [Authorize]
+ [UnitOfWork]
+ public virtual async Task ReprintAsync(UsAppLabelReprintInputVo input)
+ {
+ if (input is null)
+ {
+ throw new UserFriendlyException("入参不能为空");
+ }
+
+ var locationId = input.LocationId?.Trim();
+ if (string.IsNullOrWhiteSpace(locationId))
+ {
+ throw new UserFriendlyException("门店Id不能为空");
+ }
+
+ var taskId = input.TaskId?.Trim();
+ if (string.IsNullOrWhiteSpace(taskId))
+ {
+ throw new UserFriendlyException("taskId不能为空");
+ }
+
+ var quantity = input.PrintQuantity <= 0 ? 1 : input.PrintQuantity;
+ var clientRequestId = input.ClientRequestId?.Trim();
+ if (!string.IsNullOrWhiteSpace(clientRequestId))
+ {
+ var existed = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => x.ClientRequestId == clientRequestId)
+ .OrderBy(x => x.CopyIndex)
+ .ToListAsync();
+
+ if (existed is not null && existed.Count > 0)
+ {
+ var existedBatchId = existed.First().BatchId;
+ var existedTaskIds = existed.Select(x => x.Id).ToList();
+ return new UsAppLabelPrintOutputDto
+ {
+ TaskId = existedTaskIds.FirstOrDefault() ?? string.Empty,
+ PrintQuantity = existedTaskIds.Count,
+ BatchId = existedBatchId,
+ TaskIds = existedTaskIds
+ };
+ }
+ }
+
+ var currentUserId = CurrentUser?.Id?.ToString();
+ if (string.IsNullOrWhiteSpace(currentUserId))
+ {
+ throw new UserFriendlyException("未登录");
+ }
+
+ var old = await _dbContext.SqlSugarClient.Queryable()
+ .FirstAsync(x => x.Id == taskId);
+ if (old is null)
+ {
+ throw new UserFriendlyException("打印任务不存在");
+ }
+
+ // 管理员 / Partner 角色:可重打当前门店任意用户任务;其它角色仅本人
+ var canViewAll = await UsAppPrintLogScopeHelper.CanViewAllPrintsAtLocationAsync(
+ CurrentUser, _dbContext.SqlSugarClient);
+ if (!canViewAll && !string.Equals(old.CreatedBy?.Trim(), currentUserId, StringComparison.OrdinalIgnoreCase))
+ {
+ throw new UserFriendlyException("无权限重打该任务");
+ }
+ if (!string.Equals(old.LocationId?.Trim(), locationId, StringComparison.OrdinalIgnoreCase))
+ {
+ throw new UserFriendlyException("该任务不属于当前门店");
+ }
+
+ LabelTemplatePreviewDto? resolvedTemplate = null;
+ try
+ {
+ resolvedTemplate = JsonSerializer.Deserialize(old.RenderTemplateJson);
+ }
+ catch
+ {
+ resolvedTemplate = null;
+ }
+
+ if (resolvedTemplate is null)
+ {
+ throw new UserFriendlyException("历史任务渲染快照解析失败,无法重打");
+ }
+
+ var now = DateTime.Now;
+ var batchId = _guidGenerator.Create().ToString();
+ var taskIds = new List();
+
+ for (var i = 1; i <= quantity; i++)
+ {
+ var newTaskId = _guidGenerator.Create().ToString();
+ taskIds.Add(newTaskId);
+
+ var newTask = new FlLabelPrintTaskDbEntity
+ {
+ Id = newTaskId,
+ BatchId = batchId,
+ CopyIndex = i,
+ ClientRequestId = string.IsNullOrWhiteSpace(clientRequestId) ? null : clientRequestId,
+ LabelId = old.LabelId,
+ TemplateId = old.TemplateId,
+ LabelTypeId = old.LabelTypeId,
+ ProductId = old.ProductId,
+ LocationId = old.LocationId,
+ BaseTime = old.BaseTime,
+ PrintInputJson = old.PrintInputJson,
+ TemplateProductDefaultValuesJson = old.TemplateProductDefaultValuesJson,
+ RenderTemplateJson = old.RenderTemplateJson,
+ PrinterId = string.IsNullOrWhiteSpace(input.PrinterId) ? old.PrinterId : input.PrinterId.Trim(),
+ PrinterMac = string.IsNullOrWhiteSpace(input.PrinterMac) ? old.PrinterMac : input.PrinterMac.Trim(),
+ PrinterAddress = string.IsNullOrWhiteSpace(input.PrinterAddress) ? old.PrinterAddress : input.PrinterAddress.Trim(),
+ Status = "CREATED",
+ PrintedAt = null,
+ ErrorMessage = null,
+ CreatedBy = currentUserId,
+ CreationTime = now
+ };
+
+ await _dbContext.SqlSugarClient.Insertable(newTask).ExecuteCommandAsync();
+
+ var rows = resolvedTemplate.Elements.Select(e =>
+ {
+ var cfgJson = e.ConfigJson is null ? null : JsonSerializer.Serialize(e.ConfigJson);
+ string? renderValue = null;
+ if (e.ConfigJson is JsonElement je && je.ValueKind == JsonValueKind.Object && je.TryGetProperty("text", out var tv))
+ {
+ renderValue = tv.ValueKind == JsonValueKind.String ? tv.GetString() : tv.ToString();
+ }
+ else if (e.ConfigJson is Dictionary dict && dict.TryGetValue("text", out var v))
+ {
+ renderValue = v?.ToString();
+ }
+
+ return new FlLabelPrintDataDbEntity
+ {
+ Id = _guidGenerator.Create().ToString(),
+ PrintTaskId = newTaskId,
+ ElementId = e.Id?.Trim() ?? string.Empty,
+ ElementName = e.ElementName?.Trim(),
+ RenderValue = renderValue,
+ RenderConfigJson = cfgJson
+ };
+ }).Where(x => !string.IsNullOrWhiteSpace(x.ElementId)).ToList();
+
+ if (rows.Count > 0)
+ {
+ await _dbContext.SqlSugarClient.Insertable(rows).ExecuteCommandAsync();
+ }
+ }
+
+ return new UsAppLabelPrintOutputDto
+ {
+ TaskId = taskIds.FirstOrDefault() ?? string.Empty,
+ PrintQuantity = quantity,
+ BatchId = batchId,
+ TaskIds = taskIds
+ };
+ }
+
+ ///
+ /// App 打印日志:当前门店打印记录(分页,时间倒序)
+ ///
+ ///
+ /// 数据范围(须已绑定 input.locationId):
+ ///
+ /// - 管理员()或角色码/名含 partner:该门店 全部 打印任务;
+ /// - 其它角色:仅 CreatedBy == CurrentUser.Id。
+ ///
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "locationId": "11111111-1111-1111-1111-111111111111",
+ /// "skipCount": 1,
+ /// "maxResultCount": 20
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - locationId: 当前门店 Id(必填)
+ /// - skipCount: 页码(从 1 开始,遵循本项目约定)
+ /// - maxResultCount: 每页条数
+ ///
+ /// 分页查询入参
+ /// 分页打印日志
+ /// 成功
+ /// 参数错误/未登录
+ /// 服务器错误
+ [Authorize]
+ [HttpPost]
+ public virtual async Task> GetPrintLogListAsync(PrintLogGetListInputVo input)
+ {
+ if (input is null)
+ {
+ throw new UserFriendlyException("入参不能为空");
+ }
+
+ if (!CurrentUser.Id.HasValue)
+ {
+ throw new UserFriendlyException("用户未登录");
+ }
+
+ var locationId = input.LocationId?.Trim();
+ if (string.IsNullOrWhiteSpace(locationId))
+ {
+ throw new UserFriendlyException("门店Id不能为空");
+ }
+
+ var currentUserIdStr = CurrentUser.Id.Value.ToString();
+ await UsAppPrintLogScopeHelper.EnsureUserBoundToLocationAsync(
+ CurrentUser, _dbContext.SqlSugarClient, locationId);
+
+ var canViewAll = await UsAppPrintLogScopeHelper.CanViewAllPrintsAtLocationAsync(
+ CurrentUser, _dbContext.SqlSugarClient);
+ var restrictToCreator = !canViewAll;
+
+ var locationName = "无";
+ if (Guid.TryParse(locationId, out var locationGuid))
+ {
+ var loc = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => !x.IsDeleted && x.Id == locationGuid)
+ .Select(x => new { x.LocationCode, x.LocationName })
+ .FirstAsync();
+ if (loc is not null)
+ {
+ var name = loc.LocationName?.Trim();
+ if (!string.IsNullOrWhiteSpace(name))
+ {
+ locationName = name;
+ }
+ }
+ }
+
+ RefAsync total = 0;
+
+ var query = UsAppPrintLogScopeHelper.BuildLocationPrintTaskQuery(
+ _dbContext.SqlSugarClient, locationId, restrictToCreator, currentUserIdStr)
+ .OrderBy((t, l, p, lt, tpl) => SqlFunc.IsNull(t.PrintedAt, t.CreationTime), OrderByType.Desc)
+ .OrderBy((t, l, p, lt, tpl) => t.CreationTime, OrderByType.Desc)
+ .Select((t, l, p, lt, tpl) => new
+ {
+ t.Id,
+ t.BatchId,
+ t.CopyIndex,
+ t.LabelId,
+ LabelCode = l.LabelCode,
+ t.ProductId,
+ ProductName = p.ProductName,
+ TypeName = lt.TypeName,
+ TemplateWidth = tpl.Width,
+ TemplateHeight = tpl.Height,
+ TemplateUnit = tpl.Unit,
+ t.PrintInputJson,
+ t.PrintedAt,
+ t.CreationTime,
+ t.CreatedBy
+ });
+
+ var pageRows = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
+
+ var operatorMap = await UsAppPrintLogScopeHelper.LoadOperatorNameMapAsync(
+ _dbContext.SqlSugarClient,
+ pageRows.Select(x => x.CreatedBy));
+
+ var items = pageRows.Select(x => new PrintLogItemDto
+ {
+ TaskId = x.Id,
+ BatchId = x.BatchId,
+ CopyIndex = x.CopyIndex,
+ LabelId = x.LabelId,
+ LabelCode = x.LabelCode ?? string.Empty,
+ ProductId = x.ProductId,
+ ProductName = string.IsNullOrWhiteSpace(x.ProductName) ? "无" : x.ProductName.Trim(),
+ TypeName = x.TypeName ?? string.Empty,
+ LabelSizeText = FormatLabelSizeWithUnit(x.TemplateWidth, x.TemplateHeight, x.TemplateUnit),
+ PrintInputJson = x.PrintInputJson,
+ PrintedAt = x.PrintedAt ?? x.CreationTime,
+ OperatorName = UsAppPrintLogScopeHelper.ResolveOperatorName(operatorMap, x.CreatedBy),
+ LocationName = locationName
+ }).ToList();
+
+ var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount;
+ var pageIndex = pageSize <= 0 ? 1 : PagedQueryConvention.PageIndexFromSkipCount(input.SkipCount);
+ var totalCount = (long)total;
+ var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(totalCount / (double)pageSize);
+
+ return new PagedResultWithPageDto
+ {
+ PageIndex = pageIndex,
+ PageSize = pageSize,
+ TotalCount = totalCount,
+ TotalPages = totalPages,
+ Items = items
+ };
+ }
+
+ ///
+ /// App Label Report:当前门店打印统计(权限与 一致)
+ ///
+ ///
+ /// 示例:POST /api/app/us-app-labeling/get-label-report
+ /// ```json
+ /// { "locationId": "3a21220f-db37-3e32-7390-d55f64cd62a8", "startDate": "2026-04-07", "endDate": "2026-05-18" }
+ /// ```
+ ///
+ [Authorize]
+ [HttpPost]
+ public virtual async Task GetLabelReportAsync(UsAppLabelReportQueryInputVo input)
+ {
+ if (input is null)
+ {
+ throw new UserFriendlyException("入参不能为空");
+ }
+
+ if (!CurrentUser.Id.HasValue)
+ {
+ throw new UserFriendlyException("用户未登录");
+ }
+
+ var locationId = input.LocationId?.Trim();
+ if (string.IsNullOrWhiteSpace(locationId))
+ {
+ throw new UserFriendlyException("门店Id不能为空");
+ }
+
+ await UsAppPrintLogScopeHelper.EnsureUserBoundToLocationAsync(
+ CurrentUser, _dbContext.SqlSugarClient, locationId);
+
+ var canViewAll = await UsAppPrintLogScopeHelper.CanViewAllPrintsAtLocationAsync(
+ CurrentUser, _dbContext.SqlSugarClient);
+ var restrictToCreator = !canViewAll;
+ var currentUserIdStr = CurrentUser.Id.Value.ToString();
+ var keyword = input.Keyword?.Trim();
+
+ var (curStart, curEndExcl) = ResolveAppDateRange(input.StartDate, input.EndDate);
+ var span = curEndExcl - curStart;
+ if (span.TotalDays < 1)
+ {
+ span = TimeSpan.FromDays(1);
+ }
+
+ var prevEndExcl = curStart;
+ var prevStart = curStart - span;
+ var db = _dbContext.SqlSugarClient;
+
+ ISugarQueryable Core() =>
+ UsAppPrintLogScopeHelper.BuildLocationPrintTaskReportQuery(
+ db, locationId, restrictToCreator, currentUserIdStr, keyword);
+
+ var totalCur = await Core()
+ .Where((t, l, p, lc, pc, lt, tpl) =>
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) >= curStart &&
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) < curEndExcl)
+ .CountAsync();
+
+ var totalPrev = await Core()
+ .Where((t, l, p, lc, pc, lt, tpl) =>
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) >= prevStart &&
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) < prevEndExcl)
+ .CountAsync();
+
+ var dayCount = Math.Max(1, (int)Math.Ceiling((curEndExcl - curStart).TotalDays));
+ var prevDayCount = Math.Max(1, (int)Math.Ceiling((prevEndExcl - prevStart).TotalDays));
+ var avgDaily = Math.Round((decimal)totalCur / dayCount, 2);
+ var avgDailyPrev = Math.Round((decimal)totalPrev / prevDayCount, 2);
+
+ var categoryRows = await Core()
+ .Where((t, l, p, lc, pc, lt, tpl) =>
+ l.LabelCategoryId != null &&
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) >= curStart &&
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) < curEndExcl)
+ .GroupBy((t, l, p, lc, pc, lt, tpl) => new { lc.Id, lc.CategoryName })
+ .Select((t, l, p, lc, pc, lt, tpl) => new { lc.Id, lc.CategoryName, Cnt = SqlFunc.AggregateCount(t.Id) })
+ .ToListAsync();
+
+ var topCat = categoryRows.OrderByDescending(x => x.Cnt).FirstOrDefault();
+
+ var productRows = await Core()
+ .Where((t, l, p, lc, pc, lt, tpl) =>
+ !string.IsNullOrEmpty(p.Id) &&
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) >= curStart &&
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) < curEndExcl)
+ .GroupBy((t, l, p, lc, pc, lt, tpl) => new { p.Id, p.ProductName, Cat = pc.CategoryName })
+ .Select((t, l, p, lc, pc, lt, tpl) => new
+ {
+ p.Id,
+ p.ProductName,
+ CategoryName = pc.CategoryName,
+ Cnt = SqlFunc.AggregateCount(t.Id)
+ })
+ .ToListAsync();
+
+ var topProd = productRows.OrderByDescending(x => x.Cnt).FirstOrDefault();
+ var topList = productRows.OrderByDescending(x => x.Cnt).Take(20).ToList();
+
+ var trendEndDay = curEndExcl.Date.AddDays(-1);
+ var trendStartDay = trendEndDay.AddDays(-6);
+ if (trendStartDay < curStart.Date)
+ {
+ trendStartDay = curStart.Date;
+ }
+
+ var trendEndExcl = trendEndDay.AddDays(1);
+
+ var trendRaw = await Core()
+ .Where((t, l, p, lc, pc, lt, tpl) =>
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) >= trendStartDay &&
+ SqlFunc.IsNull(t.PrintedAt, t.CreationTime) < trendEndExcl)
+ .Select((t, l, p, lc, pc, lt, tpl) => SqlFunc.IsNull(t.PrintedAt, t.CreationTime))
+ .ToListAsync();
+
+ var trendDict = trendRaw
+ .Where(x => x.HasValue)
+ .GroupBy(x => x!.Value.Date)
+ .ToDictionary(g => g.Key, g => g.Count());
+
+ var trend = new List();
+ for (var d = trendStartDay; d <= trendEndDay; d = d.AddDays(1))
+ {
+ trend.Add(new ReportsDailyCountDto
+ {
+ Date = d.ToString("yyyy-MM-dd"),
+ Count = trendDict.TryGetValue(d, out var c) ? c : 0
+ });
+ }
+
+ var byCategory = categoryRows
+ .OrderByDescending(x => x.Cnt)
+ .Select(x => new ReportsCategoryCountDto
+ {
+ CategoryId = string.IsNullOrWhiteSpace(x.Id) ? null : x.Id.Trim(),
+ CategoryName = string.IsNullOrWhiteSpace(x.CategoryName) ? null : x.CategoryName.Trim(),
+ Count = x.Cnt
+ })
+ .ToList();
+
+ var mostUsed = topList.Select(x =>
+ {
+ var pct = totalCur <= 0 ? 0m : Math.Round(x.Cnt * 100m / totalCur, 2);
+ return new ReportsTopProductRowDto
+ {
+ ProductId = string.IsNullOrWhiteSpace(x.Id) ? null : x.Id.Trim(),
+ ProductName = string.IsNullOrWhiteSpace(x.ProductName) ? null : x.ProductName.Trim(),
+ CategoryName = string.IsNullOrWhiteSpace(x.CategoryName) ? null : x.CategoryName!.Trim(),
+ TotalPrinted = x.Cnt,
+ UsagePercent = pct
+ };
+ }).ToList();
+
+ return new ReportsLabelReportOutputDto
+ {
+ Summary = new ReportsLabelReportSummaryDto
+ {
+ TotalLabelsPrinted = totalCur,
+ TotalLabelsPrintedPrevPeriod = totalPrev,
+ TotalLabelsPrintedChangeRate = CalcAppChangeRate(totalCur, totalPrev),
+ MostPrintedCategoryName = string.IsNullOrWhiteSpace(topCat?.CategoryName) ? null : topCat.CategoryName.Trim(),
+ MostPrintedCategoryCount = topCat?.Cnt ?? 0,
+ TopProductName = string.IsNullOrWhiteSpace(topProd?.ProductName) ? null : topProd.ProductName.Trim(),
+ TopProductCount = topProd?.Cnt ?? 0,
+ AvgDailyPrints = avgDaily,
+ AvgDailyPrintsPrevPeriod = avgDailyPrev,
+ AvgDailyPrintsChangeRate = CalcAppChangeRate(avgDaily, avgDailyPrev)
+ },
+ LabelsByCategory = byCategory,
+ PrintVolumeTrend = trend,
+ MostUsedProducts = mostUsed
+ };
+ }
+
+ private static (DateTime rangeStart, DateTime rangeEndExcl) ResolveAppDateRange(DateTime? startDate, DateTime? endDate)
+ {
+ var endDay = (endDate ?? DateTime.Today).Date;
+ var endExcl = endDay.AddDays(1);
+ var start = (startDate ?? endDay.AddDays(-29)).Date;
+ if (start >= endExcl)
+ {
+ start = endExcl.AddDays(-1);
+ }
+
+ return (start, endExcl);
+ }
+
+ private static decimal CalcAppChangeRate(decimal current, decimal previous)
+ {
+ if (previous == 0)
+ {
+ return current > 0 ? 100m : 0m;
+ }
+
+ return Math.Round((current - previous) * 100m / previous, 2);
+ }
+
+ private async Task ResolveTemplateProductDefaultValuesJsonAsync(
+ string templateId,
+ string? productId,
+ string labelTypeId)
+ {
+ if (string.IsNullOrWhiteSpace(templateId) || string.IsNullOrWhiteSpace(productId) || string.IsNullOrWhiteSpace(labelTypeId))
+ {
+ return null;
+ }
+
+ var productDefault = await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => x.TemplateId == templateId)
+ .Where(x => x.ProductId == productId)
+ .Where(x => x.LabelTypeId == labelTypeId)
+ .OrderBy(x => x.OrderNum)
+ .FirstAsync();
+
+ return string.IsNullOrWhiteSpace(productDefault?.DefaultValuesJson) ? null : productDefault!.DefaultValuesJson;
+ }
+
+ private ISugarQueryable BuildLabelingJoinQuery(
+ string locationId,
+ List productIds,
+ string? filterCategoryId,
+ string? keyword)
+ {
+ var q = _dbContext.SqlSugarClient
+ .Queryable()
+ .InnerJoin((lp, l) => lp.LabelId == l.Id)
+ .InnerJoin((lp, l, p) => lp.ProductId == p.Id)
+ .InnerJoin((lp, l, p, c) => l.LabelCategoryId == c.Id)
+ .InnerJoin((lp, l, p, c, t) => l.LabelTypeId == t.Id)
+ .InnerJoin((lp, l, p, c, t, tpl) => l.TemplateId == tpl.Id)
+ .LeftJoin((lp, l, p, c, t, tpl, pc) => p.CategoryId == pc.Id)
+ .Where((lp, l, p, c, t, tpl, pc) => productIds.Contains(p.Id))
+ .Where((lp, l, p, c, t, tpl, pc) => l.LocationId == locationId)
+ .Where((lp, l, p, c, t, tpl, pc) => !l.IsDeleted && l.State)
+ .Where((lp, l, p, c, t, tpl, pc) => !p.IsDeleted && p.State)
+ .Where((lp, l, p, c, t, tpl, pc) => !c.IsDeleted && c.State)
+ .Where((lp, l, p, c, t, tpl, pc) => !t.IsDeleted && t.State)
+ .Where((lp, l, p, c, t, tpl, pc) => !tpl.IsDeleted)
+ .Where((lp, l, p, c, t, tpl, pc) =>
+ pc.Id == null || (!pc.IsDeleted && pc.State))
+ .WhereIF(!string.IsNullOrWhiteSpace(filterCategoryId), (lp, l, p, c, t, tpl, pc) => l.LabelCategoryId == filterCategoryId)
+ .WhereIF(!string.IsNullOrWhiteSpace(keyword), (lp, l, p, c, t, tpl, pc) =>
+ (l.LabelName != null && l.LabelName.Contains(keyword!)) ||
+ (p.ProductName != null && p.ProductName.Contains(keyword!)) ||
+ (pc.CategoryName != null && pc.CategoryName.Contains(keyword!)) ||
+ (pc.DisplayText != null && pc.DisplayText.Contains(keyword!)) ||
+ (c.CategoryName != null && c.CategoryName.Contains(keyword!)) ||
+ (t.TypeName != null && t.TypeName.Contains(keyword!)) ||
+ (l.LabelCode != null && l.LabelCode.Contains(keyword!)));
+
+ return q;
+ }
+
+ private sealed class LabelingTreeRow
+ {
+ public string LabelCategoryId { get; set; } = string.Empty;
+
+ public string? LabelCategoryName { get; set; }
+
+ public string? LabelCategoryPhotoUrl { get; set; }
+
+ public string? LabelCategoryButtonAppearance { get; set; }
+
+ public int LabelCategoryOrderNum { get; set; }
+
+ public string? ProductCategoryId { get; set; }
+
+ public string? ProductCategoryName { get; set; }
+
+ public string? ProductCategoryPhotoUrl { get; set; }
+
+ public string? ProductCategoryDisplayText { get; set; }
+
+ public string? ProductCategoryButtonAppearance { get; set; }
+
+ public string? ProductCategoryAvailabilityType { get; set; }
+
+ public int ProductCategoryOrderNum { get; set; }
+
+ public string ProductId { get; set; } = string.Empty;
+
+ public string? ProductName { get; set; }
+
+ public string? ProductCode { get; set; }
+
+ public string? ProductImageUrl { get; set; }
+
+ public string? ProductDisplayText { get; set; }
+
+ public string? ProductCodeValue { get; set; }
+
+ public string? ProductButtonAppearance { get; set; }
+
+ /// 产品级 CategoryPhotoUrl(fl_product),勿与 L2 产品分类字段混淆
+ public string? ProductAppearancePhotoUrl { get; set; }
+
+ public string LabelTypeId { get; set; } = string.Empty;
+
+ public string? TypeName { get; set; }
+
+ public int TypeOrderNum { get; set; }
+
+ public string LabelCode { get; set; } = string.Empty;
+
+ public string TemplateId { get; set; } = string.Empty;
+
+ public string? TemplateCode { get; set; }
+
+ public decimal TemplateWidth { get; set; }
+
+ public decimal TemplateHeight { get; set; }
+
+ public string TemplateUnit { get; set; } = "inch";
+ }
+
+ ///
+ /// 将 App 入参中的 JsonElement(对象或 null)反序列化为 PreviewAsync 所需的扁平字典。
+ ///
+ private static Dictionary? ParsePrintInputJsonToDictionary(JsonElement? printInputJson)
+ {
+ if (printInputJson is null)
+ {
+ return null;
+ }
+
+ var je = printInputJson.Value;
+ if (je.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
+ {
+ return null;
+ }
+
+ try
+ {
+ return JsonSerializer.Deserialize>(je.GetRawText());
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ private static string FormatProductCodeValueDisplay(string? codeValue)
+ {
+ var s = codeValue?.Trim();
+ return string.IsNullOrWhiteSpace(s) ? "无" : s;
+ }
+
+ private static string NormalizeCategoryName(string? categoryName)
+ {
+ var s = categoryName?.Trim();
+ return string.IsNullOrWhiteSpace(s) ? "无" : s;
+ }
+
+ private static string? NormalizeNullableId(string? id)
+ {
+ var s = id?.Trim();
+ return string.IsNullOrWhiteSpace(s) ? null : s;
+ }
+
+ private static string? NormalizeNullableUrl(string? url)
+ {
+ var s = url?.Trim();
+ return string.IsNullOrWhiteSpace(s) ? null : s;
+ }
+
+ private async Task ResolvePreviewProductIdAsync(string labelId, string? productId)
+ {
+ var resolvedProductId = productId?.Trim();
+ if (!string.IsNullOrWhiteSpace(resolvedProductId))
+ {
+ return resolvedProductId;
+ }
+
+ return await _dbContext.SqlSugarClient.Queryable()
+ .Where(x => x.LabelId == labelId)
+ .Select(x => x.ProductId)
+ .FirstAsync();
+ }
+
+ private static UsAppLabelTypeNodeDto BuildLabelTypeNode(LabelingTreeRow r)
+ {
+ return new UsAppLabelTypeNodeDto
+ {
+ LabelTypeId = r.LabelTypeId,
+ TypeName = r.TypeName ?? string.Empty,
+ OrderNum = r.TypeOrderNum,
+ LabelCode = r.LabelCode ?? string.Empty,
+ TemplateCode = r.TemplateCode,
+ LabelSizeText = FormatLabelSize(r.TemplateWidth, r.TemplateHeight, r.TemplateUnit)
+ };
+ }
+
+ private static string? FormatLabelSize(decimal w, decimal h, string unit)
+ {
+ var u = (unit ?? "inch").Trim().ToLowerInvariant();
+ var ws = w.ToString(CultureInfo.InvariantCulture);
+ var hs = h.ToString(CultureInfo.InvariantCulture);
+ return u is "inch" or "in"
+ ? $"{ws}\"x{hs}\""
+ : $"{ws}x{hs}{u}";
+ }
+
+ private static string? FormatLabelSizeWithUnit(decimal w, decimal h, string unit)
+ {
+ var u = (unit ?? "inch").Trim().ToLowerInvariant();
+ var ws = w.ToString(CultureInfo.InvariantCulture);
+ var hs = h.ToString(CultureInfo.InvariantCulture);
+ var normalizedUnit = u is "in" ? "inch" : u;
+ return $"{ws}x{hs}{normalizedUnit}";
+ }
+}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application.Contracts/FoodLabeling.Th.Application.Contracts.csproj b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application.Contracts/FoodLabeling.Th.Application.Contracts.csproj
index 9a463f4..adda440 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application.Contracts/FoodLabeling.Th.Application.Contracts.csproj
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application.Contracts/FoodLabeling.Th.Application.Contracts.csproj
@@ -3,6 +3,7 @@
+
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/FoodLabeling.Th.Application.csproj b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/FoodLabeling.Th.Application.csproj
index c017985..9a6fc2c 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/FoodLabeling.Th.Application.csproj
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/FoodLabeling.Th.Application.csproj
@@ -2,7 +2,11 @@
+
+
+
+
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/FoodLabelingThApplicationModule.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/FoodLabelingThApplicationModule.cs
index 273cf1a..c87a951 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/FoodLabelingThApplicationModule.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/FoodLabelingThApplicationModule.cs
@@ -1,5 +1,10 @@
+using FoodLabeling.Application;
using FoodLabeling.Th.Application.Contracts;
+using FoodLabeling.Th.Application.Contracts.Options;
using FoodLabeling.Th.Domain;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AspNetCore.Mvc;
using Yi.Framework.Ddd.Application;
namespace FoodLabeling.Th.Application;
@@ -10,9 +15,21 @@ namespace FoodLabeling.Th.Application;
[DependsOn(
typeof(FoodLabelingThApplicationContractsModule),
typeof(FoodLabelingThDomainModule),
+ typeof(FoodLabelingApplicationModule),
typeof(YiFrameworkDddApplicationModule)
)]
public class FoodLabelingThApplicationModule : AbpModule
{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(
+ context.Services.GetConfiguration().GetSection(FoodLabelingThTenantDatabaseOptions.SectionName));
+
+ Configure(options =>
+ {
+ options.ConventionalControllers.Create(typeof(FoodLabelingThApplicationModule).Assembly,
+ opt => opt.RemoteServiceName = "泰额版-食品标签");
+ });
+ }
}
diff --git a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
index d23327c..9e4b9dd 100644
--- a/泰额版/Food Labeling Management Code/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
+++ b/泰额版/Food Labeling Management Code/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
@@ -46,6 +46,7 @@ using Yi.Framework.Rbac.Domain.Shared.Options;
using Yi.Framework.TenantManagement.Application;
using Antis.Erp.Application;
using FoodLabeling.Application;
+using FoodLabeling.Application.MultiTenancy;
using FoodLabeling.Th.Application;
namespace Yi.Abp.Web
@@ -196,12 +197,10 @@ namespace Yi.Abp.Web
//配置多租户
Configure(options =>
{
- //基于cookie jwt不好用,有坑
options.TenantResolvers.Clear();
+ // 独立库模式:必须显式传 __tenant 或 JWT TenantId;无租户时走平台主库(yitenant)
options.TenantResolvers.Add(new HeaderTenantResolveContributor());
- //options.TenantResolvers.Add(new HeaderTenantResolveContributor());
- //options.TenantResolvers.Add(new CookieTenantResolveContributor());
- //options.TenantResolvers.RemoveAll(x => x.Name == CookieTenantResolveContributor.ContributorName);
+ options.TenantResolvers.Add(new JwtClaimTenantResolveContributor());
});
//配置Hangfire定时任务存储,开启redis后,优先使用redis
diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/UserAggregateRoot.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/UserAggregateRoot.cs
index 0f5c0b2..390e0a5 100644
--- a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/UserAggregateRoot.cs
+++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/UserAggregateRoot.cs
@@ -1,4 +1,4 @@
-using SqlSugar;
+using SqlSugar;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Yi.Framework.Core.Data;