From 1a0aced391318fe78f8b184323c11447268785f9 Mon Sep 17 00:00:00 2001 From: maqiao <625215135@qq.com> Date: Fri, 18 Apr 2025 11:01:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MasaBlazorApp3.sln | 25 + MasaBlazorApp3/App.razor | 15 + .../DataAccess/AppDataConnection.cs | 35 + .../DataAccess/ChannelStockWithDrawerCount.cs | 14 + .../DataAccess/Dao/IChannelListDao.cs | 33 + MasaBlazorApp3/DataAccess/Dao/IDrugInfoDao.cs | 34 + .../DataAccess/Dao/IDrugManuNoDao.cs | 19 + .../DataAccess/Dao/IInOutInvoiceDao.cs | 23 + .../DataAccess/Dao/IMachineRecordDao.cs | 30 + .../DataAccess/Dao/IOrderInfoDao.cs | 30 + MasaBlazorApp3/DataAccess/Dao/IRoleDao.cs | 18 + MasaBlazorApp3/DataAccess/Dao/ISelfTakeDao.cs | 17 + MasaBlazorApp3/DataAccess/Dao/IUserDao.cs | 23 + .../DataAccess/Impl/ChannelListDao.cs | 456 + MasaBlazorApp3/DataAccess/Impl/DrugInfoDao.cs | 132 + .../DataAccess/Impl/DrugManuNoDao.cs | 44 + .../DataAccess/Impl/InOutInvoiceDao.cs | 510 + .../DataAccess/Impl/MachineRecordDao.cs | 406 + .../DataAccess/Impl/OrderInfoDao.cs | 544 + MasaBlazorApp3/DataAccess/Impl/RoleDao.cs | 75 + MasaBlazorApp3/DataAccess/Impl/SelfTakeDao.cs | 300 + MasaBlazorApp3/DataAccess/Impl/UserDao.cs | 111 + MasaBlazorApp3/DataAccess/PageData.cs | 14 + MasaBlazorApp3/DataAccess/PageMultiData.cs | 15 + MasaBlazorApp3/Finger/FingerprintUtil.cs | 142 + MasaBlazorApp3/GlobalStateService.cs | 40 + MasaBlazorApp3/MasaBlazorApp3.csproj | 96 + MasaBlazorApp3/Pages/BiaoDing.razor | 288 + MasaBlazorApp3/Pages/ConfirmDialo.razor | 27 + MasaBlazorApp3/Pages/DrawerAdd.razor | 446 + MasaBlazorApp3/Pages/DrawerTake.razor | 445 + MasaBlazorApp3/Pages/DrugList.razor | 338 + MasaBlazorApp3/Pages/FingerRegDialog.razor | 70 + MasaBlazorApp3/Pages/Home.razor | 220 + MasaBlazorApp3/Pages/Index.razor | 234 + MasaBlazorApp3/Pages/InvoiceAdd.razor | 114 + MasaBlazorApp3/Pages/InvoiceAddDialog.razor | 300 + MasaBlazorApp3/Pages/InvoiceOut.razor | 114 + MasaBlazorApp3/Pages/InvoiceOutDialog.razor | 298 + MasaBlazorApp3/Pages/MachineRecordList.razor | 118 + MasaBlazorApp3/Pages/OrderDetailDialog.razor | 259 + .../Pages/OrderDetailReturnDialog.razor | 280 + MasaBlazorApp3/Pages/OrderReturn.razor | 118 + MasaBlazorApp3/Pages/OrderTake.razor | 118 + MasaBlazorApp3/Pages/RecordRetunDrug.razor | 144 + .../Pages/RecordReturnDrugDialog.razor | 309 + MasaBlazorApp3/Pages/RecordReturnEmpty.razor | 129 + .../Pages/RecordReturnEmptyDialog.razor | 305 + MasaBlazorApp3/Pages/ReturnRecord2.razor | 101 + MasaBlazorApp3/Pages/Role.razor | 268 + MasaBlazorApp3/Pages/SelfTake.razor | 294 + MasaBlazorApp3/Pages/SelfTakeDialog.razor | 247 + MasaBlazorApp3/Pages/SignatureDialog.razor | 66 + MasaBlazorApp3/Pages/StockBinding.razor | 290 + MasaBlazorApp3/Pages/StockCheck.razor | 307 + MasaBlazorApp3/Pages/StockList.razor | 90 + MasaBlazorApp3/Pages/TEST.razor | 87 + MasaBlazorApp3/Pages/User.razor | 306 + MasaBlazorApp3/Pojo/AccountBook.cs | 113 + MasaBlazorApp3/Pojo/ChannelList.cs | 48 + MasaBlazorApp3/Pojo/ChannelStock.cs | 83 + MasaBlazorApp3/Pojo/Config/DrawerConfig.cs | 17 + MasaBlazorApp3/Pojo/Config/FingerPojo.cs | 15 + MasaBlazorApp3/Pojo/Config/PortConfig.cs | 23 + MasaBlazorApp3/Pojo/Config/SettingConfig.cs | 19 + MasaBlazorApp3/Pojo/DrugInfo.cs | 62 + MasaBlazorApp3/Pojo/DrugManuNo.cs | 40 + MasaBlazorApp3/Pojo/InOutInvoice.cs | 146 + MasaBlazorApp3/Pojo/MachineRecord.cs | 149 + MasaBlazorApp3/Pojo/OrderDetail.cs | 133 + MasaBlazorApp3/Pojo/OrderFinish.cs | 33 + MasaBlazorApp3/Pojo/OrderInfo.cs | 159 + MasaBlazorApp3/Pojo/Premission.cs | 207 + MasaBlazorApp3/Pojo/Role.cs | 50 + MasaBlazorApp3/Pojo/User.cs | 39 + MasaBlazorApp3/Pojo/Vo/InvoiceVo.cs | 34 + MasaBlazorApp3/Pojo/Vo/OperationVo.cs | 37 + MasaBlazorApp3/Pojo/Vo/OrderTakeVo.cs | 32 + MasaBlazorApp3/Port/PortUtil.cs | 987 ++ MasaBlazorApp3/Port/ScreenUtil.cs | 171 + MasaBlazorApp3/Program.cs | 92 + MasaBlazorApp3/Report/GridReportUtil.cs | 38 + .../ReportTemp/account_book_temp.grf | 612 + MasaBlazorApp3/ReportTemp/machine_log_add.grf | 284 + .../ReportTemp/machine_log_check.grf | 284 + .../ReportTemp/machine_log_return.grf | 284 + .../ReportTemp/machine_log_take.grf | 284 + MasaBlazorApp3/ReportTemp/stock_template.grf | 348 + MasaBlazorApp3/Shared/EmptyLayout.razor | 6 + MasaBlazorApp3/Shared/MainLayout.razor | 154 + MasaBlazorApp3/Util/CheckComputerFreeState.cs | 53 + MasaBlazorApp3/Util/MD5.cs | 30 + MasaBlazorApp3/Util/PromiseUtil.cs | 44 + MasaBlazorApp3/Util/VirtualKeyboardHelper.cs | 342 + .../Validator/LoginModelValidator.cs | 22 + MasaBlazorApp3/_Imports.razor | 24 + MasaBlazorApp3/appsettings.json | 32 + MasaBlazorApp3/favicon.ico | Bin 0 -> 270398 bytes MasaBlazorApp3/i18ntext/MyText.en.json | 4 + MasaBlazorApp3/i18ntext/MyText.zh.json | 4 + MasaBlazorApp3/log4net.config | 53 + MasaBlazorApp3/wwwroot/css/app.css | 62 + .../wwwroot/css/bootstrap/bootstrap.min.css | 11599 ++++++++++++++++ .../css/bootstrap/bootstrap.min.css.map | 1 + MasaBlazorApp3/wwwroot/favicon.ico | Bin 0 -> 5430 bytes MasaBlazorApp3/wwwroot/images/TbExit.png | Bin 0 -> 5613 bytes MasaBlazorApp3/wwwroot/images/TbJiay.png | Bin 0 -> 5521 bytes MasaBlazorApp3/wwwroot/images/TbJjb.png | Bin 0 -> 3522 bytes MasaBlazorApp3/wwwroot/images/TbKuc.png | Bin 0 -> 20283 bytes MasaBlazorApp3/wwwroot/images/TbLsh.png | Bin 0 -> 5665 bytes MasaBlazorApp3/wwwroot/images/TbQyao.png | Bin 0 -> 5774 bytes MasaBlazorApp3/wwwroot/images/TbSet.png | Bin 0 -> 5554 bytes MasaBlazorApp3/wwwroot/images/TbTuiy.png | Bin 0 -> 5708 bytes MasaBlazorApp3/wwwroot/images/body-bg.jpg | Bin 0 -> 19588 bytes MasaBlazorApp3/wwwroot/images/body-bg.png | Bin 0 -> 140077 bytes MasaBlazorApp3/wwwroot/images/box-16.jpg | Bin 0 -> 18695 bytes MasaBlazorApp3/wwwroot/images/box.png | Bin 0 -> 5630 bytes MasaBlazorApp3/wwwroot/images/finger-bg-r.png | Bin 0 -> 54076 bytes MasaBlazorApp3/wwwroot/images/logo.png | Bin 0 -> 3660 bytes MasaBlazorApp3/wwwroot/images/no_auth.png | Bin 0 -> 1587 bytes MasaBlazorApp3/wwwroot/index.html | 37 + MasaBlazorApp3/wwwroot/signature.js | 1 + MasaBlazorApp3/wwwroot/signatureInit.js | 29 + 123 files changed, 27251 insertions(+) create mode 100644 MasaBlazorApp3.sln create mode 100644 MasaBlazorApp3/App.razor create mode 100644 MasaBlazorApp3/DataAccess/AppDataConnection.cs create mode 100644 MasaBlazorApp3/DataAccess/ChannelStockWithDrawerCount.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/IChannelListDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/IDrugInfoDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/IDrugManuNoDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/IInOutInvoiceDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/IMachineRecordDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/IOrderInfoDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/IRoleDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/ISelfTakeDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Dao/IUserDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/ChannelListDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/DrugInfoDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/DrugManuNoDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/InOutInvoiceDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/MachineRecordDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/OrderInfoDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/RoleDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/SelfTakeDao.cs create mode 100644 MasaBlazorApp3/DataAccess/Impl/UserDao.cs create mode 100644 MasaBlazorApp3/DataAccess/PageData.cs create mode 100644 MasaBlazorApp3/DataAccess/PageMultiData.cs create mode 100644 MasaBlazorApp3/Finger/FingerprintUtil.cs create mode 100644 MasaBlazorApp3/GlobalStateService.cs create mode 100644 MasaBlazorApp3/MasaBlazorApp3.csproj create mode 100644 MasaBlazorApp3/Pages/BiaoDing.razor create mode 100644 MasaBlazorApp3/Pages/ConfirmDialo.razor create mode 100644 MasaBlazorApp3/Pages/DrawerAdd.razor create mode 100644 MasaBlazorApp3/Pages/DrawerTake.razor create mode 100644 MasaBlazorApp3/Pages/DrugList.razor create mode 100644 MasaBlazorApp3/Pages/FingerRegDialog.razor create mode 100644 MasaBlazorApp3/Pages/Home.razor create mode 100644 MasaBlazorApp3/Pages/Index.razor create mode 100644 MasaBlazorApp3/Pages/InvoiceAdd.razor create mode 100644 MasaBlazorApp3/Pages/InvoiceAddDialog.razor create mode 100644 MasaBlazorApp3/Pages/InvoiceOut.razor create mode 100644 MasaBlazorApp3/Pages/InvoiceOutDialog.razor create mode 100644 MasaBlazorApp3/Pages/MachineRecordList.razor create mode 100644 MasaBlazorApp3/Pages/OrderDetailDialog.razor create mode 100644 MasaBlazorApp3/Pages/OrderDetailReturnDialog.razor create mode 100644 MasaBlazorApp3/Pages/OrderReturn.razor create mode 100644 MasaBlazorApp3/Pages/OrderTake.razor create mode 100644 MasaBlazorApp3/Pages/RecordRetunDrug.razor create mode 100644 MasaBlazorApp3/Pages/RecordReturnDrugDialog.razor create mode 100644 MasaBlazorApp3/Pages/RecordReturnEmpty.razor create mode 100644 MasaBlazorApp3/Pages/RecordReturnEmptyDialog.razor create mode 100644 MasaBlazorApp3/Pages/ReturnRecord2.razor create mode 100644 MasaBlazorApp3/Pages/Role.razor create mode 100644 MasaBlazorApp3/Pages/SelfTake.razor create mode 100644 MasaBlazorApp3/Pages/SelfTakeDialog.razor create mode 100644 MasaBlazorApp3/Pages/SignatureDialog.razor create mode 100644 MasaBlazorApp3/Pages/StockBinding.razor create mode 100644 MasaBlazorApp3/Pages/StockCheck.razor create mode 100644 MasaBlazorApp3/Pages/StockList.razor create mode 100644 MasaBlazorApp3/Pages/TEST.razor create mode 100644 MasaBlazorApp3/Pages/User.razor create mode 100644 MasaBlazorApp3/Pojo/AccountBook.cs create mode 100644 MasaBlazorApp3/Pojo/ChannelList.cs create mode 100644 MasaBlazorApp3/Pojo/ChannelStock.cs create mode 100644 MasaBlazorApp3/Pojo/Config/DrawerConfig.cs create mode 100644 MasaBlazorApp3/Pojo/Config/FingerPojo.cs create mode 100644 MasaBlazorApp3/Pojo/Config/PortConfig.cs create mode 100644 MasaBlazorApp3/Pojo/Config/SettingConfig.cs create mode 100644 MasaBlazorApp3/Pojo/DrugInfo.cs create mode 100644 MasaBlazorApp3/Pojo/DrugManuNo.cs create mode 100644 MasaBlazorApp3/Pojo/InOutInvoice.cs create mode 100644 MasaBlazorApp3/Pojo/MachineRecord.cs create mode 100644 MasaBlazorApp3/Pojo/OrderDetail.cs create mode 100644 MasaBlazorApp3/Pojo/OrderFinish.cs create mode 100644 MasaBlazorApp3/Pojo/OrderInfo.cs create mode 100644 MasaBlazorApp3/Pojo/Premission.cs create mode 100644 MasaBlazorApp3/Pojo/Role.cs create mode 100644 MasaBlazorApp3/Pojo/User.cs create mode 100644 MasaBlazorApp3/Pojo/Vo/InvoiceVo.cs create mode 100644 MasaBlazorApp3/Pojo/Vo/OperationVo.cs create mode 100644 MasaBlazorApp3/Pojo/Vo/OrderTakeVo.cs create mode 100644 MasaBlazorApp3/Port/PortUtil.cs create mode 100644 MasaBlazorApp3/Port/ScreenUtil.cs create mode 100644 MasaBlazorApp3/Program.cs create mode 100644 MasaBlazorApp3/Report/GridReportUtil.cs create mode 100644 MasaBlazorApp3/ReportTemp/account_book_temp.grf create mode 100644 MasaBlazorApp3/ReportTemp/machine_log_add.grf create mode 100644 MasaBlazorApp3/ReportTemp/machine_log_check.grf create mode 100644 MasaBlazorApp3/ReportTemp/machine_log_return.grf create mode 100644 MasaBlazorApp3/ReportTemp/machine_log_take.grf create mode 100644 MasaBlazorApp3/ReportTemp/stock_template.grf create mode 100644 MasaBlazorApp3/Shared/EmptyLayout.razor create mode 100644 MasaBlazorApp3/Shared/MainLayout.razor create mode 100644 MasaBlazorApp3/Util/CheckComputerFreeState.cs create mode 100644 MasaBlazorApp3/Util/MD5.cs create mode 100644 MasaBlazorApp3/Util/PromiseUtil.cs create mode 100644 MasaBlazorApp3/Util/VirtualKeyboardHelper.cs create mode 100644 MasaBlazorApp3/Validator/LoginModelValidator.cs create mode 100644 MasaBlazorApp3/_Imports.razor create mode 100644 MasaBlazorApp3/appsettings.json create mode 100644 MasaBlazorApp3/favicon.ico create mode 100644 MasaBlazorApp3/i18ntext/MyText.en.json create mode 100644 MasaBlazorApp3/i18ntext/MyText.zh.json create mode 100644 MasaBlazorApp3/log4net.config create mode 100644 MasaBlazorApp3/wwwroot/css/app.css create mode 100644 MasaBlazorApp3/wwwroot/css/bootstrap/bootstrap.min.css create mode 100644 MasaBlazorApp3/wwwroot/css/bootstrap/bootstrap.min.css.map create mode 100644 MasaBlazorApp3/wwwroot/favicon.ico create mode 100644 MasaBlazorApp3/wwwroot/images/TbExit.png create mode 100644 MasaBlazorApp3/wwwroot/images/TbJiay.png create mode 100644 MasaBlazorApp3/wwwroot/images/TbJjb.png create mode 100644 MasaBlazorApp3/wwwroot/images/TbKuc.png create mode 100644 MasaBlazorApp3/wwwroot/images/TbLsh.png create mode 100644 MasaBlazorApp3/wwwroot/images/TbQyao.png create mode 100644 MasaBlazorApp3/wwwroot/images/TbSet.png create mode 100644 MasaBlazorApp3/wwwroot/images/TbTuiy.png create mode 100644 MasaBlazorApp3/wwwroot/images/body-bg.jpg create mode 100644 MasaBlazorApp3/wwwroot/images/body-bg.png create mode 100644 MasaBlazorApp3/wwwroot/images/box-16.jpg create mode 100644 MasaBlazorApp3/wwwroot/images/box.png create mode 100644 MasaBlazorApp3/wwwroot/images/finger-bg-r.png create mode 100644 MasaBlazorApp3/wwwroot/images/logo.png create mode 100644 MasaBlazorApp3/wwwroot/images/no_auth.png create mode 100644 MasaBlazorApp3/wwwroot/index.html create mode 100644 MasaBlazorApp3/wwwroot/signature.js create mode 100644 MasaBlazorApp3/wwwroot/signatureInit.js diff --git a/MasaBlazorApp3.sln b/MasaBlazorApp3.sln new file mode 100644 index 0000000..6b2abd8 --- /dev/null +++ b/MasaBlazorApp3.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34024.191 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MasaBlazorApp3", "MasaBlazorApp3\MasaBlazorApp3.csproj", "{B589889C-FAEB-4394-A21D-DDCADF39382D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B589889C-FAEB-4394-A21D-DDCADF39382D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B589889C-FAEB-4394-A21D-DDCADF39382D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B589889C-FAEB-4394-A21D-DDCADF39382D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B589889C-FAEB-4394-A21D-DDCADF39382D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {304B4C57-445A-464F-829B-444D21AFE355} + EndGlobalSection +EndGlobal diff --git a/MasaBlazorApp3/App.razor b/MasaBlazorApp3/App.razor new file mode 100644 index 0000000..35e483c --- /dev/null +++ b/MasaBlazorApp3/App.razor @@ -0,0 +1,15 @@ +@namespace MasaBlazorApp3 + + + + + + + + +

Sorry, there's nothing at this address.

+
+
+
+ + diff --git a/MasaBlazorApp3/DataAccess/AppDataConnection.cs b/MasaBlazorApp3/DataAccess/AppDataConnection.cs new file mode 100644 index 0000000..a632a31 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/AppDataConnection.cs @@ -0,0 +1,35 @@ +using Google.Protobuf.Compiler; +using LinqToDB; +using LinqToDB.Data; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MasaBlazorApp3.Pojo; + +namespace MasaBlazorApp3.DataAccess +{ + public class AppDataConnection : DataConnection + { + public AppDataConnection(DataOptions options) + : base(options.Options) + { + } + + public ITable User => this.GetTable(); + public ITable Role => this.GetTable(); + public ITable ChannelList => this.GetTable(); + public ITable ChannelStock => this.GetTable(); + public ITable DrugInfo => this.GetTable(); + public ITable DrugManuNo => this.GetTable(); + public ITable OrderInfo => this.GetTable(); + public ITable OrderDetail => this.GetTable(); + public ITable MachineRecord => this.GetTable(); + public ITable InOutInvoice => this.GetTable(); + public ITable AccountBook => this.GetTable(); + + + + } +} diff --git a/MasaBlazorApp3/DataAccess/ChannelStockWithDrawerCount.cs b/MasaBlazorApp3/DataAccess/ChannelStockWithDrawerCount.cs new file mode 100644 index 0000000..7f3eeb8 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/ChannelStockWithDrawerCount.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess +{ + public class ChannelStockWithDrawerCount + { + public int[] DrawerArray { get; set; } + public List ChannelStocks { get; set; } = new List(); + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/IChannelListDao.cs b/MasaBlazorApp3/DataAccess/Dao/IChannelListDao.cs new file mode 100644 index 0000000..e240ea7 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/IChannelListDao.cs @@ -0,0 +1,33 @@ +using System; +using MasaBlazorApp3.Pojo; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + public interface IChannelListDao + { + public Task> GetAllChannelList(int DrawerType, string drugName, int? take, int? skip); + + public Task> GetChannelStockByDrugId(string DrugId); + public Task> GetChannelListByDrawerNo(int DrawerNo); + public Task> GetChannelStockByDrawerNo(int DrawerNo, int Quantity = 0); + + + public Task> GetAllDrugChannelStock(); + + public Task> GetAllDrugChannelList(); + + public Task DrawerOperationFinish(List Stocks, int type); + + public Task UnBind(string id); + + public Task Bind(ChannelStock Stock); + + + Task> GetAllChannelListWithDrug(int DrawerType, string drugName, int? take, int? skip); + + Task> GetChannelStockByDrawerNoWithDrawers(int DrawerNo, int Quantity = 0); + + //盘点 + public Task DrawerCheckFinish(List Stocks); + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/IDrugInfoDao.cs b/MasaBlazorApp3/DataAccess/Dao/IDrugInfoDao.cs new file mode 100644 index 0000000..8675833 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/IDrugInfoDao.cs @@ -0,0 +1,34 @@ +using MasaBlazorApp3.Pojo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + public interface IDrugInfoDao + { + Task> GetAllDrugAndStock(); + + + Task> GetAllDrug(); + + + Task> GetAllDrug(string drugId, string drugName, int? take, int? skip); + + + //Task> GetAllDrugAndStockList(); + + Task GetDrugManuNo(string drugId, string manuNo); + + + //添加药品信息 + int AddDrugInfo(DrugInfo drugInfo); + + //删除药品信息 + Task DeleteDrugInfo(string drugId); + //修改药品信息 + Task UpdateDrugInfo(DrugInfo drugInfo); + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/IDrugManuNoDao.cs b/MasaBlazorApp3/DataAccess/Dao/IDrugManuNoDao.cs new file mode 100644 index 0000000..953cd58 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/IDrugManuNoDao.cs @@ -0,0 +1,19 @@ +using MasaBlazorApp3.Pojo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + public interface IDrugManuNoDao + { + //添加批次 + int AddDrugManuNo(DrugManuNo drugManuNo); + //修改批次 + bool UpdateDrugManuNo(DrugManuNo drugManuNo); + //删除批次 + bool DeleteDrugManuNo(string id); + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/IInOutInvoiceDao.cs b/MasaBlazorApp3/DataAccess/Dao/IInOutInvoiceDao.cs new file mode 100644 index 0000000..182c63d --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/IInOutInvoiceDao.cs @@ -0,0 +1,23 @@ +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Vo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + public interface IInOutInvoiceDao + { + Task> GetAllInvoiceByType(string invoiceNo, DateTime invoiceDate, int? take, int? skip, int type); + + Task> getTakeInfoByInvoiceNo(string invoiceNo); + Task> getAddInfoByInvoiceNo(string invoiceNo); + + Task InvoiceOutFinish(List data); + + + Task InvoiceAddFinish(List data); + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/IMachineRecordDao.cs b/MasaBlazorApp3/DataAccess/Dao/IMachineRecordDao.cs new file mode 100644 index 0000000..cfbbd47 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/IMachineRecordDao.cs @@ -0,0 +1,30 @@ +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Vo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + public interface IMachineRecordDao + { + int InsertMachineRecord(MachineRecord record); + + Task> GetMachineRecordAsync(DateTime start, DateTime end, int operatorId, string drugId, int type, int? take, int? skip); + + Task> GetCanReturnRecords(DateTime start, DateTime end, int operatorId, string drugId, int? take, int? skip); + + Task>>> getReturnDrugInfoByRecords(List records); + + Task ReturnDrugFinish(List>> datas); + + Task> GetReturnEmpty(); + + Task> getReturnEmptyInfoByRecords(ChannelStock records); + + Task ReturnEmptyFinish(List datas,ChannelStock channelStock); + Task> GetReturnEmptyWithCanReturnQuantiy(); + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/IOrderInfoDao.cs b/MasaBlazorApp3/DataAccess/Dao/IOrderInfoDao.cs new file mode 100644 index 0000000..a5b0c7e --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/IOrderInfoDao.cs @@ -0,0 +1,30 @@ +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Vo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + public interface IOrderInfoDao + { + public Task> GetAllOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip); + + + public Task> GetAllCanReturnOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip); + + public Task> getDetailByOrderNo(string OrderrNo); + + + public Task> getTakeInfoByOrderNo(string OrderrNo); + + public Task OrderTakeFinish(List datas); + + + public Task OrderReturnFinish(List> datas, string OrderrNo); + + public Task>> getReturnInfoByOrderNo(string OrderrNo); + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/IRoleDao.cs b/MasaBlazorApp3/DataAccess/Dao/IRoleDao.cs new file mode 100644 index 0000000..c1574d1 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/IRoleDao.cs @@ -0,0 +1,18 @@ +using MasaBlazorApp3.Pojo; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + public interface IRoleDao + { + int InsertRole(Role role); + Task GetRoleById(int id); + + bool UpdateRole(Role role); + bool DeleteRole(int id); + + Task> GetRolesByName(string name, int? take, int? skip); + + Task> GetAllRoles(); + + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/ISelfTakeDao.cs b/MasaBlazorApp3/DataAccess/Dao/ISelfTakeDao.cs new file mode 100644 index 0000000..987fdef --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/ISelfTakeDao.cs @@ -0,0 +1,17 @@ +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Vo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + interface ISelfTakeDao + { + Task> GetChannelStocksByDrug(List drugInfos); + Task> getTakeInfoByOrderNo(List orderDetails); + Task OrderTakeFinish(List datas,OrderInfo order); + } +} diff --git a/MasaBlazorApp3/DataAccess/Dao/IUserDao.cs b/MasaBlazorApp3/DataAccess/Dao/IUserDao.cs new file mode 100644 index 0000000..11e41a4 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Dao/IUserDao.cs @@ -0,0 +1,23 @@ +using MasaBlazorApp3.Pojo; + +namespace MasaBlazorApp3.DataAccess.Dao +{ + public interface IUserDao + { + int InsertUser(User user); + + Task> GetAllByNickname(string nickname, int? take, int? skip); + + User GetById(int id); + + User GetByUsername(string username); + + bool UpdateUser(User user); + + bool DeleteeUser(int id); + //重置用户密码 + bool ResetPassword(int id); + + Task UpdateSign(int id, string sign); + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/ChannelListDao.cs b/MasaBlazorApp3/DataAccess/Impl/ChannelListDao.cs new file mode 100644 index 0000000..33366ad --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/ChannelListDao.cs @@ -0,0 +1,456 @@ + +using LinqToDB; +using log4net; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Config; +using MasaBlazorApp3.Pojo.Vo; +using MasaBlazorApp3.Port; +using Microsoft.Extensions.Options; +using Mysqlx.Crud; +using System.Data; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class ChannelListDao : IChannelListDao + { + + private AppDataConnection _connection; + private readonly SettingConfig _setting; + private GlobalStateService _globalStateService; + private readonly PortUtil _portUtil; + + private readonly ILog logger = LogManager.GetLogger(typeof(ChannelListDao)); + + public ChannelListDao(AppDataConnection connection, IOptions setting, GlobalStateService globalStateService, PortUtil portUtil) + { + _globalStateService = globalStateService; + _connection = connection; + _setting = setting.Value; + _portUtil = portUtil; + } + + public async Task> GetAllChannelList(int DrawerType, string drugName, int? take, int? skip) + { + + var query = _connection.ChannelStock.AsQueryable(); + + if (DrawerType != 0) + { + query = query.Where(cl => cl.DrawerType == DrawerType); + } + + if (!String.IsNullOrEmpty(drugName)) + { + query = query.Where(cl => cl.Drug.DrugName.Equals(drugName)); + } + + //query = query.Where(cl => !String.IsNullOrEmpty(cl.DrugId)); + query = query.Where(cl => cl.MachineId == _setting.machineId); + + + int pagedData = await query.CountAsync(); + + List list = await query + .LoadWith(cl => cl.Drug) + .LoadWith(cl => cl.Drug.Manus) + .LoadWith(cl => cl.drugManuNo) + .OrderBy((cl) => cl.DrawerNo) + .ThenBy((cl) => cl.ColNo) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + + + return new PageData() + { + + TotalDesserts = pagedData, + Desserts = list + }; + } + + public async Task> GetChannelStockByDrugId(string DrugId) + { + var query = _connection.ChannelStock.AsQueryable(); + + + return await query + .LoadWith(cs => cs.Drug) + .InnerJoin( + _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1), + (cs, cl) => cs.ListId == cl.Id, + (cs, cl) => cs + ) + .Where(cs => cs.DrugId == DrugId) + .Where(cs => cs.MachineId == _setting.machineId) + //.Where(cs => cs.Quantity > 0) + .OrderBy((cs) => cs.EffDate) + .ThenBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + } + + public async Task> GetChannelStockByDrawerNo(int DrawerNo, int Quantity = 0) + { + var query = _connection.ChannelStock.AsQueryable() + .LoadWith(cs => cs.Drug) + .LoadWith(cs => cs.drugManuNo) + .LoadWith(cs => cs.Drug.Manus) + .Where(cs => cs.DrawerNo == DrawerNo) + .Where(cs => cs.DrugId != String.Empty ) + .Where(cs => cs.DrawerType == 1) + .Where(cs => cs.MachineId == _setting.machineId); + + if(Quantity > 0) + { + query = query.Where(cs => cs.Quantity > 0); + } + return await query + .OrderBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + } + + public async Task> GetChannelListByDrawerNo(int DrawerNo) + { + var query = _connection.ChannelList.AsQueryable(); + + + return await query + .LoadWith(cl => cl.Drug) + .LoadWith(cl => cl.ChannelStocks.Where(cs => cs.Quantity > 0)) + .Where(cl => cl.DrawerNo == DrawerNo) + .Where(cl => cl.DrawerType == 1) + .Where(cl => cl.MachineId == _setting.machineId) + .OrderBy((cl) => cl.DrawerNo) + .ThenBy((cl) => cl.ColNo) + .ToListAsync(); + } + + public async Task> GetAllDrugChannelStock() + { + var query = _connection.ChannelStock.AsQueryable(); + + + return await query + .LoadWith(cs => cs.Drug) + .Where(cs => !String.IsNullOrEmpty(cs.DrugId)) + .Where(cs => cs.DrawerType == 1) + .Where(cs => cs.MachineId == _setting.machineId) + .OrderBy((cs) => cs.DrugId) + .ThenBy((cs) => cs.EffDate) + .ThenBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + } + + public async Task> GetAllDrugChannelList() + { + var query = _connection.ChannelList.AsQueryable(); + + + return await query + .LoadWith(cl => cl.Drug) + .LoadWith(cl => cl.ChannelStocks) + .Where(cl => !String.IsNullOrEmpty(cl.DrugId)) + .Where(cl => cl.DrawerType == 1) + .Where(cl => cl.MachineId == _setting.machineId) + .OrderBy((cl) => cl.DrugId) + .ThenBy((cl) => cl.DrawerNo) + .ThenBy((cl) => cl.ColNo) + .ToListAsync(); + } + + public async Task DrawerOperationFinish(List Stocks, int type = 1) + { + try + { + _connection.BeginTransaction(); + + string InvoiceId = "DRAWER_" + CurrentTimeMillis(); + var flag = true; + for (var i = 0; i < Stocks.Count; i++) + { + var stock = Stocks[i]; + + //var ManuNo = !stock.drugManuNo.ManuNo.Equals(stock.ManuNo) ? stock.drugManuNo.ManuNo : stock.ManuNo; + //var EffDate = !stock.drugManuNo.ManuNo.Equals(stock.ManuNo) ? stock.drugManuNo.EffDate : stock.EffDate; + var ManuNo = stock.ManuNo; + var EffDate = stock.EffDate; + // 出入库记录 + int mid = _connection.InsertWithInt32Identity(new MachineRecord() + { + MachineId = _setting.machineId, + DrawerNo = stock.DrawerNo, + ColNo = stock.ColNo, + DrugId = stock.DrugId, + ManuNo = ManuNo, + EffDate = !String.IsNullOrEmpty(EffDate) ? DateTime.ParseExact(EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = type, + Quantity = type == 1? stock.AddQuantity : stock.TakeQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + InvoiceId = InvoiceId + }); + // 更新库存 + var stockQ = _connection.ChannelStock.Where(cs => cs.Id == stock.Id) + .Set(cs => cs.Quantity, type == 1 ? stock.Quantity + stock.AddQuantity : stock.Quantity - stock.TakeQuantity); + // 入库时如果库存为0则有可能会修改批次效期进行保存 + if(type == 1 && stock.Quantity == 0 && !stock.drugManuNo.ManuNo.Equals(stock.ManuNo)) + { + stockQ = stockQ.Set(cs => cs.ManuNo, stock.drugManuNo.ManuNo).Set(cs => cs.EffDate, stock.drugManuNo.EffDate.ToString()).Set(cs => cs.Dmnguid, stock.drugManuNo.Id); + } + int r = stockQ.Update(); + // 获取更新完库存之后的药品库存 + List list = await _connection.ChannelStock.AsQueryable() + .InnerJoin( + _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1), + (cs, cl) => cs.ListId == cl.Id, + (cs, cl) => cs + ) + .Where(cs => cs.DrugId.Equals(stock.DrugId)) + .ToListAsync(); + // 保存账册 + int acid = _connection.InsertWithInt32Identity(new AccountBook() + { + MachineId = _setting.machineId, + DrugId = stock.DrugId, + ManuNo = ManuNo, + EffDate = !String.IsNullOrEmpty(EffDate) ? DateTime.ParseExact(EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = type, + OutQuantity = stock.TakeQuantity, + AddQuantity = stock.AddQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + ManuStock = list.Where(it => it.ManuNo == stock.ManuNo).Sum(it => it.Quantity), + TotalStock = list.Sum(it => it.Quantity), + InvoiceId = InvoiceId + }); + if (mid > 0 && r > 0 && acid > 0) + { + + } else + { + flag = false; + break; + } + } + if (flag) + { + _connection.CommitTransaction(); + } + else + { + _connection.RollbackTransaction(); + } + return flag; + + } catch (Exception ex) + { + logger.Error($"抽屉{(type == 1 ? "加药" : "取药")}操作完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + + public long CurrentTimeMillis() + { + return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; + } + + public async Task UnBind(string id) + { + var r = await _connection.ChannelStock + .Where(cs => cs.Id == id) + .Set(cs => cs.DrugId, String.Empty) + .Set(cs => cs.Dmnguid, String.Empty) + .Set(cs => cs.EffDate, String.Empty) + .Set(cs => cs.ManuNo, String.Empty) + .UpdateAsync(); + return r > 0; + } + + public async Task Bind(ChannelStock Stock) + { + var q = _connection.ChannelStock + .Where(cs => cs.Id == Stock.Id) + .Set(cs => cs.Dmnguid, Stock.drugManuNo?.Id??String.Empty) + .Set(cs => cs.EffDate, Stock.drugManuNo?.EffDate.ToString() ?? String.Empty) + .Set(cs => cs.ManuNo, Stock.drugManuNo?.ManuNo ?? String.Empty); + + if (Stock.Drug != null && !Stock.Drug.DrugId.Equals(Stock.DrugId)) { + q = q.Set(cs => cs.DrugId, Stock.Drug?.DrugId); + } + + var r = await q.UpdateAsync(); + return r > 0; + } + public async Task> GetAllChannelListWithDrug(int DrawerType, string drugName, int? take, int? skip) + { + + var query = _connection.ChannelStock.AsQueryable(); + + if (DrawerType != 0) + { + query = query.Where(cl => cl.DrawerType == DrawerType); + } + + if (!String.IsNullOrEmpty(drugName)) + { + query = query.Where(cl => cl.Drug.DrugName.Equals(drugName)); + } + + //query = query.Where(cl => !String.IsNullOrEmpty(cl.DrugId)); + query = query.Where(cl => cl.MachineId == _setting.machineId); + + + int pagedData = await query.CountAsync(); + + List list = await query + .LoadWith(cl => cl.Drug) + .LoadWith(cl => cl.Drug.Manus) + .LoadWith(cl => cl.drugManuNo) + .OrderBy((cl) => cl.DrawerNo) + .ThenBy((cl) => cl.ColNo) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + + var other= _connection.DrugInfo.AsQueryable(); + List drugInfos= await other + .LoadWith(di => di.Manus) + .OrderBy((di) => di.DrugId) + .ToListAsync(); + + return new PageMultiData() + { + + TotalDesserts = pagedData, + Desserts = list, + Other= drugInfos + }; + } + //抽屉加药、取药获取数据 + public async Task> GetChannelStockByDrawerNoWithDrawers(int DrawerNo, int Quantity = 0) + { + var query = _connection.ChannelStock.AsQueryable() + .LoadWith(cs => cs.Drug) + .LoadWith(cs => cs.drugManuNo) + .LoadWith(cs => cs.Drug.Manus) + .Where(cs => cs.DrawerNo == DrawerNo) + .Where(cs => cs.DrugId != String.Empty) + .Where(cs => cs.DrawerType == 1) + .Where(cs => cs.MachineId == _setting.machineId); + + if (Quantity > 0) + { + query = query.Where(cs => cs.Quantity > 0); + } + int[] ints = _connection.ChannelStock.Where(cs => cs.MachineId == _setting.machineId).GroupBy(cs=>cs.DrawerNo).Select(cs=>cs.Key).ToArray(); + List channelStocks= await query + .OrderBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + return new ChannelStockWithDrawerCount() { DrawerArray = ints, ChannelStocks = channelStocks }; + } + //盘点 + public async Task DrawerCheckFinish(List Stocks) + { + try + { + _connection.BeginTransaction(); + + string InvoiceId = "DRAWER_" + CurrentTimeMillis(); + var flag = true; + for (var i = 0; i < Stocks.Count; i++) + { + var stock = Stocks[i]; + + //var ManuNo = !stock.drugManuNo.ManuNo.Equals(stock.ManuNo) ? stock.drugManuNo.ManuNo : stock.ManuNo; + //var EffDate = !stock.drugManuNo.ManuNo.Equals(stock.ManuNo) ? stock.drugManuNo.EffDate : stock.EffDate; + var ManuNo = stock.ManuNo; + var EffDate = stock.EffDate; + // 出入库记录 + int mid = _connection.InsertWithInt32Identity(new MachineRecord() + { + MachineId = _setting.machineId, + DrawerNo = stock.DrawerNo, + ColNo = stock.ColNo, + DrugId = stock.DrugId, + ManuNo = ManuNo, + EffDate = !String.IsNullOrEmpty(EffDate) ? DateTime.ParseExact(EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 4, + Quantity =stock.CheckQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + InvoiceId = InvoiceId + }); + // 更新库存 + var stockQ = _connection.ChannelStock.Where(cs => cs.Id == stock.Id) + .Set(cs => cs.Quantity, stock.CheckQuantity); + + int r = stockQ.Update(); + // 获取更新完库存之后的药品库存 + List list = await _connection.ChannelStock.AsQueryable() + .InnerJoin( + _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1), + (cs, cl) => cs.ListId == cl.Id, + (cs, cl) => cs + ) + .Where(cs => cs.DrugId.Equals(stock.DrugId)) + .ToListAsync(); + // 保存账册 + int acid = _connection.InsertWithInt32Identity(new AccountBook() + { + MachineId = _setting.machineId, + DrugId = stock.DrugId, + ManuNo = ManuNo, + EffDate = !String.IsNullOrEmpty(EffDate) ? DateTime.ParseExact(EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 3, + OutQuantity = stock.TakeQuantity, + AddQuantity = stock.AddQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + ManuStock = list.Where(it => it.ManuNo == stock.ManuNo).Sum(it => it.Quantity), + TotalStock = list.Sum(it => it.Quantity), + InvoiceId = InvoiceId + }); + if (mid > 0 && r > 0 && acid > 0) + { + //根据抽屉类型判断是否需要写标签 + if (stock.BoardType.ToString().Contains("5")) + { + await _portUtil.WriteQuantityMethod(stock.CheckQuantity, stock.DrawerNo, stock.ColNo); + } + } + else + { + flag = false; + break; + } + } + if (flag) + { + _connection.CommitTransaction(); + } + else + { + _connection.RollbackTransaction(); + } + return flag; + + } + catch (Exception ex) + { + logger.Error($"抽屉盘点操作完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/DrugInfoDao.cs b/MasaBlazorApp3/DataAccess/Impl/DrugInfoDao.cs new file mode 100644 index 0000000..20bde97 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/DrugInfoDao.cs @@ -0,0 +1,132 @@ +using LinqToDB; +using log4net; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Config; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class DrugInfoDao : IDrugInfoDao + { + + private AppDataConnection _connection; + private readonly SettingConfig _setting; + private readonly ILog logger = LogManager.GetLogger(typeof(DrugInfoDao)); + + public DrugInfoDao(AppDataConnection connection, IOptions setting) + { + _connection = connection; + _setting = setting.Value; + } + public async Task> GetAllDrugAndStock() + { + var query = _connection.DrugInfo.AsQueryable(); + + + return await query + .LoadWith(di => di.Stocks.Where(cs => cs.Quantity > 0 && cs.MachineId == _setting.machineId)) + .InnerJoin( + _connection.ChannelStock.Where(cl => cl.MachineId == _setting.machineId && cl.DrawerType == 1).GroupBy(cl => cl.DrugId), + (di, cl) => di.DrugId == cl.Key, + (di, cl) => di + ) + //.Where(cs => cs.Quantity > 0) + .OrderBy((di) => di.DrugId) + .ToListAsync(); + } + + public async Task> GetAllDrug(string drugId, string drugName, int? take, int? skip) + { + var query = _connection.DrugInfo.AsQueryable(); + + if (!String.IsNullOrEmpty(drugId)) + { + query = query.Where(di => di.DrugId.Contains(drugId)); + } + if (!String.IsNullOrEmpty(drugName)) + { + query = query.Where(di => di.DrugName.Contains(drugName)); + } + + + + int pagedData = await query.CountAsync(); + query = query + .LoadWith(di => di.Manus) + .OrderBy((di) => di.DrugId) + .Skip((int)skip) + .Take((int)take); + + List list = await query + .ToListAsync(); + + return new PageData() + { + TotalDesserts = pagedData, + Desserts = list + }; + } + + public async Task> GetAllDrug() + { + var query = _connection.DrugInfo.AsQueryable(); + + return await query + .LoadWith(di => di.Manus) + .OrderBy((di) => di.DrugId) + .ToListAsync(); + } + + public async Task GetDrugManuNo(string drugId, string manuNo) + { + var query = _connection.DrugManuNo.AsQueryable(); + + return await query.Where(m => m.DrugId.Equals(drugId)) + .Where(m => m.ManuNo.Equals(manuNo)) + .FirstAsync(); + } + + public int AddDrugInfo(DrugInfo drugInfo) + { + return _connection.InsertWithInt32Identity(drugInfo); + } + + public async Task DeleteDrugInfo(string drugId) + { + try + { + logger.Error($"删除药品{drugId}"); + return _connection.DrugInfo.Where(di => di.DrugId == drugId).Delete() > 0; + } + catch (Exception ex) + { + logger.Error("删除药品失败,错误:" + ex.Message); + return false; + } + } + + public async Task UpdateDrugInfo(DrugInfo drugInfo) + { + try + { + var statement = _connection.DrugInfo + .Where(di => di.DrugId == drugInfo.DrugId) + .Set(di => di.DrugName, drugInfo.DrugName) + .Set(di => di.DrugSpec, drugInfo.DrugSpec) + .Set(di => di.Manufactory, drugInfo.Manufactory); + return statement.Update() > 0; + } + catch (Exception ex) + { + logger.Error($"修改药品{drugInfo.DrugId}失败,错误:" + ex.Message); + return false; + } + } + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/DrugManuNoDao.cs b/MasaBlazorApp3/DataAccess/Impl/DrugManuNoDao.cs new file mode 100644 index 0000000..824f9d2 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/DrugManuNoDao.cs @@ -0,0 +1,44 @@ +using LinqToDB; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pages; +using MasaBlazorApp3.Pojo; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class DrugManuNoDao : IDrugManuNoDao + { + private readonly AppDataConnection _connection; + public DrugManuNoDao(AppDataConnection connection) + { + _connection = connection; + } + public int AddDrugManuNo(DrugManuNo drugManuNo) + { + if(drugManuNo!=null&& drugManuNo.EffDate!=null) + { + drugManuNo.EffDate= drugManuNo.EffDate.ToString().Length>10 ?new DateTime(drugManuNo.EffDate.Value.Year, drugManuNo.EffDate.Value.Month, drugManuNo.EffDate.Value.Day) : drugManuNo.EffDate; + } + return _connection.InsertWithInt32Identity(drugManuNo); + } + + public bool DeleteDrugManuNo(string id) + { + return _connection.DrugManuNo.Where(dm => dm.Id == id).Delete() > 0; + } + + public bool UpdateDrugManuNo(DrugManuNo drugManuNo) + { + var statement = _connection.DrugManuNo + .Where(dm => dm.Id == drugManuNo.Id) + .Set(dm => dm.ManuNo, drugManuNo.ManuNo) + .Set(dm => dm.EffDate, drugManuNo.EffDate); + return statement.Update() > 0; + } + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/InOutInvoiceDao.cs b/MasaBlazorApp3/DataAccess/Impl/InOutInvoiceDao.cs new file mode 100644 index 0000000..c72b3b0 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/InOutInvoiceDao.cs @@ -0,0 +1,510 @@ +using LinqToDB; +using log4net; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pages; +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Config; +using MasaBlazorApp3.Pojo.Vo; +using MasaBlazorApp3.Port; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class InOutInvoiceDao : IInOutInvoiceDao + { + private AppDataConnection _connection; + private readonly SettingConfig _setting; + private readonly ILog logger = LogManager.GetLogger(typeof(InOutInvoiceDao)); + private GlobalStateService _globalStateService; + private readonly PortUtil _portUtil; + + public InOutInvoiceDao(AppDataConnection connection, IOptions setting, GlobalStateService globalStateService, PortUtil portUtil) + { + _connection = connection; + _setting = setting.Value; + _globalStateService = globalStateService; + _portUtil = portUtil; + } + public async Task> GetAllInvoiceByType(string invoiceNo, DateTime invoiceDate, int? take, int? skip, int type = 1) + { + var query2 = from cl in _connection.ChannelList.Where(c => c.MachineId == _setting.machineId) + group cl by cl.DrugId into temp + select new { temp.Key }; + var query3 = from ioi in _connection.InOutInvoice + from od in query2.InnerJoin(od => od.Key == ioi.DrugId) + group ioi by ioi.InvoiceNo into temp + select new InOutInvoice{ + InvoiceNo= temp.First().InvoiceNo, + InPharmacyId = temp.First().InPharmacyId, + OutPharmacyId = temp.First().OutPharmacyId, + InvoiceDate = temp.First().InvoiceDate, + CreateTime = temp.First().CreateTime, + Type = temp.First().Type, + CancelFlag = temp.First().CancelFlag, + Status = temp.First().Status, + }; + + + + //var query = _connection.FromSql($@" + // SELECT ioi.invoice_no,ioi.in_pharmacy_id, ioi.out_pharmacy_id, ioi.invoice_date, ioi.create_time, ioi.type, ioi.cancel_flag, ioi.status FROM in_out_invoice ioi + // INNER JOIN (SELECT drug_id FROM channel_list WHERE machine_id = ""{_setting.machineId}"" GROUP BY drug_id) c ON c.drug_id = ioi.drug_id + // GROUP BY ioi.invoice_no"); + + if (!String.IsNullOrEmpty(invoiceNo)) + { + //query = query.Where(ioi => ioi.InvoiceNo.Contains(invoiceNo)); + query3 = query3.Where(ioi => ioi.InvoiceNo.Contains(invoiceNo)); + } + if(invoiceDate != DateTime.MinValue) + { + //query = query.Where(ioi => ioi.CreateTime.Date.Equals(invoiceDate.Date)); + query3 = query3.Where(ioi => ioi.InvoiceNo.Contains(invoiceNo)); + } + + if(!String.IsNullOrEmpty(_setting.storage)) + { + if (type == 1) + { + //query = query.Where(ioi => ioi.OutPharmacyId.Equals(_setting.storage)); + query3 = query3.Where(ioi => ioi.OutPharmacyId.Equals(_setting.storage)); + } + // 调拨出库 + else if (type == 2) + { + //query = query.Where(ioi => ioi.InPharmacyId.Equals(_setting.storage)); + query3 = query3.Where(ioi => ioi.OutPharmacyId.Equals(_setting.storage)); + } + + } + // 调拨入库 + if (type == 1) + { + //query = query.Where(ioi => (ioi.Type == 0 && ioi.Status == 2) || (ioi.Type == 1 && ioi.Status == 0)); + query3 = query3.Where(ioi => (ioi.Type == 0 && ioi.Status == 2) || (ioi.Type == 1 && ioi.Status == 0)); + } + // 调拨出库 + else if (type == 2) + { + //query = query.Where(ioi => new int[] { 0, 2 }.Contains(ioi.Type) && ioi.Status == 0); + query3 = query3.Where(ioi => new int[] { 0, 2 }.Contains(ioi.Type) && ioi.Status == 0); + } + //query = query.Where(ioi => ioi.CancelFlag == 0); + //query = query.Select(ioi => new InOutInvoice() + //{ + // InPharmacyId = ioi.InPharmacyId, + // OutPharmacyId = ioi.OutPharmacyId, + // InvoiceDate = ioi.InvoiceDate, + // InvoiceNo = ioi.InvoiceNo, + // CreateTime = ioi.CreateTime, + // Type = ioi.Type, + // Status = ioi.Status, + // CancelFlag = ioi.CancelFlag, + //}); + + query3 = query3.Where(ioi => ioi.CancelFlag == 0); + List list = await query3 + .OrderByDescending(ioi => ioi.CreateTime) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + + int pagedData = await query3.CountAsync(); + return new PageData() + { + + TotalDesserts = pagedData, + Desserts = list + }; + + } + public async Task GetDrugManuNo(string drugId, string manuNo) + { + var query = _connection.DrugManuNo.AsQueryable(); + + return await query.Where(m => m.DrugId.Equals(drugId)) + .Where(m => m.ManuNo.Equals(manuNo)) + .FirstAsync(); + } + + public async Task> GetChannelStockByDrugId(string DrugId, string manuNo, int quantity = 0) + { + var query = _connection.ChannelStock.AsQueryable(); + + + query = query.Where(cs => cs.MachineId.Equals(_setting.machineId)).Where(cs => cs.DrawerType == 1).Where(cs => cs.DrugId.Equals(DrugId)); + + + if (quantity > 0) + { + query = query.Where(cs => cs.Quantity > 0); + if (!String.IsNullOrEmpty(manuNo)) + { + query = query.Where(cs => cs.ManuNo.Equals(manuNo)); + } + } else + { + if (!String.IsNullOrEmpty(manuNo)) + { + query = query.Where(cs => cs.ManuNo.Equals(manuNo) || String.IsNullOrEmpty(cs.ManuNo) || cs.Quantity == 0); + } + } + + return await query.OrderBy((cs) => cs.EffDate) + .ThenBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + } + + public async Task> getInvoiceByInvoiceNo(string invoiceNo) + { + var query = _connection.InOutInvoice.AsQueryable(); + + query = query.InnerJoin( + _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.machineId)).GroupBy(cs => cs.DrugId).Select(cs => cs.Key), + (ioi, key) => key == ioi.DrugId, + (ioi, key) => ioi) + .Where(ioi => ioi.InvoiceNo.Equals(invoiceNo)) + .OrderBy(ioi => ioi.DrugId); + return await query.ToListAsync(); + } + + public async Task getDrugInfoById(string DrugId) + { + return await _connection.DrugInfo.Where(di => di.DrugId == DrugId).FirstOrDefaultAsync(); + } + + + public async Task> getTakeInfoByInvoiceNo(string invoiceNo) + { + List tempData = new(); + var flag = true; + List details = await this.getInvoiceByInvoiceNo(invoiceNo); + for (var i = 0; i < details.Count; i++) + { + //List> tempData = new(); + InOutInvoice detail = details[i]; + + DrugInfo Drug = await this.getDrugInfoById(detail.DrugId); + // 当前detail取药数量 + var Quantity = detail.quantity; + List stockList = await this.GetChannelStockByDrugId(detail.DrugId, detail.DrugManuNo, Quantity); + + // 当前药品的库存总量 + var total = stockList.Sum(cs => cs.Quantity); + + if (flag) + { + // 盘点库存是否足够 + if (total >= Quantity) + { + + for (var j = 0; Quantity > 0; j++) + { + ChannelStock stock = stockList[j]; + if (Quantity > stock.Quantity) + { + // 取药数量大于库存 + stock.TakeQuantity = stock.Quantity; + Quantity -= stock.Quantity; + } + else + { + //取药数量小于库存 + stock.TakeQuantity = Quantity; + Quantity = 0; + } + } + } + else + { + // 库存不足 + flag = false; + } + } + tempData.Add(new InvoiceVo() + { + Drug = Drug, + Invoice = detail, + StockQuantity = total, + Quantity = detail.quantity, + ChannelStocks = stockList, + }); + } + return tempData; + } + + public async Task> getAddInfoByInvoiceNo(string invoiceNo) + { + List tempData = new(); + List details = await this.getInvoiceByInvoiceNo(invoiceNo); + for (var i = 0; i < details.Count; i++) + { + //List> tempData = new(); + InOutInvoice detail = details[i]; + List stockList = await this.GetChannelStockByDrugId(detail.DrugId, detail.DrugManuNo); + + DrugInfo Drug = await this.getDrugInfoById(detail.DrugId); + + // 当前药品的库存总量 + var total = stockList.Aggregate(0, (current, next) => current + next.Quantity); + // 当前detail加药数量 + var Quantity = detail.quantity; + + stockList.First().AddQuantity = Quantity; + + tempData.Add(new InvoiceVo() + { + Drug = Drug, + Invoice = detail, + StockQuantity = total, + Quantity = Quantity, + ChannelStocks = stockList, + }); + + } + return tempData; + } + + public async Task InvoiceOutFinish(List datas) + { + try + { + _connection.BeginTransaction(); + var flag = true; + // 更新处方状态 + int r1 = _connection.InOutInvoice.Where(oi => oi.InvoiceNo == datas.First().Invoice.InvoiceNo) + .Set(oi => oi.Status, 2) + .Update(); + if (!(r1 > 0)) + { + flag = false; + logger.Error("调拨取药完成更新状态失败"); + _connection.RollbackTransaction(); + return flag; + } + for (var i = 0; i < datas.Count; i++) + { + var invoiceVo = datas[i]; + + List stocks = invoiceVo.ChannelStocks.Where(cs => cs.TakeQuantity > 0).ToList(); + + for (var j = 0; j < stocks.Count; j++) + { + var ChannelStock = stocks[j]; + // 出库记录 + int mid = _connection.InsertWithInt32Identity(new MachineRecord() + { + MachineId = _setting.machineId, + DrawerNo = ChannelStock.DrawerNo, + ColNo = ChannelStock.ColNo, + DrugId = ChannelStock.DrugId, + ManuNo = ChannelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(ChannelStock.EffDate) ? DateTime.ParseExact(ChannelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 2, + Quantity = ChannelStock.TakeQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + InvoiceId = invoiceVo.Invoice.InvoiceNo, + }); + // 更新库存 + int r = _connection.ChannelStock.Where(cs => cs.Id == ChannelStock.Id) + .Set(cs => cs.Quantity, ChannelStock.Quantity - ChannelStock.TakeQuantity) + .Update(); + // 获取更新完库存之后的药品库存 + List list = await _connection.ChannelStock.AsQueryable() + .InnerJoin( + _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1), + (cs, cl) => cs.ListId == cl.Id, + (cs, cl) => cs + ) + .Where(cs => cs.DrugId.Equals(ChannelStock.DrugId)) + .ToListAsync(); + // 保存账册 + int acid = _connection.InsertWithInt32Identity(new AccountBook() + { + MachineId = _setting.machineId, + DrugId = ChannelStock.DrugId, + ManuNo = ChannelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(ChannelStock.EffDate) ? DateTime.ParseExact(ChannelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 2, + OutQuantity = ChannelStock.TakeQuantity, + AddQuantity = 0, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + ManuStock = list.Where(it => it.ManuNo == ChannelStock.ManuNo).Sum(it => it.Quantity), + TotalStock = list.Sum(it => it.Quantity), + InvoiceId = invoiceVo.Invoice.InvoiceNo + }); + if (mid > 0 && r > 0 && acid > 0) + { + //根据抽屉类型判断是否需要写标签 + if (ChannelStock.BoardType.ToString().Contains("5")) + { + await _portUtil.WriteQuantityMethod(ChannelStock.Quantity- ChannelStock.TakeQuantity, ChannelStock.DrawerNo, ChannelStock.ColNo); + } + } + else + { + flag = false; + break; + } + } + + if (!flag) + { + break; + } + + } + if (flag) + { + _connection.CommitTransaction(); + } + else + { + _connection.RollbackTransaction(); + } + return flag; + + } + catch (Exception ex) + { + logger.Error("调拨取药完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + + public async Task InvoiceAddFinish(List datas) + { + + try + { + _connection.BeginTransaction(); + var flag = true; + // 更新调拨单状态 + int r1 = _connection.InOutInvoice.Where(oi => oi.InvoiceNo == datas.First().Invoice.InvoiceNo) + .Set(oi => oi.Status, 4) + .Update(); + if (!(r1 > 0)) + { + flag = false; + logger.Error("调拨加药完成更新状态失败"); + _connection.RollbackTransaction(); + return flag; + } + for (var i = 0; i < datas.Count; i++) + { + var invoiceVo = datas[i]; + + List stocks = invoiceVo.ChannelStocks.Where(cs => cs.AddQuantity > 0).ToList(); + + for (var j = 0; j < stocks.Count; j++) + { + var ChannelStock = stocks[j]; + + // 更新库存 + var q = _connection.ChannelStock.Where(cs => cs.Id == ChannelStock.Id) + .Set(cs => cs.Quantity, ChannelStock.Quantity + ChannelStock.AddQuantity); + if (String.IsNullOrEmpty(ChannelStock.ManuNo) || (ChannelStock.Quantity == 0 && !ChannelStock.ManuNo.Equals(invoiceVo.Invoice.DrugManuNo))) + { + DrugManuNo drugManuNo = await GetDrugManuNo(ChannelStock.DrugId, invoiceVo.Invoice.DrugManuNo); + + ChannelStock.Dmnguid = drugManuNo.Id; + ChannelStock.ManuNo = drugManuNo.ManuNo; + ChannelStock.EffDate = drugManuNo.EffDate.ToString(); + + q = q.Set(cs => cs.Dmnguid, drugManuNo.Id) + .Set(cs => cs.ManuNo, drugManuNo.ManuNo) + .Set(cs => cs.EffDate, drugManuNo.EffDate.ToString()); + } + int r = q.Update(); + // 入库记录 + int mid = _connection.InsertWithInt32Identity(new MachineRecord() + { + MachineId = _setting.machineId, + DrawerNo = ChannelStock.DrawerNo, + ColNo = ChannelStock.ColNo, + DrugId = ChannelStock.DrugId, + ManuNo = ChannelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(ChannelStock.EffDate) ? DateTime.ParseExact(ChannelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 1, + Quantity = ChannelStock.AddQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + InvoiceId = invoiceVo.Invoice.InvoiceNo, + }); + + // 获取更新完库存之后的药品库存 + List list = await _connection.ChannelStock.AsQueryable() + .Where(cs => cs.MachineId.Equals(_setting.machineId)) + .Where(cs => cs.DrawerType == 1) + .Where(cs => cs.DrugId.Equals(ChannelStock.DrugId)) + .ToListAsync(); + // 保存账册 + int acid = _connection.InsertWithInt32Identity(new AccountBook() + { + MachineId = _setting.machineId, + DrugId = ChannelStock.DrugId, + ManuNo = ChannelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(ChannelStock.EffDate) ? DateTime.ParseExact(ChannelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 1, + OutQuantity = 0, + AddQuantity = ChannelStock.AddQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + ManuStock = list.Where(it => it.ManuNo == ChannelStock.ManuNo).Sum(it => it.Quantity), + TotalStock = list.Sum(it => it.Quantity), + InvoiceId = invoiceVo.Invoice.InvoiceNo + }); + if (mid > 0 && r > 0 && acid > 0) + { + //根据抽屉类型判断是否需要写标签 + if (ChannelStock.BoardType.ToString().Contains("5")) + { + await _portUtil.WriteQuantityMethod(ChannelStock.Quantity - ChannelStock.TakeQuantity, ChannelStock.DrawerNo, ChannelStock.ColNo); + } + } + else + { + flag = false; + break; + } + } + if(!flag) + { + break; + } + + } + if (flag) + { + _connection.CommitTransaction(); + } + else + { + _connection.RollbackTransaction(); + } + return flag; + + } + catch (Exception ex) + { + logger.Error("调拨加药完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/MachineRecordDao.cs b/MasaBlazorApp3/DataAccess/Impl/MachineRecordDao.cs new file mode 100644 index 0000000..cc63a53 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/MachineRecordDao.cs @@ -0,0 +1,406 @@ +using LinqToDB; +using log4net; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pages; +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Config; +using MasaBlazorApp3.Pojo.Vo; +using MasaBlazorApp3.Port; +using Microsoft.Extensions.Options; +using Mysqlx.Crud; +using static LinqToDB.Common.Configuration; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class MachineRecordDao : IMachineRecordDao + { + + private readonly AppDataConnection _connection; + private readonly SettingConfig _setting; + private readonly ILog logger = LogManager.GetLogger(typeof(MachineRecordDao)); + private readonly PortUtil _portUtil; + + //public UserDao(MyContext context) + //{ + // Context = context; + //} + public MachineRecordDao(AppDataConnection connection, IOptions setting, PortUtil portUtil) + { + _connection = connection; + _setting = setting.Value; + _portUtil = portUtil; + } + + public async Task> GetChannelStockByDrugId(string DrugId, String ManuNo) + { + var query = _connection.ChannelStock.AsQueryable(); + + + query = query.Where(cs => cs.MachineId.Equals(_setting.machineId)).Where(cs => cs.DrawerType == 1) + .Where(cs => cs.Quantity > 0) + .Where(cs => cs.DrugId.Equals(DrugId)) + .Where(cs => cs.ManuNo.Equals(ManuNo)); + + + return await query.OrderBy((cs) => cs.EffDate) + .ThenBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + } + //还药时有库位即可,不需要库存大于0的条件 + public async Task> GetChannelStockByDrugIdForReturn(string DrugId, String ManuNo) + { + var query = _connection.ChannelStock.AsQueryable(); + + + query = query.Where(cs => cs.MachineId.Equals(_setting.machineId)).Where(cs => cs.DrawerType == 1) + //.Where(cs => cs.Quantity > 0) + .Where(cs => cs.DrugId.Equals(DrugId)) + .Where(cs => cs.ManuNo.Equals(ManuNo)); + + + return await query.OrderBy((cs) => cs.EffDate) + .ThenBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + } + + public async Task> GetCanReturnRecords(DateTime start, DateTime end, int operatorId, string drugId, int? take, int? skip) + { + var query = _connection.MachineRecord.AsQueryable().Where(it => it.MachineId.Equals(_setting.machineId)); + if (start != null && start != DateTime.MinValue) + { + query = query.Where(mr => mr.OperationTime > start); + } + if (end != null && end != DateTime.MinValue) + { + query = query.Where(mr => mr.OperationTime < end); + } + if (operatorId != 0) + { + query = query.Where(mr => mr.Operator == operatorId); + } + query = query.Where(mr => mr.Type == 2); + query = query.Where(mr => mr.Status < 2); + if (!String.IsNullOrEmpty(drugId)) + { + query = query.Where(mr => mr.DrugId == drugId); + } + int pagedData = await query.CountAsync(); + List MachineRecords = await query.LoadWith(mr => mr.Drug) + .LoadWith(mr => mr.OperatorUser) + .OrderByDescending(mr => mr.OperationTime) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + + return new PageData() { Desserts = MachineRecords, TotalDesserts = pagedData }; + } + + public async Task> GetMachineRecordAsync(DateTime start, DateTime end, int operatorId, string drugId, int type, int? take, int? skip) + { + var query = _connection.MachineRecord.AsQueryable().Where(it => it.MachineId.Equals(_setting.machineId)); + if (start != null && start != DateTime.MinValue) + { + query = query.Where(mr => mr.OperationTime > start); + } + if (end != null && end != DateTime.MinValue) + { + query = query.Where(mr => mr.OperationTime < end); + } + if (operatorId != 0) + { + query = query.Where(mr => mr.Operator == operatorId); + } + if (type != 0) + { + query = query.Where(mr => mr.Type == type); + } + if (!String.IsNullOrEmpty(drugId)) + { + query = query.Where(mr => mr.DrugId == drugId); + } + int pagedData = await query.CountAsync(); + List MachineRecords = await query.LoadWith(mr => mr.Drug) + .LoadWith(mr => mr.OperatorUser) + .OrderByDescending(mr => mr.OperationTime) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + + return new PageData() { Desserts = MachineRecords, TotalDesserts = pagedData }; + + } + + + public int InsertMachineRecord(MachineRecord record) + { + record.MachineId = _setting.machineId; + return _connection.InsertWithInt32Identity(record); + } + public async Task>>> getReturnDrugInfoByRecords(List records) + { + List>> list = new(); + + for (int i = 0; i < records.Count; i++) + { + var record = records[i]; + //var index = list.FindIndex(it => it.Drug.DrugId == record.DrugId && it.data.Count > 0 && it.data.First().ManuNo == record.ManuNo); + var index = list.FindIndex(it => it.Drug.DrugId == record.DrugId && it.data.First().ManuNo == record.ManuNo); + if (index > -1) + { + list[index].Quantity += record.CurrentReturnQuantity; + list[index].data.Add(record); + if (list[index].ChannelStocks.Count > 0) + { + list[index].ChannelStocks.First().ReturnQuantity += record.CurrentReturnQuantity; + } + } + else + { + //List stockList = await this.GetChannelStockByDrugId(record.DrugId, record.ManuNo); + List stockList = await this.GetChannelStockByDrugIdForReturn(record.DrugId, record.ManuNo); + // 当前药品的库存总量 + var total = stockList.Sum(current => current.Quantity); + if (stockList.Count > 0) + { + stockList.First().ReturnQuantity = record.CurrentReturnQuantity; + } + list.Add(new OperationVo>() + { + Drug = record.Drug, + ChannelStocks = stockList, + data = new List { record }, + Quantity = record.CurrentReturnQuantity, + StockQuantity = total, + }); + } + + + } + return list; + } + + public async Task ReturnDrugFinish(List>> datas) + { + //throw new NotImplementedException(); + //还药完成 + try + { + _connection.BeginTransaction(); + if (datas.Count > 0) + { + datas = datas.Select(it => + { + it.ChannelStocks = it.ChannelStocks.Where(cs => cs.ReturnQuantity > 0).ToList(); + return it; + }).ToList(); + if (datas.Count > 0) + { + foreach (var data in datas) + { + int sumQuantity = data.data.Sum(mr => mr.CurrentReturnQuantity); + //更新 库存 + foreach (ChannelStock record in data.ChannelStocks) + { + record.Quantity = record.Quantity + record.ReturnQuantity; + record.Id = record.Id; + _connection.Update(record); + + // 保存数据 还药记录 + int acid = _connection.InsertWithInt32Identity(new MachineRecord() + { + MachineId = record.MachineId, + DrawerNo = record.DrawerNo, + ColNo = record.ColNo, + DrugId = record.DrugId, + ManuNo = record.ManuNo, + EffDate = !String.IsNullOrEmpty(record.EffDate) ? DateTime.ParseExact(record.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + Operator = data.data.First().Operator, + OperationTime = DateTime.Now, + Quantity = record.ReturnQuantity, + Type = 31, + InvoiceId = data.data.First().InvoiceId, + GetId = data.data.First().GetId + }); + //称重计数或称重+智能显示+管控药盒 类型需要 发26指令 + if (record.BoardType == 5 || record.BoardType == 6) + { + //计数数量设置,发送称重26指令 + _portUtil.SetNumCount(record.DrawerNo, record.ColNo, record.ReturnQuantity); + Thread.Sleep(80); + } + + } + // 更新 取药记录 设置还药数量、状态 + foreach (MachineRecord record in data.data) + { + record.ReturnQuantity1 = record.ReturnQuantity1 + record.CurrentReturnQuantity; + record.Id = record.Id; + record.Status = (record.Quantity - (record.ReturnQuantity1 + record.ReturnQuantity2 + sumQuantity)) == 0 ? 2 : 1; + _connection.Update(record); + } + + } + _connection.CommitTransaction(); + } + } + else + { + _connection.RollbackTransaction(); + return false; + } + return true; + } + catch (Exception ex) + { + logger.Error("还药完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + + + #region 还空瓶 + public async Task> GetReturnEmpty() + { + List channelStocks = new(); + var query = _connection.ChannelStock.AsQueryable().Where(it => it.MachineId == _setting.machineId && it.DrawerType == 2); + channelStocks= await query.LoadWith(cs => cs.Drug).ToListAsync(); + + //获取可归还数量 + return channelStocks; + //if (start != null && start != DateTime.MinValue) + //{ + // query = query.Where(mr => mr.OperationTime > start); + //} + //if (end != null && end != DateTime.MinValue) + //{ + // query = query.Where(mr => mr.OperationTime < end); + //} + //if (operatorId != 0) + //{ + // query = query.Where(mr => mr.Operator == operatorId); + //} + //query = query.Where(mr => mr.Type == 2); + //query = query.Where(mr => mr.Status < 2); + //if (!String.IsNullOrEmpty(drugId)) + //{ + // query = query.Where(mr => mr.DrugId == drugId); + //} + //int pagedData = await query.CountAsync(); + //List MachineRecords = await query.LoadWith(mr => mr.Drug) + // .LoadWith(mr => mr.OperatorUser) + // .OrderByDescending(mr => mr.OperationTime) + // .Skip((int)skip) + // .Take((int)take) + // .ToListAsync(); + + //return new PageData() { Desserts = MachineRecords, TotalDesserts = pagedData }; + } + public async Task> getReturnEmptyInfoByRecords(ChannelStock records) + { + List machineRecords = new(); + int pagedData = 0; + if (records != null && !string.IsNullOrEmpty(records.DrugId)) + { + var query = _connection.MachineRecord.Where(it => it.DrugId == records.DrugId && it.MachineId == _setting.machineId && it.Type == 2 && it.Status != 2).AsQueryable(); + machineRecords = await query.LoadWith(cs => cs.OperatorUser).ToListAsync(); + + pagedData = await query.CountAsync(); + } + return new PageData() { Desserts = machineRecords, TotalDesserts = pagedData }; + + } + public async Task ReturnEmptyFinish(List datas, ChannelStock channelStock) + { + try + { + _connection.BeginTransaction(); + // 更新数据 库存信息 + channelStock.Quantity = channelStock.Quantity+ datas.Sum(it => it.CurrentReturnQuantity); + int iStock = _connection.Update(channelStock); + for (int i = 0; i < datas.Count; i++) + { + MachineRecord _MachineRecord = datas[i]; + _MachineRecord.ReturnQuantity2 = _MachineRecord.ReturnQuantity2+ _MachineRecord.CurrentReturnQuantity; + _MachineRecord.Status = _MachineRecord.ReturnQuantity2 + _MachineRecord.ReturnQuantity1 >= _MachineRecord.Quantity ? 2 : 1; + // 更新数据 取药记录 设置还药数量、状态 + _connection.Update(_MachineRecord); + // 保存数据 还药空瓶记录 + int iMachineRecord = _connection.InsertWithInt32Identity(new MachineRecord() { + MachineId= channelStock.MachineId, + DrawerNo = channelStock.DrawerNo, + ColNo = channelStock.ColNo, + DrugId = channelStock.DrugId, + ManuNo = channelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(channelStock.EffDate) ? DateTime.ParseExact(channelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + Operator = _MachineRecord.Operator, + OperationTime = DateTime.Now, + Quantity = _MachineRecord.CurrentReturnQuantity, + Type = 31, + InvoiceId = _MachineRecord.InvoiceId, + GetId = _MachineRecord.GetId + }); + + ////称重计数或称重+智能显示+管控药盒 类型需要 发26指令 + //if (channelStock.BoardType == 5 || channelStock.BoardType == 6) + //{ + // //计数数量设置,发送称重26指令 + // _portUtil.SetNumCount(channelStock.DrawerNo, channelStock.ColNo, channelStock.ReturnQuantity); + // Thread.Sleep(80); + //} + + + if (channelStock.BoardType.ToString().Contains("5")) + { + await _portUtil.WriteQuantityMethod(channelStock.Quantity + datas.Sum(it => it.CurrentReturnQuantity), channelStock.DrawerNo, channelStock.ColNo); + } + } + // 更新屏显库存 + if (channelStock.BoardType == 5 || channelStock.BoardType == 35) + { + _portUtil.WriteQuantity(channelStock.DrawerNo, channelStock.ColNo, channelStock.Quantity); + } + _connection.CommitTransaction(); + return true; + } + catch (Exception ex) + { + logger.Error("还空瓶完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + public async Task> GetReturnEmptyWithCanReturnQuantiy() + { + List channelStocks = new(); + var queryStock = _connection.ChannelStock.Where(cs => cs.DrawerType == 2 && cs.MachineId == _setting.machineId); + var queryMachineRecord = _connection.MachineRecord.Where(dm => dm.Type == 2 && dm.Status != 2); + var query = from cs in queryStock + join other in queryMachineRecord on cs.DrugId equals other.DrugId + where cs.MachineId==other.MachineId + group other by cs.DrugId into g + select new + { + ChannelStockId = g.Key, + SumValue = g.Sum(x => x.Quantity-x.ReturnQuantity1-x.ReturnQuantity2) + }; + + var results = await query.ToListAsync(); + channelStocks= await queryStock.LoadWith(cs => cs.Drug).ToListAsync(); + foreach (var itemStock in channelStocks) + { + foreach (var itemResult in results) + { + if(itemStock.DrugId==itemResult.ChannelStockId) + { + itemStock.CanReturnQuantity = itemResult.SumValue; + } + } + } + return channelStocks; + } + #endregion + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/OrderInfoDao.cs b/MasaBlazorApp3/DataAccess/Impl/OrderInfoDao.cs new file mode 100644 index 0000000..1a97974 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/OrderInfoDao.cs @@ -0,0 +1,544 @@ +using LinqToDB; +using LinqToDB.SqlQuery; +using log4net; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pages; +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Config; +using MasaBlazorApp3.Pojo.Vo; +using MasaBlazorApp3.Port; +using Microsoft.Extensions.Options; +using Mysqlx.Crud; +using Radzen.Blazor.Rendering; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class OrderInfoDao : IOrderInfoDao + { + + private readonly SettingConfig _setting; + private AppDataConnection _connection; + private GlobalStateService _globalStateService; + private readonly ILog logger = LogManager.GetLogger(typeof(OrderInfoDao)); + private readonly PortUtil _portUtil; + + public OrderInfoDao(AppDataConnection connection, IOptions setting, GlobalStateService globalStateService,PortUtil portUtil) + { + _connection = connection; + _setting = setting.Value; + _globalStateService = globalStateService; + _portUtil = portUtil; + } + + public async Task> GetAllOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip) + { + //var query = _connection.OrderInfo.AsQueryable(); + + //query.InnerJoin((oi, od) => oi.OrderNo == od.OrderNo); + + var query2 = from od in _connection.OrderDetail + from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.machineId).InnerJoin(c => c.DrugId == od.DrugId) + group od by od.OrderNo into temp + select new { temp.Key }; + var query = from oi in _connection.OrderInfo + from od in query2.InnerJoin(od => od.Key == oi.OrderNo) + select oi; + + if (!String.IsNullOrEmpty(OrderrNo)) + { + query = query.Where(oi => oi.OrderNo.Equals(OrderrNo)); + } + if(OrderDate !=null && OrderDate!= DateTime.MinValue) + { + query = query.Where(oi => oi.OrderDate.Date.Equals(OrderDate.Date)); + } + + query = query.Where(oi => oi.Status == 0); + query = query.Where(oi => oi.HisDispFlag == 0); + query = query.Where(oi => oi.CancelFlag == 0); + + + int pagedData = await query.CountAsync(); + + List list = await query + .OrderBy((oi) => oi.RecvDate) + .ThenBy((oi => oi.OrderNo)) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + + + return new PageData() + { + TotalDesserts = pagedData, + Desserts = list + }; + } + + public async Task> getDetailByOrderNo(string OrderrNo) + { + var query2 = from cl in _connection.ChannelStock + where cl.MachineId == _setting.machineId + group cl by cl.DrugId into temp + select new { temp.Key }; + ; + + + var query = from od in _connection.OrderDetail.Where(od => od.OrderNo == OrderrNo) + from cl in query2.InnerJoin(c => c.Key == od.DrugId) + orderby od.DrugId + select od; + + query = query.LoadWith(od => od.Drug); + + return await query.ToListAsync(); + } + + public async Task> GetChannelStockByDrugId(string DrugId, String ManuNo, int quantity = 0) + { + var query = _connection.ChannelStock.AsQueryable(); + + + query = query.Where(cs => cs.MachineId.Equals(_setting.machineId)).Where(cs => cs.DrawerType == 1) + .Where(cs => cs.Quantity > 0) + .Where(cs => cs.DrugId.Equals(DrugId)); + + if (quantity > 0) + { + if (!String.IsNullOrEmpty(ManuNo)) + { + query = query.Where(cs => cs.ManuNo.Equals(ManuNo)); + } + } else + { + if (!String.IsNullOrEmpty(ManuNo)) + { + query = query.Where(cs => cs.ManuNo.Equals(ManuNo) || cs.Quantity == 0); + } + } + + + return await query.OrderBy((cs) => cs.EffDate) + .ThenBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + } + + public async Task> getTakeInfoByOrderNo(string OrderrNo) + { + List tempData = new(); + List tempData2 = new(); + List details = await this.getDetailByOrderNo(OrderrNo); + var flag = true; + for (var i = 0; i < details.Count; i++) + { + //List> tempData = new(); + OrderDetail detail = details[i]; + // 当前detail取药数量 + var Quantity = detail.Quantity; + List stockList = await this.GetChannelStockByDrugId(detail.DrugId, detail.SetManuNo, Quantity); + + // 当前药品的库存总量 + var total = stockList.Sum(current => current.Quantity); + + tempData2.Add(new OrderTakeVo() + { + Drug = detail.Drug, + OrderDetail = detail, + StockQuantity = total, + Quantity = Quantity + }); + + if (flag) + { + // 盘点库存是否足够 + if (total > Quantity) + { + + for (var j = 0; Quantity > 0; j++) + { + ChannelStock stock = stockList[j]; + if (Quantity > stock.Quantity) + { + // 取药数量大于库存 + tempData.Add(new OrderTakeVo() + { + Drug = detail.Drug, + OrderDetail = detail, + ChannelStock = stock, + StockQuantity = total, + Quantity = stock.Quantity, + }); + Quantity -= stock.Quantity; + } + else + { + //取药数量小于库存 + tempData.Add(new OrderTakeVo() + { + Drug = detail.Drug, + OrderDetail = detail, + ChannelStock = stock, + StockQuantity = total, + Quantity = Quantity, + }); + Quantity = 0; + } + } + } + else + { + // 库存不足 + flag = false; + } + } + + } + if (flag) + { + return tempData; + } + else + { + return tempData2; + } + } + + public async Task OrderTakeFinish(List datas) + { + + try + { + _connection.BeginTransaction(); + var flag = true; + // 更新处方状态 + int r1 = _connection.OrderInfo.Where(oi => oi.OrderNo == datas.First().OrderDetail.OrderNo) + .Set(oi => oi.Status, 1) + .Update(); + if (!(r1 > 0)) + { + flag = false; + logger.Error("处方取药完成更新处方状态失败"); + _connection.RollbackTransaction(); + return flag; + } + for (var i = 0; i < datas.Count; i++) + { + var orderTakeVo = datas[i]; + // 出库记录 + int mid = _connection.InsertWithInt32Identity(new MachineRecord() + { + MachineId = _setting.machineId, + DrawerNo = orderTakeVo.ChannelStock.DrawerNo, + ColNo = orderTakeVo.ChannelStock.ColNo, + DrugId = orderTakeVo.ChannelStock.DrugId, + ManuNo = orderTakeVo.ChannelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(orderTakeVo.ChannelStock.EffDate) ? DateTime.ParseExact(orderTakeVo.ChannelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 2, + Quantity = orderTakeVo.GetQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + InvoiceId = orderTakeVo.OrderDetail.Id.ToString(), + }); + // 更新库存 + int r = _connection.ChannelStock.Where(cs => cs.Id == orderTakeVo.ChannelStock.Id) + .Set(cs => cs.Quantity, orderTakeVo.ChannelStock.Quantity - orderTakeVo.GetQuantity) + .Update(); + // 获取更新完库存之后的药品库存 + List list = await _connection.ChannelStock.AsQueryable() + .InnerJoin( + _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1), + (cs, cl) => cs.ListId == cl.Id, + (cs, cl) => cs + ) + .Where(cs => cs.DrugId.Equals(orderTakeVo.ChannelStock.DrugId)) + .ToListAsync(); + // 保存账册 + int acid = _connection.InsertWithInt32Identity(new AccountBook() + { + MachineId = _setting.machineId, + DrugId = orderTakeVo.ChannelStock.DrugId, + ManuNo = orderTakeVo.ChannelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(orderTakeVo.ChannelStock.EffDate) ? DateTime.ParseExact(orderTakeVo.ChannelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 2, + OutQuantity = orderTakeVo.GetQuantity, + AddQuantity = 0, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + ManuStock = list.Where(it => it.ManuNo == orderTakeVo.ChannelStock.ManuNo).Sum(it => it.Quantity), + TotalStock = list.Sum(it => it.Quantity), + InvoiceId = orderTakeVo.OrderDetail.Id.ToString() + }); + if (mid > 0 && r > 0 && acid > 0) + { + if (orderTakeVo.ChannelStock.BoardType.ToString().Contains("5")) + { + await _portUtil.WriteQuantityMethod(orderTakeVo.ChannelStock.Quantity - orderTakeVo.GetQuantity, orderTakeVo.ChannelStock.DrawerNo, orderTakeVo.ChannelStock.ColNo); + } + + } + else + { + flag = false; + break; + } + } + if (flag) + { + _connection.CommitTransaction(); + } + else + { + _connection.RollbackTransaction(); + } + return flag; + + } + catch (Exception ex) + { + logger.Error("处方取药完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + + public async Task> GetAllCanReturnOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip) + { + var query2 = from od in _connection.OrderDetail + from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.machineId).InnerJoin(c => c.DrugId == od.DrugId) + group od by od.OrderNo into temp + select new { temp.Key }; + var query = from oi in _connection.OrderInfo + from od in query2.InnerJoin(od => od.Key == oi.OrderNo) + select oi; + + if (!String.IsNullOrEmpty(OrderrNo)) + { + query = query.Where(oi => oi.OrderNo.Equals(OrderrNo)); + } + if (OrderDate != null && OrderDate != DateTime.MinValue) + { + query = query.Where(oi => oi.OrderDate.Date.Equals(OrderDate.Date)); + } + + query = query.Where(oi => oi.Status == 1); + query = query.Where(oi => oi.CancelFlag == 1); + + + int pagedData = await query.CountAsync(); + + List list = await query + .OrderBy((oi) => oi.RecvDate) + .ThenBy((oi => oi.OrderNo)) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + + + return new PageData() + { + TotalDesserts = pagedData, + Desserts = list + }; + } + + public async Task> GetMachineRecordByOrderNo(string OrderrNo) + { + var query = _connection.MachineRecord.AsQueryable(); + query = query.InnerJoin( + _connection.OrderDetail.Where(od => od.OrderNo.Equals(OrderrNo)), + (mr, od) => mr.InvoiceId.Equals(od.Id), + (mr, od) => mr + ) + .Where(md => md.Type == 2) + .LoadWith(md => md.Drug) + ; + return await query.ToListAsync(); + } + + public async Task>> getReturnInfoByOrderNo(string OrderrNo) + { + List> tempData = new(); + List details = await this.GetMachineRecordByOrderNo(OrderrNo); + for (var i = 0; i < details.Count; i++) + { + //List> tempData = new(); + MachineRecord detail = details[i]; + List stockList = await this.GetChannelStockByDrugId(detail.DrugId, detail.ManuNo); + + + // 当前药品的库存总量 + var total = stockList.Sum(current => current.Quantity); + // 当前detail出库数量 + var Quantity = detail.Quantity; + + stockList.First().AddQuantity = Quantity; + + tempData.Add(new OperationVo() + { + Drug = detail.Drug, + data = detail, + StockQuantity = total, + Quantity = Quantity, + ChannelStocks = stockList, + }); + + } + return tempData; + } + + public async Task GetDrugManuNo(string drugId, string manuNo) + { + var query = _connection.DrugManuNo.AsQueryable(); + + return await query.Where(m => m.DrugId.Equals(drugId)) + .Where(m => m.ManuNo.Equals(manuNo)) + .FirstAsync(); + } + + public async Task OrderReturnFinish(List> datas, string OrderNo) + { + try + { + _connection.BeginTransaction(); + var flag = true; + // 更新处方状态 + int r1 = _connection.OrderInfo.Where(oi => oi.OrderNo == OrderNo) + .Set(oi => oi.Status, 0) + .Update(); + if (!(r1 > 0)) + { + flag = false; + logger.Error("处方取药完成更新处方状态失败"); + _connection.RollbackTransaction(); + return flag; + } + for (var i = 0; i < datas.Count; i++) + { + var operationVo = datas[i]; + + List stocks = operationVo.ChannelStocks.Where(cs => cs.ReturnQuantity > 0).ToList(); + + // 更新取出记录状态 + var r2 = _connection.MachineRecord.Where(cs => cs.Id == operationVo.data.Id) + .Set(cs => cs.Status, 2) + .Set(cs => cs.ReturnQuantity1, operationVo.data.Quantity).Update(); + + if(r2 > 0) + { + + } else + { + flag = false; + break; + } + + for (var j = 0; j < stocks.Count; j++) + { + var channelStock = stocks[j]; + + // 更新库存 + var q = _connection.ChannelStock.Where(cs => cs.Id == channelStock.Id) + .Set(cs => cs.Quantity, channelStock.Quantity + channelStock.ReturnQuantity); + if (String.IsNullOrEmpty(channelStock.ManuNo) || (channelStock.Quantity == 0 && !channelStock.ManuNo.Equals(operationVo.data.ManuNo))) + { + DrugManuNo drugManuNo = await GetDrugManuNo(channelStock.DrugId, operationVo.data.ManuNo); + + channelStock.Dmnguid = drugManuNo.Id; + channelStock.ManuNo = drugManuNo.ManuNo; + channelStock.EffDate = drugManuNo.EffDate.ToString(); + + q = q.Set(cs => cs.Dmnguid, drugManuNo.Id) + .Set(cs => cs.ManuNo, drugManuNo.ManuNo) + .Set(cs => cs.EffDate, drugManuNo.EffDate.ToString()); + } + int r = q.Update(); + // 退回记录 + int mid = _connection.InsertWithInt32Identity(new MachineRecord() + { + MachineId = _setting.machineId, + DrawerNo = channelStock.DrawerNo, + ColNo = channelStock.ColNo, + DrugId = channelStock.DrugId, + ManuNo = channelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(channelStock.EffDate) ? DateTime.ParseExact(channelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 31, + Quantity = channelStock.ReturnQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + InvoiceId = operationVo.data.InvoiceId.ToString(), + GetId = operationVo.data.Id + }); + + // 获取更新完库存之后的药品库存 + List list = await _connection.ChannelStock.AsQueryable() + .InnerJoin( + _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1), + (cs, cl) => cs.ListId == cl.Id, + (cs, cl) => cs + ) + .Where(cs => cs.DrugId.Equals(channelStock.DrugId)) + .ToListAsync(); + // 保存账册 + int acid = _connection.InsertWithInt32Identity(new AccountBook() + { + MachineId = _setting.machineId, + DrugId = channelStock.DrugId, + ManuNo = channelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(channelStock.EffDate) ? DateTime.ParseExact(channelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 2, + OutQuantity = channelStock.ReturnQuantity, + AddQuantity = 0, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + ManuStock = list.Where(it => it.ManuNo == channelStock.ManuNo).Sum(it => it.Quantity), + TotalStock = list.Sum(it => it.Quantity), + InvoiceId = operationVo.data.InvoiceId + }); + if (mid > 0 && r > 0 && acid > 0) + { + if(channelStock.BoardType.ToString().Contains("5")) + { + await _portUtil.WriteQuantityMethod(channelStock.Quantity - channelStock.ReturnQuantity, channelStock.DrawerNo, channelStock.ColNo); + } + } + else + { + flag = false; + break; + } + + } + + + } + if (flag) + { + _connection.CommitTransaction(); + } + else + { + _connection.RollbackTransaction(); + } + return flag; + + } + catch (Exception ex) + { + logger.Error("处方取药完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/RoleDao.cs b/MasaBlazorApp3/DataAccess/Impl/RoleDao.cs new file mode 100644 index 0000000..6355459 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/RoleDao.cs @@ -0,0 +1,75 @@ +using LinqToDB; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Config; +using Microsoft.Extensions.Options; +using System.Linq; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class RoleDao : IRoleDao + { + + private AppDataConnection _connection; + private readonly SettingConfig _setting; + + public RoleDao(AppDataConnection connection, IOptions setting) { _connection = connection; _setting = setting.Value; } + + public async Task GetRoleById(int id) + { + return await _connection.Role.AsQueryable().FirstAsync(x => x.Id == id); + } + + + public int InsertRole(Role role) + { + role.MachineId = _setting.machineId; + return _connection.InsertWithInt32Identity(role); + } + + public bool UpdateRole(Role role) + { + int r = _connection.Role + .Where(r => r.Id == role.Id) + .Set(r => r.RoleName, role.RoleName) + .Set(r => r.permissions, role.permissions) + .Update(); + return r > 0; + } + + public bool DeleteRole(int id) + { + return _connection.Role.Where(r => r.Id ==id).Delete() > 0; + } + + public async Task> GetRolesByName(string name, int? take, int? skip) + { + var query = _connection.Role.AsQueryable(); + + if (!String.IsNullOrEmpty(name)) + { + query = query.Where(r => r.RoleName.IndexOf(name) > -1); + } + query = query.Where(r => r.MachineId == _setting.machineId); + + List list = await query + .OrderBy(r => r.Id) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + + int pagedData = await query.CountAsync(); + return new PageData() + { + + TotalDesserts = pagedData, + Desserts = list + }; + } + + public async Task> GetAllRoles() + { + return await _connection.Role.Where(r => r.MachineId == _setting.machineId).ToListAsync(); + } + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/SelfTakeDao.cs b/MasaBlazorApp3/DataAccess/Impl/SelfTakeDao.cs new file mode 100644 index 0000000..c2de68c --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/SelfTakeDao.cs @@ -0,0 +1,300 @@ +using LinqToDB; +using log4net; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pages; +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Config; +using MasaBlazorApp3.Pojo.Vo; +using MasaBlazorApp3.Port; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Channels; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class SelfTakeDao : ISelfTakeDao + { + private AppDataConnection _connection; + private readonly SettingConfig _setting; + ILog logger = LogManager.GetLogger(typeof(SelfTake)); + private GlobalStateService _globalStateService; + private readonly PortUtil _portUtil; + + public SelfTakeDao(AppDataConnection connection, IOptions setting, GlobalStateService globalStateService, PortUtil portUtil) + { + _connection = connection; + _setting = setting.Value; + _globalStateService = globalStateService; + _portUtil = portUtil; + } + /// + /// 根据药品信息 获取药品库存信息 + /// + /// + /// + public async Task> GetChannelStocksByDrug(List drugInfos) + { + List channelStocks = new List(); + try + { + foreach (var drugInfo in drugInfos) + { + var query = _connection.ChannelStock.AsQueryable(); + ChannelStock channelStock = query.Where(cs => cs.MachineId == _setting.machineId && cs.DrawerType == 1 && cs.DrugId == drugInfo.DrugId).First(); + if (channelStock != null) + { + channelStocks.Add(channelStock); + } + else + { + logger.Info($"药品{drugInfo.DrugName}未绑定"); + channelStocks.Add(new ChannelStock() + { + DrugId = drugInfo.DrugId, + DrawerType = 1, + MachineId = _setting.machineId, + Quantity = 0 + }); + } + } + } + catch (Exception ex) + { + logger.Info($"SelfTakeDao异常{ex.Message}"); + } + return channelStocks; + } + /// + /// 根据药品明细获取数据 + /// + /// + /// + public async Task> getTakeInfoByOrderNo(List orderDetails) + { + + List tempData = new(); + List tempData2 = new(); + var flag = true; + for (var i = 0; i < orderDetails.Count; i++) + { + //List> tempData = new(); + OrderDetail detail = orderDetails[i]; + // 当前detail取药数量 + var Quantity = detail.Quantity; + List stockList = await this.GetChannelStockByDrugId(detail.Drug.DrugId, detail.SetManuNo, Quantity); + + // 当前药品的库存总量 + var total = stockList.Sum(current => current.Quantity); + + tempData2.Add(new OrderTakeVo() + { + Drug = detail.Drug, + OrderDetail = detail, + StockQuantity = total, + Quantity = Quantity + }); + + if (flag) + { + // 盘点库存是否足够 + if (total > Quantity) + { + + for (var j = 0; Quantity > 0; j++) + { + ChannelStock stock = stockList[j]; + if (Quantity > stock.Quantity) + { + // 取药数量大于库存 + tempData.Add(new OrderTakeVo() + { + Drug = detail.Drug, + OrderDetail = detail, + ChannelStock = stock, + StockQuantity = total, + Quantity = stock.Quantity, + }); + Quantity -= stock.Quantity; + } + else + { + //取药数量小于库存 + tempData.Add(new OrderTakeVo() + { + Drug = detail.Drug, + OrderDetail = detail, + ChannelStock = stock, + StockQuantity = total, + Quantity = Quantity, + }); + Quantity = 0; + } + } + } + else + { + // 库存不足 + flag = false; + } + } + + } + if (flag) + { + return tempData; + } + else + { + return tempData2; + } + } + + public async Task> GetChannelStockByDrugId(string DrugId, String ManuNo, int quantity = 0) + { + var query = _connection.ChannelStock.AsQueryable(); + + + query = query.Where(cs => cs.MachineId.Equals(_setting.machineId)).Where(cs => cs.DrawerType == 1) + .Where(cs => cs.Quantity > 0) + .Where(cs => cs.DrugId.Equals(DrugId)); + + if (quantity > 0) + { + if (!String.IsNullOrEmpty(ManuNo)) + { + query = query.Where(cs => cs.ManuNo.Equals(ManuNo)); + } + } + else + { + if (!String.IsNullOrEmpty(ManuNo)) + { + query = query.Where(cs => cs.ManuNo.Equals(ManuNo) || cs.Quantity == 0); + } + } + + + return await query.OrderBy((cs) => cs.EffDate) + .ThenBy((cs) => cs.DrawerNo) + .ThenBy((cs) => cs.ColNo) + .ToListAsync(); + } + + /// + /// 保存自选取药完成数据 + /// + /// + /// + public async Task OrderTakeFinish(List datas, OrderInfo order) + { + + try + { + _connection.BeginTransaction(); + var flag = true; + // 保存处方信息 + order.Status = 1; + order.PatientId = order.PatientId == null ? "0" : order.PatientId; + int r1 = _connection.InsertWithInt32Identity(order); + if (!(r1 > 0)) + { + flag = false; + logger.Error("处方取药完成更新处方状态失败"); + _connection.RollbackTransaction(); + return flag; + } + for (var i = 0; i < datas.Count; i++) + { + var orderTakeVo = datas[i]; + //保存处方明细 + orderTakeVo.OrderDetail.PatientId = orderTakeVo.OrderDetail.PatientId == null ? order.PatientId : orderTakeVo.OrderDetail.PatientId; + orderTakeVo.OrderDetail.ChargeDate = orderTakeVo.OrderDetail.ChargeDate == null ? order.ChargeDate : orderTakeVo.OrderDetail.ChargeDate; + orderTakeVo.OrderDetail.OrderNo = order.OrderNo; + orderTakeVo.OrderDetail.DrugId = orderTakeVo.Drug.DrugId; + orderTakeVo.OrderDetail.SetManuNo = orderTakeVo.ChannelStock.ManuNo; + orderTakeVo.OrderDetail.SetEffDate = orderTakeVo.ChannelStock.EffDate; + int od = _connection.InsertWithInt32Identity(orderTakeVo.OrderDetail); + // 出库记录 + int mid = _connection.InsertWithInt32Identity(new MachineRecord() + { + MachineId = _setting.machineId, + DrawerNo = orderTakeVo.ChannelStock.DrawerNo, + ColNo = orderTakeVo.ChannelStock.ColNo, + DrugId = orderTakeVo.ChannelStock.DrugId, + ManuNo = orderTakeVo.ChannelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(orderTakeVo.ChannelStock.EffDate) ? DateTime.ParseExact(orderTakeVo.ChannelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 2, + Quantity = orderTakeVo.GetQuantity, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + InvoiceId = orderTakeVo.OrderDetail.Id.ToString(), + }); + // 更新库存 + int r = _connection.ChannelStock.Where(cs => cs.Id == orderTakeVo.ChannelStock.Id) + .Set(cs => cs.Quantity, orderTakeVo.ChannelStock.Quantity - orderTakeVo.GetQuantity) + .Update(); + // 获取更新完库存之后的药品库存 + List list = await _connection.ChannelStock.AsQueryable() + .InnerJoin( + _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1), + (cs, cl) => cs.ListId == cl.Id, + (cs, cl) => cs + ) + .Where(cs => cs.DrugId.Equals(orderTakeVo.ChannelStock.DrugId)) + .ToListAsync(); + // 保存账册 + int acid = _connection.InsertWithInt32Identity(new AccountBook() + { + MachineId = _setting.machineId, + DrugId = orderTakeVo.ChannelStock.DrugId, + ManuNo = orderTakeVo.ChannelStock.ManuNo, + EffDate = !String.IsNullOrEmpty(orderTakeVo.ChannelStock.EffDate) ? DateTime.ParseExact(orderTakeVo.ChannelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, + OperationTime = DateTime.Now, + Type = 2, + OutQuantity = orderTakeVo.GetQuantity, + AddQuantity = 0, + Operator = _globalStateService.Operator.Id, + Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, + ManuStock = list.Where(it => it.ManuNo == orderTakeVo.ChannelStock.ManuNo).Sum(it => it.Quantity), + TotalStock = list.Sum(it => it.Quantity), + InvoiceId = orderTakeVo.OrderDetail.Id.ToString() + }); + if (mid > 0 && r > 0 && acid > 0) + { + //根据抽屉类型判断是否需要写标签 + if (orderTakeVo.ChannelStock.BoardType.ToString().Contains("5")) + { + await _portUtil.WriteQuantityMethod(orderTakeVo.ChannelStock.Quantity - orderTakeVo.GetQuantity, orderTakeVo.ChannelStock.DrawerNo, orderTakeVo.ChannelStock.ColNo); + } + } + else + { + flag = false; + break; + } + } + if (flag) + { + _connection.CommitTransaction(); + } + else + { + _connection.RollbackTransaction(); + } + return flag; + + } + catch (Exception ex) + { + logger.Error("自选取药完成保存数据库失败,错误:" + ex.Message); + _connection.RollbackTransaction(); + return false; + } + } + } +} diff --git a/MasaBlazorApp3/DataAccess/Impl/UserDao.cs b/MasaBlazorApp3/DataAccess/Impl/UserDao.cs new file mode 100644 index 0000000..7c662b2 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/Impl/UserDao.cs @@ -0,0 +1,111 @@ +using Google.Protobuf.WellKnownTypes; +using LinqToDB; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.Pojo; +using MasaBlazorApp3.Pojo.Config; +using MasaBlazorApp3.Util; +using Microsoft.Extensions.Options; +using System.Data; +using System.Xml.Linq; + +namespace MasaBlazorApp3.DataAccess.Impl +{ + public class UserDao : IUserDao + { + + //private MyContext Context; + + private readonly AppDataConnection _connection; + private readonly SettingConfig _setting; + + //public UserDao(MyContext context) + //{ + // Context = context; + //} + public UserDao(AppDataConnection connection, IOptions setting) + { + _connection = connection; + _setting = setting.Value; + } + + public async Task> GetAllByNickname(string nickname, int? take, int? skip) + { + var query = _connection.User.AsQueryable(); + + if (!String.IsNullOrEmpty(nickname)) + { + query = query.Where(r => r.NickName.IndexOf(nickname) > -1); + } + query = query.Where(u => u.MachineId == _setting.machineId); + + List list = await query + .LoadWith(u => u.role) + .OrderBy(u => u.Id) + .Skip((int)skip) + .Take((int)take) + .ToListAsync(); + int pagedData = await query.CountAsync(); + return new PageData() + { + + TotalDesserts = pagedData, + Desserts = list + }; + } + + public User GetById(int id) + { + return _connection.User.LoadWith(u => u.role).FirstOrDefault(u => u.Id == id); + } + + public User GetByUsername(string username) + { + + return _connection.User.LoadWith(u => (u.role)).FirstOrDefault(u => u.Username == username&&u.MachineId== _setting.machineId); + } + + public int InsertUser(User user) + { + user.MachineId = _setting.machineId; + user.Password = MD5.GetMD5Hash("123456").ToLower(); + return _connection.InsertWithInt32Identity(user); + } + + public bool UpdateUser(User user) + { + var statement = _connection.User + .Where(u => u.Id == user.Id) + .Set(u => u.NickName, user.NickName) + .Set(u => u.Username, user.Username) + .Set(u => u.RoleId, user.RoleId); + //if(!String.IsNullOrEmpty(user.Password)) + //{ + // statement.Set(u => user.Password, MD5.GetMD5Hash(user.Password).ToLower()); + //} + return statement.Update() > 0; + } + + public bool DeleteeUser(int id) + { + return _connection.User.Where(u => u.Id == id).Delete() > 0; + } + //重置用户密码 + public bool ResetPassword(int id) + { + var statement= _connection.User.Where(u => u.Id == id).Set(u=>u.Password, MD5.GetMD5Hash("123456").ToLower()); + return statement.Update() > 0; + } + + public async Task UpdateSign(int id, string sign) + { + var statement = _connection.User + .Where(u => u.Id == id) + .Set(u => u.Sign, Convert.FromBase64String(sign)); + //if(!String.IsNullOrEmpty(user.Password)) + //{ + // statement.Set(u => user.Password, MD5.GetMD5Hash(user.Password).ToLower()); + //} + return (await statement.UpdateAsync()) > 0; + } + } +} diff --git a/MasaBlazorApp3/DataAccess/PageData.cs b/MasaBlazorApp3/DataAccess/PageData.cs new file mode 100644 index 0000000..1cab9b4 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/PageData.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess +{ + public class PageData + { + public int TotalDesserts { get; set; } + public List Desserts { get; set; } = new List(); + } +} diff --git a/MasaBlazorApp3/DataAccess/PageMultiData.cs b/MasaBlazorApp3/DataAccess/PageMultiData.cs new file mode 100644 index 0000000..da34870 --- /dev/null +++ b/MasaBlazorApp3/DataAccess/PageMultiData.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.DataAccess +{ + public class PageMultiData + { + public int TotalDesserts { get; set; } + public List Desserts { get; set; } = new List(); + public List Other { get; set; } = new List(); + } +} diff --git a/MasaBlazorApp3/Finger/FingerprintUtil.cs b/MasaBlazorApp3/Finger/FingerprintUtil.cs new file mode 100644 index 0000000..03615c2 --- /dev/null +++ b/MasaBlazorApp3/Finger/FingerprintUtil.cs @@ -0,0 +1,142 @@ +using log4net; +using MasaBlazorApp3.Pojo; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using zkemkeeper; +using Microsoft.Extensions.Options; +using MasaBlazorApp3.Pojo.Config; + +namespace MasaBlazorApp3.Finger +{ + public class FingerprintUtil + { + + private readonly ILog logger = LogManager.GetLogger(typeof(FingerprintUtil)); + private readonly FingerPojo _options; + + public CZKEMClass axCZKEM1 = new CZKEMClass(); + public bool bIsConnected = false; + + private int fingerPort = 4370; + private int machineNumber = 1; + private int machineType = 2; + + public FingerprintUtil(IOptions options) + { + _options = options.Value; + logger.Info($"进入构造器,开始连接指纹机"); + // ConnectionMain(); + } + + public async void ConnectionMain() + { + await Task.Run(() => + { + try + { + bIsConnected = axCZKEM1.Connect_Net(_options.ip, fingerPort); + logger.Info($"连接指纹机,IP:{_options.ip},端口:{fingerPort},机器号:{machineNumber},连接结果:{bIsConnected}"); + if (bIsConnected) + { + if (axCZKEM1.RegEvent(machineNumber, 65535)) + { + this.axCZKEM1.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx); + //this.axCZKEM1.OnEnrollFinger += new zkemkeeper._IZKEMEvents_OnEnrollFingerEventHandler(axCZKEM1_OnEnrollFinger); + this.axCZKEM1.OnEnrollFingerEx += new zkemkeeper._IZKEMEvents_OnEnrollFingerExEventHandler(axCZKEM1_OnEnrollFingerEx); + + } + } + } + catch + { + } + }); + + } + + //If your fingerprint(or your card) passes the verification,this event will be triggered + private void axCZKEM1_OnAttTransactionEx(string sEnrollNumber, int iIsInValid, int iAttState, int iVerifyMethod, int iYear, int iMonth, int iDay, int iHour, int iMinute, int iSecond, int iWorkCode) + { + + logger.Info($"触发用户验证通过事件,用户id:{sEnrollNumber}验证方式:{iVerifyMethod}"); + } + + //When you are enrolling your finger,this event will be triggered. + private void axCZKEM1_OnEnrollFinger(int iEnrollNumber, int iFingerIndex, int iActionResult, int iTemplateLength) + { + + axCZKEM1.StartIdentify(); + axCZKEM1.RefreshData(1); + + logger.Info($"触发用户登记指纹事件,用户id:{iEnrollNumber}指纹索引:{iFingerIndex}登记结果:{(iActionResult == 0)}"); + + } + + private void axCZKEM1_OnEnrollFingerEx(string iEnrollNumber, int iFingerIndex, int iActionResult, int iTemplateLength) + { + + axCZKEM1.StartIdentify(); + axCZKEM1.RefreshData(1); + logger.Info($"触发用户登记指纹事件1,用户id:{iEnrollNumber}指纹索引:{iFingerIndex}登记结果:{(iActionResult == 0)}"); + + } + + /** + * 删除用户 + */ + public bool DelUser(int Id) + { + bool result = false; + axCZKEM1.EnableDevice(machineNumber, false); + if (machineType == 1) + { + result = axCZKEM1.DeleteEnrollData(machineNumber, Id, machineNumber, 12); + } + else + { + result = axCZKEM1.SSR_DeleteEnrollData(machineNumber, Id.ToString(), 12); + } + + axCZKEM1.RefreshData(machineNumber); + axCZKEM1.EnableDevice(machineNumber, true); + return result; + } + + /** + * 添加或修改用户 + */ + public bool SaveUser(User User) + { + bool result = false; + //axCZKEM1.SetStrCardNumber(User.UserBarcode); + if (machineType == 1) + { + result = axCZKEM1.SetUserInfo(machineNumber, User.Id, User.NickName, "123456", 0, true); + } + else + { + result = axCZKEM1.SSR_SetUserInfo(machineNumber, User.Id.ToString(), User.NickName, "123456", 0, true); + } + return result; + } + + /** + * 添加或修改用户指纹 + */ + public bool SaveFingerprint(int Id, int FingerIndex) + { + bool result = false; + // 取消其他操作 + bool res2 = axCZKEM1.CancelOperation(); + // 删除源指纹 + bool res = axCZKEM1.SSR_DelUserTmp(machineNumber, Id.ToString(), FingerIndex); + // 添加新指纹 + result = axCZKEM1.StartEnrollEx(Id.ToString(), FingerIndex, 3); + return result; + } + } +} diff --git a/MasaBlazorApp3/GlobalStateService.cs b/MasaBlazorApp3/GlobalStateService.cs new file mode 100644 index 0000000..99684dd --- /dev/null +++ b/MasaBlazorApp3/GlobalStateService.cs @@ -0,0 +1,40 @@ +using System.ComponentModel; +using MasaBlazorApp3.Pojo; + +namespace MasaBlazorApp3 +{ + public class GlobalStateService : INotifyPropertyChanged + { + private User _operator; + private User _reviewer; + + public User Operator + { + get { return _operator; } + set + { + _operator = value; + //OnPropertyChanged(); + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Operator")); + } + } + + public User Reviewer + { + get => _reviewer; + set + { + _reviewer = value; + //OnPropertyChanged(); + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Reviewer")); + } + } + + public event PropertyChangedEventHandler? PropertyChanged; + + //protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + //{ + + //} + } +} diff --git a/MasaBlazorApp3/MasaBlazorApp3.csproj b/MasaBlazorApp3/MasaBlazorApp3.csproj new file mode 100644 index 0000000..0b4ec44 --- /dev/null +++ b/MasaBlazorApp3/MasaBlazorApp3.csproj @@ -0,0 +1,96 @@ + + + + WinExe + net7.0 + enable + enable + favicon.ico + + + + + tlbimp + 0 + 1 + fe9ded34-e159-408e-8490-b720a5e632c7 + 0 + false + False + + + tlbimp + 0 + 6 + 4018f953-1bfe-441e-8a04-dc8ba1ff060e + 0 + false + False + + + + + + + + + + + + + + + + + + + + + Always + + + + + + Always + + + + + + + + + + + + + + Always + + + + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + diff --git a/MasaBlazorApp3/Pages/BiaoDing.razor b/MasaBlazorApp3/Pages/BiaoDing.razor new file mode 100644 index 0000000..632b535 --- /dev/null +++ b/MasaBlazorApp3/Pages/BiaoDing.razor @@ -0,0 +1,288 @@ +@page "/stock/biaoDing" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Util; +@using Microsoft.AspNetCore.Components +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + + +
+ @if (DrawerNos.Count() > 8) + { +
+
+ @foreach (int i in DrawerNos) + { + + + } +
+
+ } + else + { +
+
+ @foreach (int i in DrawerNos) + { + + + } +
+
+ } + +
+ + + + + + + + + + + + + + + + @if (channel.Quantity == 0 && !String.IsNullOrEmpty(channel.DrugId)) + { + + + + + @((context as DrugManuNo)?.ManuNo) + @((context as DrugManuNo)?.EffDate) + + + + + } + else + { + + @channel.drugManuNo?.ManuNo + @channel.drugManuNo?.EffDate + } + + + + + + + + @if (cs.BoardType == 2) + { + @cs.AddQuantity + } + else + { + + + } + + + + +
+@code { + @inject IChannelListDao channelListDao; + @inject NavigationManager na; + @inject PortUtil PortUtil; + @inject NotificationService _message + @inject IOptions setting; + int status = 0; + int drawerNo = 1; + RadzenDataGrid grid; + private List? channels; + bool isLoading; + int count; + int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + int[] BeforeQuantity = new int[9]; + int[] AfterQuantity = new int[9]; + private readonly ILog logger = LogManager.GetLogger(typeof(DrawerAdd)); + + // 当前操作的库位号列表 + public List ColNos { get; set; } = new List(); + int currentCol = 0; + bool CompleteIsEnable = true; + bool CancleIsEnable = true; + + void SelectDrawer(int drawerNo) + { + this.drawerNo = drawerNo; + grid.Reload(); + } + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await channelListDao.GetChannelStockByDrawerNoWithDrawers(drawerNo); + DrawerNos = result.DrawerArray; + channels = result.ChannelStocks; + count = result.ChannelStocks.Count; + + + isLoading = false; + } + async Task OpenDrawer() + { + this.status = 1; + var promiseUtil = new PromiseUtil(); + await promiseUtil.taskAsyncLoop(500, null, async (data, next, stop) => + { + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + // if(库存》0) + // {} + + } + var b = await PortUtil.OpenDrawerStatus(this.drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,加药"); + this.status = 2; + PortUtil.Operate = true; + next(); + } + // else + // { + // _message.Notify( + // new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + // ); + // logger.Info($"抽屉打开失败"); + // RestData(); + // PortUtil.Operate = false; + // stop(); + // } + + else if (this.status == 2) + { + if (setting.Value.box != null && setting.Value.box.Contains(this.drawerNo)) + { + //药盒抽屉,开药盒 + for (int i = 0; i < ColNos.Count; i++) + { + await PortUtil.OpenBoxByColNo(ColNos[i]); + } + } + // 查询抽屉是否为关闭状态 + var b2 = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b2) + { + PortUtil.SpeakAsync($"加药完成,请,核对,或,录入,正确的,添加数量"); + // 判断是否为称重抽屉 + if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo)) + { + //关闭抽屉后获取称重稳定数量 + // await GetWeightQuantity(); + } + this.status = 3; + PortUtil.Operate = false; + stop(); + } + else + { + if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + channels.ForEach(cl => + { + cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1]; + }); + } + // 判断是否为称重抽屉 + if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo)) + { + //开抽屉后查数 + for (int i = 0; i < 9; i++) + { + int afterQuantity = await PortUtil.CheckQuantityForSingle(i); + AfterQuantity[i] = afterQuantity; + logger.Info($"AfterQuantity:{i}-{AfterQuantity}数量{string.Join(",", BeforeQuantity)}"); + } + channels.ForEach(cl => + { + cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1]; + }); + } + next(); // continue iteration + } + + } + } + catch (Exception e) + { + logger.Info($"抽屉加药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo)) + { + PortUtil.AllLightOff(); + } + RestData(); + stop(); + } + }); + } + void RestData() + { + this.status = 0; + } + void OnCellClick(DataGridCellMouseEventArgs args) + { + if (args.Data.BoardType.ToString().Contains("3")) + { + //是药盒抽屉则点击行,打开对应行的药箱 + if (!ColNos.Contains(args.Data.ColNo)) + { + ColNos.Add(args.Data.ColNo); + } + } + else + { + grid.EditRow(args.Data); + } + } +} diff --git a/MasaBlazorApp3/Pages/ConfirmDialo.razor b/MasaBlazorApp3/Pages/ConfirmDialo.razor new file mode 100644 index 0000000..bfce5a1 --- /dev/null +++ b/MasaBlazorApp3/Pages/ConfirmDialo.razor @@ -0,0 +1,27 @@ + + + + 确认要@(confirmInfo) 吗? + + + + + + + + + +@code { + @inject Radzen.DialogService dialogService; + [Parameter] public string confirmInfo { get; set; } + protected override async Task OnInitializedAsync() + { + var info = confirmInfo; + base.OnInitializedAsync(); + } + async Task ConfirmOK() + { + // 关闭弹窗 + dialogService.Close(true); + } +} diff --git a/MasaBlazorApp3/Pages/DrawerAdd.razor b/MasaBlazorApp3/Pages/DrawerAdd.razor new file mode 100644 index 0000000..5d6fa59 --- /dev/null +++ b/MasaBlazorApp3/Pages/DrawerAdd.razor @@ -0,0 +1,446 @@ +@page "/add/drawer" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Util; +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + +
+
+ @* *@ +
+ @foreach (int i in DrawerNos) + { + + + } +
+ @*
*@ +
+
+ + + + @if (status < 3) + { + + } + @if (status == 3) + { + + } + @if (status > 0 && status <= 3) + { + + } + + + + + + + + + + + + @if (channel.Quantity == 0 && !String.IsNullOrEmpty(channel.DrugId)) + { + + + + + @((context as DrugManuNo)?.ManuNo) + @((context as DrugManuNo)?.EffDate) + + + + + } + else + { + + @channel.drugManuNo?.ManuNo + @channel.drugManuNo?.EffDate + } + + + + + + + + @if (cs.BoardType == 2) + { + @cs.AddQuantity + } + else + { + + + } + + + + + +
+@code { + @inject IChannelListDao channelListDao; + @inject NavigationManager na; + @inject PortUtil PortUtil; + @inject NotificationService _message + @inject IOptions setting; + int status = 0; + int drawerNo = 1; + RadzenDataGrid grid; + private List? channels; + bool isLoading; + int count; + int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + int[] BeforeQuantity = new int[9]; + int[] AfterQuantity = new int[9]; + private readonly ILog logger = LogManager.GetLogger(typeof(DrawerAdd)); + + // 当前操作的库位号列表 + public List ColNos { get; set; } = new List(); + int currentCol = 0; + bool CompleteIsEnable = true; + bool CancleIsEnable=true; + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await channelListDao.GetChannelStockByDrawerNoWithDrawers(drawerNo); + // var result = await channelListDao.GetChannelStockByDrawerNo(drawerNo); + // Update the Data property + DrawerNos = result.DrawerArray; + channels = result.ChannelStocks; + // Update the count + count = result.ChannelStocks.Count; + + + isLoading = false; + } + async Task OpenDrawer() + { + this.status = 1; + // 根据抽屉类型来决定打开前是否需要查询数量 + var promiseUtil = new PromiseUtil(); + await promiseUtil.taskAsyncLoop(500, null, async (data, next, stop) => + { + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + // 判断是否为单支抽屉 + if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo); + BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】"); + } + // 判断是否为称重抽屉 + if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo)) + { + //开抽屉前先查数 + for (int i = 0; i < 9; i++) + { + int beforeQuantity = await PortUtil.CheckQuantityForSingle(i); + BeforeQuantity[i] = beforeQuantity; + logger.Info($"BeforeQuantity:{i}-{beforeQuantity}数量{string.Join(",", BeforeQuantity)}"); + } + } + + var b = await PortUtil.OpenDrawerStatus(this.drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,加药"); + this.status = 2; + PortUtil.Operate = true; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + RestData(); + PortUtil.Operate = false; + stop(); + } + + } + // 检测状态 + else if (this.status == 2) + { + if (setting.Value.box != null && setting.Value.box.Contains(this.drawerNo)) + { + //药盒抽屉,开药盒 + for(int i=0;i< ColNos.Count;i++) + { + await PortUtil.OpenBoxByColNo(ColNos[i]); + } + } + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + PortUtil.SpeakAsync($"加药完成,请,核对,或,录入,正确的,添加数量"); + // 判断是否为称重抽屉 + if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo)) + { + //关闭抽屉后获取称重稳定数量 + await GetWeightQuantity(); + } + this.status = 3; + PortUtil.Operate = false; + stop(); + } + else + { + if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + channels.ForEach(cl => + { + cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1]; + }); + } + // 判断是否为称重抽屉 + if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo)) + { + //开抽屉后查数 + for (int i = 0; i < 9; i++) + { + int afterQuantity = await PortUtil.CheckQuantityForSingle(i); + AfterQuantity[i] = afterQuantity; + logger.Info($"AfterQuantity:{i}-{AfterQuantity}数量{string.Join(",", BeforeQuantity)}"); + } + channels.ForEach(cl => + { + cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1]; + }); + } + next(); // continue iteration + } + + } + } + catch (Exception e) + { + logger.Info($"抽屉加药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo)) + { + PortUtil.AllLightOff(); + } + RestData(); + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + this.BeforeQuantity = new int[9]; + this.AfterQuantity = new int[9]; + } + //关闭抽屉后获取称重稳定数量 + public async Task GetWeightQuantity() + { + List finallyQuantity = new List(); + await new PromiseUtil().taskAsyncLoop(200, 0, async (options, next, stop) => + { + if (!PortUtil.Operate || this.status == 0) + { + stop(); + } + else + { + try + { + logger.Info("关闭抽屉后获取称重稳定数量"); + if (finallyQuantity.Count >= 10) + { + for (int i = 0; i < finallyQuantity.Count; i++) + { + logger.Info($"finallyQuantity{i} {string.Join(",", finallyQuantity[i])}"); + } + if (AreAllArraysEqual(finallyQuantity)) + { + stop(); + channels.ForEach(cl => + { + cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1]; + }); + } + else + { + finallyQuantity.RemoveAt(0); + next(); + } + } + else + { + if (finallyQuantity.Count >= 9) + { + CancleIsEnable = true; + } + else + { + CancleIsEnable = false; + } + CompleteIsEnable = false; + PortUtil.DrawerNo = drawerNo; + int[] quantity = await PortUtil.CheckQuantityByAddrForMulti(); + AfterQuantity = quantity; + int[] Quantitys = new int[BeforeQuantity.Length]; + for (int i = 0; i < BeforeQuantity.Length; i++) + { + Quantitys[i] = BeforeQuantity[i] - AfterQuantity[i]; + } + finallyQuantity.Add(Quantitys); + logger.Info($"Quantity{string.Join(",", Quantitys)}"); + + channels.ForEach(cl => + { + cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1]; + }); + next(); + } + } + catch (Exception ex) + { + logger.Info($"关闭抽屉后获取称重稳定数量异常{ex.Message}"); + next(); + } + } + }); + } + public bool AreAllArraysEqual(List arrays) + { + if (arrays == null || arrays.Count == 0) return false; + // 取第一个数组作为参照进行比较 + var referenceArray = arrays[0]; + // 检查列表中除了第一个数组外的所有数组是否与第一个数组相等 + return arrays.Skip(1).All(array => array.SequenceEqual(referenceArray)); + } + async Task AddFinish() + { + if (channels.Any(cl => cl.AddQuantity != 0 && cl.DrugId != null && cl.drugManuNo != null)) + { + // 保存账册、操作记录 + var b = await channelListDao.DrawerOperationFinish(channels.Where(cl => cl.AddQuantity != 0).ToList(), 1); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(channels)}"); + } + else + { + // 判断是否为标签抽屉 + if (setting.Value.label.Contains(this.drawerNo)) + { + //写标签数量 + channels.ForEach(async it => + { + await PortUtil.WriteQuantityMethod(it.Quantity + it.AddQuantity, it.DrawerNo, it.ColNo); + }); + } + } + } + + //重置状态 + this.RestData(); + // 重新查询库存 + await grid.Reload(); + } + + void Cancel() + { + this.status = 0; + } + + void SelectDrawer(int drawerNo) + { + this.drawerNo = drawerNo; + grid.Reload(); + } + + void OnCellClick(DataGridCellMouseEventArgs args) + { + if (args.Data.BoardType.ToString().Contains("3")) + { + //是药盒抽屉则点击行,打开对应行的药箱 + if (!ColNos.Contains(args.Data.ColNo)) + { + ColNos.Add(args.Data.ColNo); + } + } + else + { + grid.EditRow(args.Data); + } + } + private IDisposable? registration; + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + registration = na.RegisterLocationChangingHandler(OnLocationChanging); + } + } + + private ValueTask OnLocationChanging(LocationChangingContext context) + { + // 操作中不可跳转页面 + if (status > 0) + { + context.PreventNavigation(); //阻止导航 + } + return ValueTask.CompletedTask; + } + //在生命周期函数Dispose中,移除订阅的事件,并销毁非托管资源registration=========================================== + public void Dispose() + { + registration?.Dispose(); + } +} diff --git a/MasaBlazorApp3/Pages/DrawerTake.razor b/MasaBlazorApp3/Pages/DrawerTake.razor new file mode 100644 index 0000000..32cf938 --- /dev/null +++ b/MasaBlazorApp3/Pages/DrawerTake.razor @@ -0,0 +1,445 @@ +@page "/take/drawer" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Util; +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + + @*
+
+ + @foreach (int i in DrawerNos) + { + + } + +
+
*@ +
+
+ @* *@ +
+ @foreach (int i in DrawerNos) + { + + + } +
+ @*
*@ +
+
+ + + + @if (status < 3) + { + + } + @if (status == 3) + { + + } + @if (status > 0 && status <= 3) + { + + } + + + + + + + + + + + + + + + + @if (channel.BoardType == 2) + { + @channel.TakeQuantity + } + else + { + + @* *@ + } + + + + + +
+@code { + @inject IChannelListDao channelListDao; + @inject NavigationManager na; + @inject PortUtil PortUtil; + @inject NotificationService _message + @inject IOptions setting; + int status = 0; + int drawerNo = 1; + RadzenDataGrid grid; + private List? channels; + bool isLoading; + int count; + int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }; + int[] BeforeQuantity = new int[9]; + int[] AfterQuantity = new int[9]; + + // 当前操作的库位号列表 + public List ColNos { get; set; } = new List(); + bool CompleteIsEnable = true; + bool CancleIsEnable = true; + + private readonly ILog logger = LogManager.GetLogger(typeof(DrawerTake)); + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + // var result = await channelListDao.GetChannelStockByDrawerNo(drawerNo, 1); + var result = await channelListDao.GetChannelStockByDrawerNoWithDrawers(drawerNo); + DrawerNos = result.DrawerArray; + // Update the Data property + channels = result.ChannelStocks; + // Update the count + count = result.ChannelStocks.Count; + + + isLoading = false; + } + async Task OpenDrawer() + { + this.status = 1; + // 根据抽屉类型来决定打开前是否需要查询数量 + var promiseUtil = new PromiseUtil(); + await promiseUtil.taskAsyncLoop(500, null, async (data, next, stop) => + { + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + // 判断是否为单支抽屉 + if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo); + BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】"); + } + // 判断是否为称重抽屉 + if (setting.Value.weigh!=null&&setting.Value.weigh.Contains(this.drawerNo)) + { + //开抽屉前先查数 + for (int i = 0; i < 9; i++) + { + int beforeQuantity = await PortUtil.CheckQuantityForSingle(i); + BeforeQuantity[i] = beforeQuantity; + logger.Info($"BeforeQuantity:{i}-{beforeQuantity}数量{string.Join(",", BeforeQuantity)}"); + } + } + + var b = await PortUtil.OpenDrawerStatus(this.drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药"); + PortUtil.Operate = true; + this.status = 2; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + RestData(); + stop(); + } + + } + // 检测状态 + else if (this.status == 2) + { + if (setting.Value.box != null && setting.Value.box.Contains(this.drawerNo)) + { + //药盒抽屉,开药盒 + for (int i = 0; i < ColNos.Count; i++) + { + await PortUtil.OpenBoxByColNo(ColNos[i]); + } + } + + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + PortUtil.SpeakAsync($"取药完成,请核对或录入正确的取出数量"); + // 判断是否为称重抽屉 + if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo)) + { + //关闭抽屉后获取称重稳定数量 + await GetWeightQuantity(); + } + logger.Info($"关闭抽屉,称重抽屉获取稳定数量后日志"); + this.status = 3; + PortUtil.Operate = false; + stop(); + } + else + { + if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + channels.ForEach(cl => + { + cl.TakeQuantity = this.BeforeQuantity[cl.ColNo - 1] - this.AfterQuantity[cl.ColNo - 1]; + }); + + } + // 判断是否为称重抽屉 + if (setting.Value.weigh!=null&&setting.Value.weigh.Contains(this.drawerNo)) + { + //开抽屉后查数 + for (int i = 0; i < 9; i++) + { + int afterQuantity = await PortUtil.CheckQuantityForSingle(i); + AfterQuantity[i] = afterQuantity; + logger.Info($"AfterQuantity:{i}-{AfterQuantity}数量{string.Join(",", BeforeQuantity)}"); + } + channels.ForEach(cl => + { + cl.TakeQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1]; + }); + } + next(); // continue iteration + } + + } + } + catch (Exception e) + { + logger.Info($"抽屉取药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(this.drawerNo)) + { + PortUtil.AllLightOff(); + } + RestData(); + stop(); + } + }); + } + //关闭抽屉后获取称重稳定数量 + public async Task GetWeightQuantity() + { + List finallyQuantity = new List(); + await new PromiseUtil().taskAsyncLoop(200, 0, async (options, next, stop) => + { + if (!PortUtil.Operate || this.status == 0) + { + stop(); + CancleIsEnable = true; + CompleteIsEnable = true; + logger.Info($"停止循环{!PortUtil.Operate}-{this.status}"); + } + else + { + try + { + logger.Info("关闭抽屉后获取称重稳定数量"); + if (finallyQuantity.Count >= 10) + { + for (int i = 0; i < finallyQuantity.Count; i++) + { + logger.Info($"finallyQuantity{i} {string.Join(",", finallyQuantity[i])}"); + } + if (AreAllArraysEqual(finallyQuantity)) + { + stop(); + CancleIsEnable = true; + CompleteIsEnable = true; + + logger.Info("对比成功停止循环"); + + channels.ForEach(cl => + { + cl.TakeQuantity = this.BeforeQuantity[cl.ColNo - 1] - this.AfterQuantity[cl.ColNo - 1]; + }); + } + else + { + finallyQuantity.RemoveAt(0); + CancleIsEnable = true; + next(); + } + } + else + { + if (finallyQuantity.Count >= 9) + { + CancleIsEnable = true; + } + else + { + CancleIsEnable = false; + } + CompleteIsEnable = false; + PortUtil.DrawerNo = drawerNo; + int[] quantity = await PortUtil.CheckQuantityByAddrForMulti(); + AfterQuantity = quantity; + int[] Quantitys = new int[BeforeQuantity.Length]; + for (int i = 0; i < BeforeQuantity.Length; i++) + { + Quantitys[i] = BeforeQuantity[i] - AfterQuantity[i]; + } + finallyQuantity.Add(Quantitys); + logger.Info($"Quantity{string.Join(",", Quantitys)}"); + channels.ForEach(cl => + { + cl.TakeQuantity = this.BeforeQuantity[cl.ColNo - 1] - this.AfterQuantity[cl.ColNo - 1]; + }); + next(); + } + } + catch (Exception ex) + { + logger.Info($"关闭抽屉后获取称重稳定数量异常{ex.Message}"); + next(); + } + } + }); + } + public bool AreAllArraysEqual(List arrays) + { + if (arrays == null || arrays.Count == 0) return false; + // 取第一个数组作为参照进行比较 + var referenceArray = arrays[0]; + // 检查列表中除了第一个数组外的所有数组是否与第一个数组相等 + return arrays.Skip(1).All(array => array.SequenceEqual(referenceArray)); + } + void RestData() + { + this.status = 0; + this.BeforeQuantity = new int[9]; + this.AfterQuantity = new int[9]; + + InvokeAsync(StateHasChanged); + } + + async Task TakeFinish() + { + if (channels.Any(cl => cl.TakeQuantity != 0)) + { + + // 保存账册、操作记录 + var b = await channelListDao.DrawerOperationFinish(channels.Where(cl => cl.TakeQuantity != 0).ToList(), 2); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"抽屉取药保存数据库失败,数据{JsonConvert.SerializeObject(channels)}"); + } + else + { + // 判断是否为标签抽屉 + if (setting.Value.label.Contains(this.drawerNo)) + { + //写标签数量 + channels.ForEach(async it => + { + await PortUtil.WriteQuantityMethod(it.Quantity + it.AddQuantity, it.DrawerNo, it.ColNo); + }); + } + } + } + //重置状态 + this.RestData(); + // 重新查询库存 + await grid.Reload(); + } + + void Cancel() + { + this.status = 0; + } + + void SelectDrawer(int drawerNo) + { + this.drawerNo = drawerNo; + InvokeAsync(StateHasChanged); + grid.Reload(); + } + + void OnCellClick(DataGridCellMouseEventArgs args) + { + if (args.Data.BoardType.ToString().Contains("3")) + { + //是药盒抽屉则点击行,打开对应行的药箱 + if (!ColNos.Contains(args.Data.ColNo)) + { + ColNos.Add(args.Data.ColNo); + } + } + else + { + grid.EditRow(args.Data); + } + } + private IDisposable? registration; + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + registration = na.RegisterLocationChangingHandler(OnLocationChanging); + } + } + + private ValueTask OnLocationChanging(LocationChangingContext context) + { + // 操作中不可跳转页面 + if (status > 0) + { + context.PreventNavigation(); //阻止导航 + } + return ValueTask.CompletedTask; + } + //在生命周期函数Dispose中,移除订阅的事件,并销毁非托管资源registration=========================================== + public void Dispose() + { + registration?.Dispose(); + } +} diff --git a/MasaBlazorApp3/Pages/DrugList.razor b/MasaBlazorApp3/Pages/DrugList.razor new file mode 100644 index 0000000..35fcb0e --- /dev/null +++ b/MasaBlazorApp3/Pages/DrugList.razor @@ -0,0 +1,338 @@ +@page "/stock/drug" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ @* + б + *@ + @if (SelectedDrugs.Count > 0) + { + + @* + + + + *@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ } +
+
+
+ +@code { + @inject IDrugInfoDao drugInfoDao; + @inject DialogService dialogService; + @inject IDrugManuNoDao drugManuNoDao; + RadzenDataGrid grid; + RadzenDataGrid ManusGrid; + + + List manuNoToInsert = new List(); + List manuNoToUpdate = new List(); + + bool isLoading; + int count; + private IEnumerable? _forecasts; + + IList SelectedDrugs { get; set; } = new List(); + string DrugId; + string DrugName; + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await drugInfoDao.GetAllDrug(DrugId, DrugName, args.Top, args.Skip); + // Update the Data property + _forecasts = result.Desserts; + count = result.TotalDesserts; + SelectedDrugs = new List() { _forecasts.FirstOrDefault() }; + + isLoading = false; + } + + async Task reloadGrid() + { + DrugId = String.Empty; + DrugName = String.Empty; + await grid.Reload(); + } + + void Reset() + { + manuNoToInsert.Clear(); + manuNoToUpdate.Clear(); + } + void Reset(DrugManuNo drugManuNo) + { + manuNoToInsert.Remove(drugManuNo); + manuNoToUpdate.Remove(drugManuNo); + } + /// ҩƷ + async Task InsertDrugRow() + { + var drugInfo = new DrugInfo(); + drugInfo.Manus.Add(new DrugManuNo()); + SelectedDrugs.Add(drugInfo); + await grid.InsertRow(drugInfo); + } + // //ҩƷϢ + async Task OnDrugUpdateRow(DrugInfo drugInfo) + { + // ݿҩƷ + drugInfoDao.UpdateDrugInfo(drugInfo); + grid.Reload(); + } + //ҩƷϢ + async Task OnDrugCreateRow(DrugInfo drugInfo) + { + // ݿҩƷ + drugInfoDao.AddDrugInfo(drugInfo); + grid.Reload(); + } + async Task EditDrugRow(DrugInfo drugInfo) + { + drugInfoDao.UpdateDrugInfo(drugInfo); + await grid.EditRow(drugInfo); + } + async Task SaveDrugRow(DrugInfo drugInfo) + { + await grid.UpdateRow(drugInfo); + } + void CancelDrugEdit(DrugInfo drugInfo) + { + Reset(); + grid.CancelEditRow(drugInfo); + grid.Reload(); + } + async Task DeleteDrugRow(DrugInfo drugInfo) + { + Reset(); + if(!string.IsNullOrEmpty(drugInfo.DrugId)) + { + //ȷʾ + var b = await dialogService.OpenAsync( + $"ɾȷ", + new Dictionary() { { "confirmInfo", "ɾҩƷ"+drugInfo.DrugName } }, + new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false }); + if(b) + { + // ݿɾ + drugInfoDao.DeleteDrugInfo(drugInfo.DrugId); + } + grid.Reload(); + } + } + + /// + async Task InsertRow() + { + var drugManuNo = new Pojo.DrugManuNo() + { + Id = Guid.NewGuid().ToString(), + DrugId = SelectedDrugs.FirstOrDefault().DrugId + }; + SelectedDrugs.FirstOrDefault().Manus.Add(drugManuNo); + await ManusGrid.InsertRow(drugManuNo); + } + + async Task EditRow(DrugManuNo drugManuNo) + { + + Reset(); + + manuNoToUpdate.Add(drugManuNo); + await ManusGrid.EditRow(drugManuNo); + } + async Task SaveRow(DrugManuNo drugManuNo) + { + await ManusGrid.UpdateRow(drugManuNo); + } + + void CancelEdit(DrugManuNo drugManuNo) + { + Reset(drugManuNo); + + ManusGrid.CancelEditRow(drugManuNo); + ManusGrid.Reload(); + } + + async Task DeleteRow(DrugManuNo drugManuNo) + { + Reset(drugManuNo); + + if (SelectedDrugs.FirstOrDefault().Manus.Contains(drugManuNo)) + { + //ȷʾ + var b = await dialogService.OpenAsync( + $"ȷɾ", + new Dictionary() { { "confirmInfo", "ɾΣ"+drugManuNo.ManuNo } }, + new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false } + ); + if(b) + { + // ݿɾ + drugManuNoDao.DeleteDrugManuNo(drugManuNo.Id); + await ManusGrid.Reload(); + } + } + else + { + ManusGrid.CancelEditRow(drugManuNo); + await ManusGrid.Reload(); + } + } + void OnUpdateRow(DrugManuNo dm) + { + Reset(dm); + + // ݿ + drugManuNoDao.UpdateDrugManuNo(dm); + ManusGrid.Reload(); + } + void OnCreateRow(DrugManuNo dm) + { + // ݿ + drugManuNoDao.AddDrugManuNo(dm); + manuNoToInsert.Remove(dm); + ManusGrid.Reload(); + } + +} diff --git a/MasaBlazorApp3/Pages/FingerRegDialog.razor b/MasaBlazorApp3/Pages/FingerRegDialog.razor new file mode 100644 index 0000000..4388f24 --- /dev/null +++ b/MasaBlazorApp3/Pages/FingerRegDialog.razor @@ -0,0 +1,70 @@ +@page "/user/finger/{userId}" + +@using log4net; + + + + + + + + + + + + + + + +@code { + [Parameter] public int userId { get; set; } + + + @inject DialogService dialogService; + @inject FingerprintUtil FingerprintUtil; + + + private readonly ILog logger = LogManager.GetLogger(typeof(FingerRegDialog)); + + List fingerNames = new List() + { + "左小拇指","左无名指","左中指", "左食指", "左大拇指", "右小拇指", "右无名指", "右中指" ,"右食指", "右大拇指" + + }; + + string fingerName = "左小拇指"; + bool regLoading = false; + + + void RegZWJSubmit() + { + regLoading = true; + InvokeAsync(StateHasChanged); + FingerprintUtil.axCZKEM1.OnEnrollFingerEx += axCZKEM1_OnEnrollFingerEx; + FingerprintUtil.SaveFingerprint(userId, fingerNames.FindIndex(n => n.Equals(fingerName))); + } + + void RegZWJCancel() + { + + FingerprintUtil.axCZKEM1.CancelOperation(); + regLoading = false; + InvokeAsync(StateHasChanged); + FingerprintUtil.axCZKEM1.OnEnrollFingerEx -= axCZKEM1_OnEnrollFingerEx; + dialogService.Close(); + } + + private void axCZKEM1_OnEnrollFingerEx(string iEnrollNumber, int iFingerIndex, int iActionResult, int iTemplateLength) + { + + FingerprintUtil.axCZKEM1.StartIdentify(); + FingerprintUtil.axCZKEM1.RefreshData(1); + regLoading = false; + InvokeAsync(StateHasChanged); + dialogService.Close(); + logger.Info($"触发用户登记指纹事件1,用户id:{iEnrollNumber}指纹索引:{iFingerIndex}登记结果:{(iActionResult == 0)}"); + FingerprintUtil.axCZKEM1.OnEnrollFingerEx -= axCZKEM1_OnEnrollFingerEx; + + } + +} diff --git a/MasaBlazorApp3/Pages/Home.razor b/MasaBlazorApp3/Pages/Home.razor new file mode 100644 index 0000000..a86e6d2 --- /dev/null +++ b/MasaBlazorApp3/Pages/Home.razor @@ -0,0 +1,220 @@ +@page "/home" +@using MasaBlazorApp3.Util +@using log4net +@layout EmptyLayout + + + + + + + + + + + + + 操作人:@Operator.NickName + @if (Reviewer != null) + { + 复核人:@Reviewer.NickName + } + + + + + + + + + + + + + 出库 + @if (!Operator.role.permissionIds.Any(id => id - 10 < 10)) + { +
+ +
+ } +
+ + 入库 + @if (!Operator.role.permissionIds.Any(id => id - 20 > 0 && id - 20 < 10)) + { +
+ +
+ } +
+
+ + + 归还 + @if (!Operator.role.permissionIds.Any(id => id - 30 > 0 && id - 30 < 10)) + { +
+ +
+ } +
+ + + 库存管理 + @if (!Operator.role.permissionIds.Any(id => id - 40 > 0 && id - 40 < 10)) + { +
+ +
+ } +
+ + 系统设置 + @if (!Operator.role.permissionIds.Any(id => id - 50 > 0 && id - 50 < 10)) + { +
+ +
+ } +
+ +
+
+
+
+ + +@code { + @inject NavigationManager na; + @inject TooltipService tooltipService + private List userPremissions { get; set; } = new(); + @inject GlobalStateService globalStateService; + Pojo.User Operator; + Pojo.User Reviewer; + + Timer timer; + @inject PortUtil _portUtil; + private readonly ILog logger = LogManager.GetLogger(typeof(Home)); + @inject Microsoft.Extensions.Options.IOptions setting; + bool currentPage = true; + + protected override void OnInitialized() + { + + + Operator = globalStateService.Operator; + Reviewer = globalStateService.Reviewer; + + // timer = new Timer(state => + // { + // var now = DateTime.Now; + + + // InvokeAsync(StateHasChanged); + // }, null, 0, 1000); + if (setting.Value.autoOutLog > 0) + { + // 是否需要自动退出 + var promiseUtil = new PromiseUtil(); + promiseUtil.taskAsyncLoop(500, null, async (data, next, stop) => + { + if (globalStateService.Operator == null || !currentPage) + { + logger.Info($"Home页自动退出循环停止{globalStateService.Operator==null},{!currentPage}"); + stop(); + } + else + { + try + { + //没有在操作抽屉 + if (!_portUtil.Operate) + { + // 无人操作鼠标键盘 + if ((DateTime.Now - _portUtil.dateTime).TotalSeconds > setting.Value.autoOutLog && CheckComputerFreeState.GetLastInputTime() > setting.Value.autoOutLog) + { + logger.Info($"设备{setting.Value.autoOutLog}内无人操作,用户【{Operator?.NickName}】自动退出登录,_portUtil.Operate:{_portUtil.Operate},totalSecond:{(DateTime.Now - _portUtil.dateTime).TotalSeconds},lastInputTime:{CheckComputerFreeState.GetLastInputTime()},autoOutLog:{setting.Value.autoOutLog}"); + globalStateService.Operator = null; + globalStateService.Reviewer = null; + na.NavigateTo(""); + stop(); + } + else + { + next(); + } + } + else + { + next(); + } + } + catch (Exception ex) + { + logger.Info($"检查是否自动退出循环异常:{ex.Message}"); + next(); + } + } + }); + } + base.OnInitialized(); + } + + public void Dispose() + { + timer?.Dispose(); + } + + void jump2Page(int parentId) + { + List childrenIds = Operator.role.permissionIds.Where(id => id - (parentId * 10) > 0 && id - (parentId * 10) < 10).ToList(); + if(childrenIds.Count > 0) + { + childrenIds.Sort(); + int minId = childrenIds[0]; + string path = new Premission().getAdminPremission().Find(p => p.Id == parentId).Items.ToList().Find(p2 => p2.Id == minId).PremissionPath; + na.NavigateTo(path); + currentPage = false; + } + } + void logout() + { + globalStateService.Operator = null; + globalStateService.Reviewer = null; + na.NavigateTo(""); + } +} diff --git a/MasaBlazorApp3/Pages/Index.razor b/MasaBlazorApp3/Pages/Index.razor new file mode 100644 index 0000000..c548931 --- /dev/null +++ b/MasaBlazorApp3/Pages/Index.razor @@ -0,0 +1,234 @@ +@page "/" +@layout EmptyLayout + +@using System.ComponentModel; +@using log4net; + + + + + + + + + + + + + @if(loginMode == 2) + { + ˣ@globalStateService.Operator?.NickName + ˣ@globalStateService.Reviewer?.NickName + } + + + + + + ¼ + + +
+ +
+ + +
+
+
+ +
+ + +
+
+
+ + +
+
+
+
+ +
+
+ + + +@code { + + @inject FingerprintUtil FingerprintUtil; + @inject PortUtil PortUtil; + @inject NavigationManager na; + @inject NotificationService _message + @inject GlobalStateService globalStateService; + @inject IUserDao userDao; + @inject Microsoft.Extensions.Options.IOptions setting; + + + + private readonly ILog logger = LogManager.GetLogger(typeof(Index)); + + private int loginMode = 1; + private bool opFirst = true; + + + + bool isShow; + + private Pojo.User loginModel = new(); + + protected override Task OnInitializedAsync() + { + FingerprintUtil.axCZKEM1.OnAttTransactionEx += axCZKEM1_OnAttTransactionEx; + + loginMode = setting.Value.loginMode; + opFirst = setting.Value.opFirst; + + return base.OnInitializedAsync(); + } + + private void SetUser(Pojo.User user) + { + + // жǷΪ˫˵¼ģʽ + if (loginMode == 2) + { + // жǷDzȵ¼ + if (opFirst) + { + // жϲǷѾ¼Ѿ¼˵ʱΪڶ˵¼ + if (globalStateService.Operator != null) + { + // жǷDz˵֤ + if (globalStateService.Operator.Id != user.Id) + { + FingerprintUtil.axCZKEM1.OnAttTransactionEx -= axCZKEM1_OnAttTransactionEx; + globalStateService.Reviewer = user; + na.NavigateTo("/home"); + logger.Info($"˫˵¼ģʽˡ{globalStateService.Operator.NickName}ˡ{user.NickName}¼"); + } else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "ʾ", Detail = $"֤ظʹ˺", Duration = 3000 } + ); + } + } else + { + // ʱΪһ˵¼ + globalStateService.Operator = user; + InvokeAsync(StateHasChanged); + loginModel = new(); + } + } + // Ϊڶ˵¼ + else + { + // жϸǷѾ¼Ѿ¼˵ʱΪڶ˵¼ + if (globalStateService.Reviewer != null) + { + // жǷǸ˵֤ + if (globalStateService.Reviewer.Id != user.Id) + { + FingerprintUtil.axCZKEM1.OnAttTransactionEx -= axCZKEM1_OnAttTransactionEx; + globalStateService.Operator = user; + na.NavigateTo("/home"); + logger.Info($"˫˵¼ģʽˡ{user.NickName}ˡ{globalStateService.Reviewer.NickName}¼"); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "ʾ", Detail = $"֤ظʹ˺", Duration = 3000 } + ); + } + } + else + { + // ʱΪһ˵¼ + globalStateService.Reviewer = user; + InvokeAsync(StateHasChanged); + loginModel = new(); + } + + } + + } else + { + FingerprintUtil.axCZKEM1.OnAttTransactionEx -= axCZKEM1_OnAttTransactionEx; + globalStateService.Operator = user; + na.NavigateTo("/home"); + logger.Info($"˵¼ģʽû{user.NickName}¼"); + } + } + + + + private void Submit(Pojo.User user) + { + Pojo.User u = userDao.GetByUsername(loginModel.Username); + if (u != null) + { + if (Util.MD5.GetMD5Hash(loginModel.Password).ToLower().Equals(u.Password)) + { + SetUser(u); + } else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "ʾ", Detail = $"", Duration = 4000 } + ); + logger.Info($"û{u.NickName}"); + + } + + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "ʾ", Detail = $"޴û", Duration = 4000 } + ); + logger.Info($"ûû{loginModel.Username}"); + } + } + + private void axCZKEM1_OnAttTransactionEx(string sEnrollNumber, int iIsInValid, int iAttState, int iVerifyMethod, int iYear, int iMonth, int iDay, int iHour, int iMinute, int iSecond, int iWorkCode) + { + + Pojo.User u = userDao.GetById(Convert.ToInt32(sEnrollNumber)); + if(u != null) + { + SetUser(u); + } else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "ʾ", Detail = $"ϵͳûIDΪ{sEnrollNumber}û", Duration = 4000 } + ); + logger.Info($"ָƻ֤ͨidΪ{sEnrollNumber}ǻݿ޴û"); + } + + } + + private void Exit() + { + + Environment.Exit(0); + } + + +} diff --git a/MasaBlazorApp3/Pages/InvoiceAdd.razor b/MasaBlazorApp3/Pages/InvoiceAdd.razor new file mode 100644 index 0000000..ae1607f --- /dev/null +++ b/MasaBlazorApp3/Pages/InvoiceAdd.razor @@ -0,0 +1,114 @@ +@page "/add/invoice" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + +
+
+
+ +@code { + @inject IInOutInvoiceDao inOutInvoiceDao; + @inject DialogService dialogService; + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? _forecasts; + string InvoiceNo; + DateTime InvoiceDate = DateTime.MinValue; + + void OnCurrentDateChanged(DateTime args) + { + InvoiceDate = new DateTime(args.Year, args.Month, args.Day); + } + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await inOutInvoiceDao.GetAllInvoiceByType(InvoiceNo, InvoiceDate, args.Top, args.Skip, 1); + // Update the Data property + _forecasts = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + InvoiceNo = ""; + InvoiceDate = DateTime.MinValue; + await grid.Reload(); + } + + async Task InvoiceSelected(InOutInvoice oi) + { + + var b = await dialogService.OpenAsync( + $"", + new Dictionary() { { "invoice", oi } }, + new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false } + ); + if (b) + { + await reloadGrid(); + } + } + + + + + +} diff --git a/MasaBlazorApp3/Pages/InvoiceAddDialog.razor b/MasaBlazorApp3/Pages/InvoiceAddDialog.razor new file mode 100644 index 0000000..430e338 --- /dev/null +++ b/MasaBlazorApp3/Pages/InvoiceAddDialog.razor @@ -0,0 +1,300 @@ +@page "/invoice/add/{invoice}" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Pojo.Vo; +@using MasaBlazorApp3.Util; +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + + + 单据号: + @(invoice?.InvoiceNo) + 时间: + @(invoice?.InvoiceDate) + + + + + + + + + + + + + + + + + + + + + + @if (status < 2) + { + + } + @if (status == 2) + { + + } + @if (status < 2) + { + + } + + + +@code { + @inject Radzen.DialogService dialogService; + @inject IInOutInvoiceDao inOutInvoiceDao; + @inject IOptions setting; + @inject NotificationService _message + @inject PortUtil PortUtil; + + RadzenDataGrid grid; + + + private readonly ILog logger = LogManager.GetLogger(typeof(InvoiceAddDialog)); + + [Parameter] public InOutInvoice invoice { get; set; } + private bool CanTakeDrug = true; + int status = 0; + + public List data { get; set; } + + async Task StartAdd() + { + if(data.Any(it => it.Quantity != it.ChannelStocks.Sum(cs => cs.AddQuantity))) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请填写正确的入库数量!", Duration = 4000 } + ); + + } else + { + await OpenDrawer(); + } + } + + async Task CancelOpera() + { + status = 0; + dialogService.Close(false); + } + + + async Task OpenDrawer() + { + this.status = 1; + // 解析需要打开的抽屉列表 + List channels = new(); + for (int i = 0; i < data.Count; i++) + { + channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.AddQuantity > 0)).ToList(); + } + + List drawerNos = channels.GroupBy(it => it.DrawerNo).Select(it => it.Key).ToList(); + + // 根据抽屉类型来决定打开前是否需要查询数量 + int index = 0; + var BeforeQuantity = new int[9]; + var AfterQuantity = new int[9]; + await new PromiseUtil().taskAsyncLoop(500, 0, async (options, next, stop) => + { + var drawerNo = drawerNos[index]; + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + if (options._data == 0) + { + BeforeQuantity = new int[9]; + AfterQuantity = new int[9]; + // 判断是否为单支抽屉 + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】"); + + await PortUtil.NoLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast().ToArray()); + } + var b = await PortUtil.OpenDrawerStatus(drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,加药"); + options._data = 1; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + PortUtil.AllLightOff(); + RestData(); + stop(); + } + } + // 检测状态 + else if (options._data == 1) + { + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + options._data = 0; + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + if (index == drawerNos.Count - 1) + { + PortUtil.SpeakAsync($"加药完成,请,点击完成按钮进行确认"); + this.status = 2; + stop(); + } + else + { + index += 1; + next(); + } + } + else + { + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + data.ForEach(cl => + { + cl.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).ToList().ForEach(cs => + { + logger.Info($"单支抽屉【{drawerNo}】,应加药品数量【{cs.AddQuantity}】,现实取数量【{AfterQuantity[cs.ColNo - 1] - BeforeQuantity[cs.ColNo - 1]}】"); + }); + + }); + } + next(); // continue iteration + } + } + + + } + } + catch (Exception e) + { + RestData(); + logger.Info($"调拨加药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + } + + async Task AddFinish() + { + + // 保存账册、操作记录 + var b = await inOutInvoiceDao.InvoiceAddFinish(data); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(data)}"); + // 关闭弹窗 + dialogService.Close(false); + } + else + { + // 关闭弹窗 + dialogService.Close(true); + + } + //重置状态 + this.RestData(); + } + + + protected override async Task OnInitializedAsync() + { + data = await inOutInvoiceDao.getAddInfoByInvoiceNo(invoice.InvoiceNo); + // 如果有库位列表未空则说明不能取药,需要增加库位 + if (data.Any(it => it.ChannelStocks.Count == 0)) + { + CanTakeDrug = false; + } + base.OnInitializedAsync(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + base.OnAfterRender(firstRender); + + if (firstRender) + { + await Task.Delay(15); + await grid.ExpandRows(grid.PagedView.Where(it => it.ChannelStocks.Count > 0)); + } + } + + + void RowRender(RowRenderEventArgs args) + { + args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0; + } + + + void OnCellClick(DataGridCellMouseEventArgs args, RadzenDataGrid Grid) + { + Grid.EditRow(args.Data); + } + + +} diff --git a/MasaBlazorApp3/Pages/InvoiceOut.razor b/MasaBlazorApp3/Pages/InvoiceOut.razor new file mode 100644 index 0000000..c828325 --- /dev/null +++ b/MasaBlazorApp3/Pages/InvoiceOut.razor @@ -0,0 +1,114 @@ +@page "/take/invoice" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + +
+
+
+ +@code { + @inject IInOutInvoiceDao inOutInvoiceDao; + @inject DialogService dialogService; + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? _forecasts; + string InvoiceNo; + DateTime InvoiceDate = DateTime.MinValue; + + void OnCurrentDateChanged(DateTime args) + { + InvoiceDate = new DateTime(args.Year, args.Month, args.Day); + } + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await inOutInvoiceDao.GetAllInvoiceByType(InvoiceNo, InvoiceDate, args.Top, args.Skip, 2); + // Update the Data property + _forecasts = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + InvoiceNo = ""; + InvoiceDate = DateTime.MinValue; + await grid.Reload(); + } + + async Task InvoiceSelected(InOutInvoice oi) + { + + var b = await dialogService.OpenAsync( + $"", + new Dictionary() { { "invoice", oi } }, + new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false } + ); + if (b) + { + await reloadGrid(); + } + } + + + + + +} diff --git a/MasaBlazorApp3/Pages/InvoiceOutDialog.razor b/MasaBlazorApp3/Pages/InvoiceOutDialog.razor new file mode 100644 index 0000000..14813a1 --- /dev/null +++ b/MasaBlazorApp3/Pages/InvoiceOutDialog.razor @@ -0,0 +1,298 @@ +@page "/invoice/out/{invoice}" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Pojo.Vo; +@using MasaBlazorApp3.Util; +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + + + + 单据号: + @(invoice?.InvoiceNo) + 时间: + @(invoice?.InvoiceDate) + + + + + + + + + + + + + + + + + + + + + + @if (status < 2) + { + + } + @if (status == 2) + { + + } + @if (status <= 2) + { + + } + + + +@code { + @inject Radzen.DialogService dialogService; + @inject IInOutInvoiceDao inOutInvoiceDao; + @inject IOptions setting; + @inject NotificationService _message + @inject PortUtil PortUtil; + + RadzenDataGrid grid; + + private readonly ILog logger = LogManager.GetLogger(typeof(InvoiceOutDialog)); + + [Parameter] public InOutInvoice invoice { get; set; } + private bool CanTakeDrug = true; + + int status = 0; + + public List data { get; set; } + + async Task StartTake() + { + if(data.Any(it => it.Quantity != it.ChannelStocks.Sum(cs => cs.TakeQuantity))) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请填写正确的出库数量!", Duration = 4000 } + ); + + } else + { + await OpenDrawer(); + } + } + async Task CancelOpera() + { + status = 0; + dialogService.Close(false); + } + async Task OpenDrawer() + { + this.status = 1; + // 解析需要打开的抽屉列表 + List channels = new(); + for(int i = 0; i < data.Count; i++) + { + channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.TakeQuantity > 0)).ToList(); + } + + List drawerNos = channels.GroupBy(it => it.DrawerNo).Select(it => it.Key).ToList(); + + // 根据抽屉类型来决定打开前是否需要查询数量 + var promiseUtil = new PromiseUtil(); + int index = 0; + var BeforeQuantity = new int[9]; + var AfterQuantity = new int[9]; + await promiseUtil.taskAsyncLoop(500, 0 , async (options, next, stop) => + { + var drawerNo = drawerNos[index]; + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + if (options._data == 0) + { + BeforeQuantity = new int[9]; + AfterQuantity = new int[9]; + // 判断是否为单支抽屉 + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】"); + + await PortUtil.HasLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast().ToArray()); + } + var b = await PortUtil.OpenDrawerStatus(drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药"); + options._data = 1; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + PortUtil.AllLightOff(); + RestData(); + stop(); + } + } + // 检测状态 + else if (options._data == 1) + { + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + options._data = 0; + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + if (index == drawerNos.Count - 1) + { + PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认"); + this.status = 2; + stop(); + } + else + { + index += 1; + next(); + } + } + else + { + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + data.ForEach(cl => + { + cl.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).ToList().ForEach(cs => + { + logger.Info($"单支抽屉【{drawerNo}】,应取药品数量【{cs.TakeQuantity}】,现实取数量【{BeforeQuantity[cs.ColNo - 1] - AfterQuantity[cs.ColNo - 1]}】"); + }); + + }); + } + next(); // continue iteration + } + } + + + } + } + catch (Exception e) + { + RestData(); + logger.Info($"调拨取药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + } + + async Task TakeFinish() + { + + // 保存账册、操作记录 + var b = await inOutInvoiceDao.InvoiceOutFinish(data); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(data)}"); + // 关闭弹窗 + dialogService.Close(false); + } + else + { + // 关闭弹窗 + dialogService.Close(true); + + } + //重置状态 + this.RestData(); + } + + + protected override async Task OnInitializedAsync() + { + data = await inOutInvoiceDao.getTakeInfoByInvoiceNo(invoice.InvoiceNo); + // 如果有【stockQuantity】字段说明有药品库存不足 + if (data.Any(it => it.ChannelStocks == null || it.ChannelStocks.Count == 0)) + { + CanTakeDrug = false; + } + base.OnInitializedAsync(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + base.OnAfterRender(firstRender); + + if (firstRender) + { + await Task.Delay(15); + await grid.ExpandRows(grid.PagedView.Where(it => it.ChannelStocks.Count > 0)); + } + } + + + void RowRender(RowRenderEventArgs args) + { + args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0; + } + + void OnCellClick(DataGridCellMouseEventArgs args, RadzenDataGrid Grid) + { + Grid.EditRow(args.Data); + } + + +} diff --git a/MasaBlazorApp3/Pages/MachineRecordList.razor b/MasaBlazorApp3/Pages/MachineRecordList.razor new file mode 100644 index 0000000..ee7df09 --- /dev/null +++ b/MasaBlazorApp3/Pages/MachineRecordList.razor @@ -0,0 +1,118 @@ +@page "/take/record/{type}" +@page "/add/record/{type}" +@page "/return/record1/{type}" +@page "/return/record2/{type}" +@page "/stock/record/{type}" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + +
+
+
+ +@code { + @inject IMachineRecordDao machineRecordDao; + @inject DialogService dialogService; + + @inject NavigationManager navigate; + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? _forecasts; + DateTime start; + DateTime end; + + + [Parameter] public string type { get; set; } + + protected override void OnParametersSet() + { + if(grid != null) + { + reloadGrid(); + } + } + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await machineRecordDao.GetMachineRecordAsync(start, end, 0, "", int.Parse(type), args.Top, args.Skip); + // Update the Data property + _forecasts = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + start = DateTime.MinValue; + end = DateTime.MinValue; + await grid.Reload(); + } + + + + + +} diff --git a/MasaBlazorApp3/Pages/OrderDetailDialog.razor b/MasaBlazorApp3/Pages/OrderDetailDialog.razor new file mode 100644 index 0000000..599b078 --- /dev/null +++ b/MasaBlazorApp3/Pages/OrderDetailDialog.razor @@ -0,0 +1,259 @@ +@page "/orderDetail/{order}" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Pojo.Vo; +@using MasaBlazorApp3.Util; +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + + + + 处方号: + @(order?.OrderNo) + 患者姓名: + @(order?.PatientName) + 性别: + @(order?.Sex) + 年龄: + @(order?.Age) + + + @if (CanTakeDrug) + { + + + + + + + + + + + + + } + else + { + + + + + + + + + } + + + + + + @if (status < 2) + { + + } + @if (status == 2) + { + + } + @if (status <= 2) + { + + } + + + +@code { + @inject Radzen.DialogService dialogService; + @inject IOrderInfoDao orderInfoDao; + @inject IChannelListDao channelListDao; + @inject IOptions setting; + @inject NotificationService _message + @inject PortUtil PortUtil; + private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog)); + + int status; + + [Parameter] public OrderInfo order { get; set; } + private bool CanTakeDrug = true; + + public List data { get; set; } + + + + protected override async Task OnInitializedAsync() + { + data = await orderInfoDao.getTakeInfoByOrderNo(order.OrderNo); + // 如果有【stockQuantity】字段说明有药品库存不足 + if (data.Any(it => it.ChannelStock == null)) + { + CanTakeDrug = false; + } + base.OnInitializedAsync(); + } + + async Task OpenDrawer() + { + this.status = 1; + // 解析需要打开的抽屉列表 + List drawerNos = this.data.GroupBy(it => it.ChannelStock.DrawerNo).Select(it => it.First()).ToList(); + + // 根据抽屉类型来决定打开前是否需要查询数量 + var promiseUtil = new PromiseUtil(); + + await promiseUtil.taskAsyncLoop(500, 0, async (options, next, stop) => + { + var orderTakeVo = drawerNos[options._data]; + var drawerNo = orderTakeVo.ChannelStock.DrawerNo; + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + if (orderTakeVo.Status == 0) + { + // 判断是否为单支抽屉 + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + orderTakeVo.BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,开抽屉前检测数量【{string.Join(",", orderTakeVo.BeforeQuantity)}】"); + + await PortUtil.HasLightOnByCol(drawerNo, data.Where(ot => ot.ChannelStock.DrawerNo == drawerNo).Select(ot => ot.ChannelStock.ColNo).ToArray()); + } + var b = await PortUtil.OpenDrawerStatus(drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药"); + orderTakeVo.Status = 1; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + PortUtil.AllLightOff(); + RestData(); + stop(); + } + } + // 检测状态 + else if (orderTakeVo.Status == 1) + { + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + + data.ForEach(cl => + { + if (cl.ChannelStock.DrawerNo == drawerNo) + { + cl.GetQuantity = cl.Quantity; + + } + }); + orderTakeVo.Status = 2; + PortUtil.AllLightOff(); + if (options._data == drawerNos.Count - 1) + { + PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认"); + this.status = 2; + stop(); + } + else + { + options._data += 1; + next(); + } + } + else + { + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + orderTakeVo.AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,抽屉未关检测数量【{string.Join(",", orderTakeVo.AfterQuantity)}】"); + + data.ForEach(cl => + { + if (cl.ChannelStock.DrawerNo == drawerNo) + { + logger.Info($"单支抽屉【{drawerNo}】,应取药品数量【{orderTakeVo.Quantity}】,现实取数量【{orderTakeVo.BeforeQuantity[cl.ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[cl.ChannelStock.ColNo - 1]}】"); + } + + }); + } + next(); // continue iteration + } + } + + + } + } + catch (Exception e) + { + RestData(); + logger.Info($"处方取药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + } + + async Task TakeFinish() + { + + // 保存账册、操作记录 + var b = await orderInfoDao.OrderTakeFinish(data); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"处方取药保存数据库失败,数据{JsonConvert.SerializeObject(data)}"); + // 关闭弹窗 + dialogService.Close(false); + } + else + { + // for (int i = 0; i < data.Count; i++) + // { + // // 判断是否为标签抽屉 + // if (setting.Value.label.Contains(data[i].ChannelStock.DrawerNo)) + // { + // //写标签数量 + // await PortUtil.WriteQuantityMethod(data[i].Quantity + data[i].GetQuantity, data[i].ChannelStock.DrawerNo, data[i].ChannelStock.ColNo); + // } + + // } + // 关闭弹窗 + dialogService.Close(true); + + } + //重置状态 + this.RestData(); + } + + +} diff --git a/MasaBlazorApp3/Pages/OrderDetailReturnDialog.razor b/MasaBlazorApp3/Pages/OrderDetailReturnDialog.razor new file mode 100644 index 0000000..b9b8b32 --- /dev/null +++ b/MasaBlazorApp3/Pages/OrderDetailReturnDialog.razor @@ -0,0 +1,280 @@ +@page "/orderDetailReturn/{order}" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Pojo.Vo; +@using MasaBlazorApp3.Util; +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + + + + 处方号: + @(order?.OrderNo) + 患者姓名: + @(order?.PatientName) + 性别: + @(order?.Sex) + 年龄: + @(order?.Age) + + + + + + + + + + + + + + + + + + + + @if(status < 2) + { + + } + @if(status == 2) + { + + } + @if(status < 2) + { + + } + + + +@code { + @inject Radzen.DialogService dialogService; + @inject IOrderInfoDao orderInfoDao; + @inject IChannelListDao channelListDao; + @inject IOptions setting; + @inject NotificationService _message + @inject PortUtil PortUtil; + private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog)); + RadzenDataGrid> grid; + + int status; + + [Parameter] public OrderInfo order { get; set; } + private bool CanReturnDrug = true; + + public List> data { get; set; } + + + + protected override async Task OnInitializedAsync() + { + data = await orderInfoDao.getReturnInfoByOrderNo(order.OrderNo); + // 如果有【stockQuantity】字段说明有药品库存不足 + if (data.Any(it => it.ChannelStocks == null)) + { + CanReturnDrug = false; + } + base.OnInitializedAsync(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + base.OnAfterRender(firstRender); + + if (firstRender) + { + await Task.Delay(15); + await grid.ExpandRows(grid.PagedView.Where(it => it.ChannelStocks.Count > 0)); + } + } + + async Task OpenDrawer() + { + this.status = 1; + // 解析需要打开的抽屉列表 + List channels = new(); + for (int i = 0; i < data.Count; i++) + { + channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.AddQuantity > 0)).ToList(); + } + + List drawerNos = channels.GroupBy(it => it.DrawerNo).Select(it => it.Key).ToList(); + + // 根据抽屉类型来决定打开前是否需要查询数量 + int index = 0; + var BeforeQuantity = new int[9]; + var AfterQuantity = new int[9]; + await new PromiseUtil().taskAsyncLoop(500, 0, async (options, next, stop) => + { + var drawerNo = drawerNos[index]; + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + if (options._data == 0) + { + BeforeQuantity = new int[9]; + AfterQuantity = new int[9]; + // 判断是否为单支抽屉 + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】"); + + await PortUtil.NoLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast().ToArray()); + } + var b = await PortUtil.OpenDrawerStatus(drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,放置退回药品"); + options._data = 1; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"处方退药抽屉【{drawerNo}】打开失败"); + PortUtil.AllLightOff(); + RestData(); + stop(); + } + } + // 检测状态 + else if (options._data == 1) + { + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + options._data = 0; + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + if (index == drawerNos.Count - 1) + { + PortUtil.SpeakAsync($"退药完成,请,点击完成按钮进行确认"); + this.status = 2; + stop(); + } + else + { + index += 1; + next(); + } + } + else + { + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + data.ForEach(cl => + { + cl.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).ToList().ForEach(cs => + { + logger.Info($"单支抽屉【{drawerNo}】,应退药品数量【{cs.AddQuantity}】,现实退数量【{AfterQuantity[cs.ColNo - 1] - BeforeQuantity[cs.ColNo - 1]}】"); + }); + + }); + } + next(); // continue iteration + } + } + + + } + } + catch (Exception e) + { + RestData(); + logger.Info($"处方退药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + } + + async Task TakeFinish() + { + + // 保存账册、操作记录 + var b = await orderInfoDao.OrderReturnFinish(data, order.OrderNo); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"处方取药保存数据库失败,数据{JsonConvert.SerializeObject(data)}"); + // 关闭弹窗 + dialogService.Close(false); + } + else + { + // 关闭弹窗 + dialogService.Close(true); + + } + //重置状态 + this.RestData(); + } + + void RowRender(RowRenderEventArgs> args) + { + args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0; + } + + + void OnCellClick(DataGridCellMouseEventArgs args, RadzenDataGrid Grid) + { + Grid.EditRow(args.Data); + } + + + +} diff --git a/MasaBlazorApp3/Pages/OrderReturn.razor b/MasaBlazorApp3/Pages/OrderReturn.razor new file mode 100644 index 0000000..af1a5b6 --- /dev/null +++ b/MasaBlazorApp3/Pages/OrderReturn.razor @@ -0,0 +1,118 @@ +@page "/return/order" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + +
+
+
+ +@code { + @inject IOrderInfoDao orderInfoDao; + @inject DialogService dialogService; + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? _forecasts; + string OrderNo; + DateTime OrderDate; + + void OnCurrentDateChanged(DateTime args) + { + OrderDate = new DateTime(args.Year, args.Month, args.Day); + } + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await orderInfoDao.GetAllCanReturnOrderInfo(OrderNo, OrderDate, args.Top, args.Skip); + // Update the Data property + _forecasts = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + OrderNo = ""; + OrderDate = DateTime.MinValue; + await grid.Reload(); + } + + async Task OrderSelected(OrderInfo oi) + { + + var b = await dialogService.OpenAsync( + $"ҩ", + new Dictionary() { { "order", oi } }, + new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false } + ); + if(b) + { + await reloadGrid(); + } + } + + + + + +} diff --git a/MasaBlazorApp3/Pages/OrderTake.razor b/MasaBlazorApp3/Pages/OrderTake.razor new file mode 100644 index 0000000..a312097 --- /dev/null +++ b/MasaBlazorApp3/Pages/OrderTake.razor @@ -0,0 +1,118 @@ +@page "/take/order" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + +
+
+
+ +@code { + @inject IOrderInfoDao orderInfoDao; + @inject DialogService dialogService; + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? _forecasts; + string OrderNo; + DateTime OrderDate; + + void OnCurrentDateChanged(DateTime args) + { + OrderDate = new DateTime(args.Year, args.Month, args.Day); + } + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await orderInfoDao.GetAllOrderInfo(OrderNo, OrderDate, args.Top, args.Skip); + // Update the Data property + _forecasts = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + OrderNo = ""; + OrderDate = DateTime.MinValue; + await grid.Reload(); + } + + async Task OrderSelected(OrderInfo oi) + { + + var b = await dialogService.OpenAsync( + $"", + new Dictionary() { { "order", oi } }, + new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false } + ); + if(b) + { + await reloadGrid(); + } + } + + + + + +} diff --git a/MasaBlazorApp3/Pages/RecordRetunDrug.razor b/MasaBlazorApp3/Pages/RecordRetunDrug.razor new file mode 100644 index 0000000..0998828 --- /dev/null +++ b/MasaBlazorApp3/Pages/RecordRetunDrug.razor @@ -0,0 +1,144 @@ +@page "/return/byRecord" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +@code { + @inject IMachineRecordDao machineRecordDao; + @inject DialogService dialogService; + RadzenDataGrid grid; + bool isLoading; + int count; + private List? _forecasts; + + DateTime start; + DateTime end; + + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await machineRecordDao.GetCanReturnRecords(start, end, 0, "", args.Top, args.Skip); + // Update the Data property + _forecasts = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + start = DateTime.MinValue; + end = DateTime.MinValue; + await grid.Reload(); + } + async Task OpenReturnDialog() + { + var list = _forecasts.Where(mr => mr.CurrentReturnQuantity > 0).ToList(); + + var b = await dialogService.OpenAsync( + $"¼ҩ", + new Dictionary() { { "records", list } }, + new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false } + ); + if (b) + { + await reloadGrid(); + } + + } + + void OnCellClick(DataGridCellMouseEventArgs args) + { + grid.EditRow(args.Data); + } + + + + +} diff --git a/MasaBlazorApp3/Pages/RecordReturnDrugDialog.razor b/MasaBlazorApp3/Pages/RecordReturnDrugDialog.razor new file mode 100644 index 0000000..2165a49 --- /dev/null +++ b/MasaBlazorApp3/Pages/RecordReturnDrugDialog.razor @@ -0,0 +1,309 @@ +@page "/return/drug/{records}" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Pojo.Vo; +@using MasaBlazorApp3.Util; +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + + + + + + + + + + + + + + + + + + + + + + + + + + @if (status < 2) + { + + } + @if (status == 2) + { + + } + @if (status < 2) + { + + } + + + +@code { + @inject Radzen.DialogService dialogService; + @inject IMachineRecordDao machineRecordDao; + @inject IOptions setting; + @inject NotificationService _message + @inject PortUtil PortUtil; + + RadzenDataGrid>> grid; + + + private readonly ILog logger = LogManager.GetLogger(typeof(InvoiceAddDialog)); + + [Parameter] public List records { get; set; } + private bool CanTakeDrug = true; + int status = 0; + + public List>> data { get; set; } + + async Task StartAdd() + { + if(data.Any(it => it.Quantity != it.ChannelStocks.Sum(cs => cs.ReturnQuantity))) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请填写正确的入库数量!", Duration = 4000 } + ); + + } else + { + await OpenDrawer(); + } + } + + async Task CancelOpera() + { + status = 0; + dialogService.Close(false); + } + + + async Task OpenDrawer() + { + this.status = 1; + // 解析需要打开的抽屉列表 + List channels = new(); + for (int i = 0; i < data.Count; i++) + { + channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.ReturnQuantity > 0)).ToList(); + } + if (channels.Count == 0) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请填写正确的入库数量!", Duration = 4000 } + ); + return; + } + + List drawerNos = channels.GroupBy(it => it.DrawerNo).Select(it => it.Key).ToList(); + + // 根据抽屉类型来决定打开前是否需要查询数量 + int index = 0; + var BeforeQuantity = new int[9]; + var AfterQuantity = new int[9]; + await new PromiseUtil().taskAsyncLoop(500, 0, async (options, next, stop) => + { + var drawerNo = drawerNos[index]; + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + if (options._data == 0) + { + BeforeQuantity = new int[9]; + AfterQuantity = new int[9]; + // 判断是否为单支抽屉 + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】"); + + await PortUtil.NoLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast().ToArray()); + } + var b = await PortUtil.OpenDrawerStatus(drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,加药"); + options._data = 1; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + PortUtil.AllLightOff(); + RestData(); + stop(); + } + } + // 检测状态 + else if (options._data == 1) + { + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + options._data = 0; + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + if (index == drawerNos.Count - 1) + { + PortUtil.SpeakAsync($"加药完成,请,点击完成按钮进行确认"); + this.status = 2; + stop(); + } + else + { + index += 1; + next(); + } + } + else + { + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + data.ForEach(cl => + { + cl.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).ToList().ForEach(cs => + { + logger.Info($"单支抽屉【{drawerNo}】,应加药品数量【{cs.AddQuantity}】,现实取数量【{AfterQuantity[cs.ColNo - 1] - BeforeQuantity[cs.ColNo - 1]}】"); + }); + + }); + } + next(); // continue iteration + } + } + + + } + } + catch (Exception e) + { + RestData(); + logger.Info($"调拨加药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + } + + async Task AddFinish() + { + + // 保存账册、操作记录 + var b = await machineRecordDao.ReturnDrugFinish(data); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(data)}"); + // 关闭弹窗 + dialogService.Close(false); + } + else + { + // 关闭弹窗 + dialogService.Close(true); + + } + //重置状态 + this.RestData(); + } + + + protected override async Task OnInitializedAsync() + { + data = await machineRecordDao.getReturnDrugInfoByRecords(records); + // 如果有库位列表未空则说明不能取药,需要增加库位 + if (data.Any(it => it.ChannelStocks.Count == 0)) + { + CanTakeDrug = false; + } + base.OnInitializedAsync(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + base.OnAfterRender(firstRender); + + if (firstRender) + { + await Task.Delay(15); + await grid.ExpandRows(grid.PagedView.Where(it => it.ChannelStocks.Count > 0)); + } + } + + + void RowRender(RowRenderEventArgs>> args) + { + args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0; + } + + + void OnCellClick(DataGridCellMouseEventArgs args, RadzenDataGrid Grid) + { + Grid.EditRow(args.Data); + } + + +} diff --git a/MasaBlazorApp3/Pages/RecordReturnEmpty.razor b/MasaBlazorApp3/Pages/RecordReturnEmpty.razor new file mode 100644 index 0000000..5e40ba3 --- /dev/null +++ b/MasaBlazorApp3/Pages/RecordReturnEmpty.razor @@ -0,0 +1,129 @@ +@page "/return/empty" + + +
+
+ @*
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
*@ +
+ + + @* + + + + *@ + + + + @* *@ + + + + + @* + + + + *@ + + +
+
+
+ +@code { + @inject IMachineRecordDao machineRecordDao; + @inject DialogService dialogService; + @inject NotificationService _message + RadzenDataGrid grid; + bool isLoading; + int count; + private List? _forecasts; + + // DateTime start; + // DateTime end; + + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + _forecasts = await machineRecordDao.GetReturnEmptyWithCanReturnQuantiy(); + // _forecasts = await machineRecordDao.GetReturnEmpty(); + + isLoading = false; + } + + async Task reloadGrid() + { + await grid.Reload(); + } + async Task OnCellClick(DataGridCellMouseEventArgs args) + { + if (string.IsNullOrEmpty(args.Data.DrugId)) + { + _message.Notify( + new NotificationMessage { Style = "position: absolute; inset-inline-start: -1000px;", Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"该库位无药品,请先绑药!", Duration = 4000 } + ); + return; + } + // grid.EditRow(args.Data); + var list = args.Data;// _forecasts.Where(mr => mr.DrawerNo > 0).ToList(); + + var b = await dialogService.OpenAsync( + $"归还空瓶", + new Dictionary() { { "records", list } }, + new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false } + ); + if (b) + { + await reloadGrid(); + } + } +} diff --git a/MasaBlazorApp3/Pages/RecordReturnEmptyDialog.razor b/MasaBlazorApp3/Pages/RecordReturnEmptyDialog.razor new file mode 100644 index 0000000..d7f45ba --- /dev/null +++ b/MasaBlazorApp3/Pages/RecordReturnEmptyDialog.razor @@ -0,0 +1,305 @@ +@page "/return/empty/{records}" +@using MasaBlazorApp3.Pojo.Config; +@using MasaBlazorApp3.Pojo.Vo; +@using MasaBlazorApp3.Util; +@using Microsoft.Extensions.Options; +@using Newtonsoft.Json; +@using log4net; + + + + + 药品:@drugName + + + 规格:@drugSpec + + + 厂家:@drugManufactory + + + 可还空瓶数:@emptyQuantity + + + + + + + + + 选择 + + + + + + + + + + + + + + + + + + + + + @if (status < 2) + { + + } + @if (status == 2) + { + + } + @if (status < 2) + { + + } + +@code +{ + @inject IMachineRecordDao machineRecordDao; + @inject Radzen.DialogService dialogService; + @inject IMachineRecordDao machineRecordDao; + @inject IOptions setting; + @inject NotificationService _message + @inject PortUtil PortUtil; + + [Parameter] + public ChannelStock records { get; set; } + // public PageData data { get; set; } + string drugName = string.Empty; + string drugSpec = string.Empty; + string drugManufactory = string.Empty; + int emptyQuantity = 0; + + RadzenDataGrid grid; + bool isLoading; + int count; + private List? _returnEmptys; + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + drugName = records.Drug.DrugName; + drugSpec = records.Drug.DrugSpec; + drugManufactory = records.Drug.Manufactory; + + var result = await machineRecordDao.getReturnEmptyInfoByRecords(records); + // Update the Data property + _returnEmptys = result.Desserts; + emptyQuantity = _returnEmptys.Sum(it=>it.Quantity-it.ReturnQuantity1-it.ReturnQuantity2); + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + await grid.Reload(); + } + void OnCellClick(DataGridCellMouseEventArgs args) + { + MachineRecord machineRecord = args.Data; + grid.EditRow(machineRecord); + if (machineRecord.CurrentReturnQuantity > 0 && args.Column.ColumnPickerTitle == "本次归还") + { + machineRecord.IsSelected = true; + } + else + { + machineRecord.IsSelected = !machineRecord.IsSelected; + if (machineRecord.IsSelected) + { + machineRecord.CurrentReturnQuantity = machineRecord.Quantity - machineRecord.ReturnQuantity1 - machineRecord.ReturnQuantity2; + } + else + { + machineRecord.CurrentReturnQuantity = 0; + } + } + } + + + private readonly ILog logger = LogManager.GetLogger(typeof(RecordReturnEmptyDialog)); + int status = 0; + async Task StartAdd() + { + if (_returnEmptys.Where(it => it.CurrentReturnQuantity>0).Count()<=0) + { + _message.Notify( + new NotificationMessage { Style = "position: absolute; inset-inline-start: -1000px;", Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择药品!", Duration = 4000 } + ); + + } + else + { + await OpenDrawer(); + } + } + + async Task CancelOpera() + { + status = 0; + dialogService.Close(false); + } + + + async Task OpenDrawer() + { + this.status = 1; + // 解析需要打开的抽屉列表 + + int drawerNo = records.DrawerNo; + + // 根据抽屉类型来决定打开前是否需要查询数量 + int index = 0; + var BeforeQuantity = new int[9]; + var AfterQuantity = new int[9]; + await new PromiseUtil().taskAsyncLoop(500, 0, async (options, next, stop) => + { + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + if (options._data == 0) + { + BeforeQuantity = new int[9]; + AfterQuantity = new int[9]; + // 判断是否为单支抽屉 + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】"); + + //await PortUtil.NoLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast().ToArray()); + } + var b = await PortUtil.OpenDrawerStatus(drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请放入空瓶"); + options._data = 1; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + PortUtil.AllLightOff(); + RestData(); + stop(); + } + } + // 检测状态 + else if (options._data == 1) + { + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + options._data = 0; + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + PortUtil.SpeakAsync($"加药完成,请,点击完成按钮进行确认"); + this.status = 2; + stop(); + } + else + { + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉【{drawerNo}】,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + // data.ForEach(cl => + // { + // cl.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).ToList().ForEach(cs => + // { + // logger.Info($"单支抽屉【{drawerNo}】,应还空瓶数量【{cs.AddQuantity}】,现实还数量【{AfterQuantity[cs.ColNo - 1] - BeforeQuantity[cs.ColNo - 1]}】"); + // }); + + // }); + } + next(); // continue iteration + } + } + + + } + } + catch (Exception e) + { + RestData(); + logger.Info($"还空瓶发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + } + + async Task AddFinish() + { + + // 保存账册、操作记录 + var b = await machineRecordDao.ReturnEmptyFinish(_returnEmptys.Where(it => it.CurrentReturnQuantity > 0).ToList(), records); + if (!b) + { + _message.Notify(new NotificationMessage { Style = "position: absolute; inset-inline-start: -1000px;", Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"还空瓶保存数据库失败,数据{JsonConvert.SerializeObject(_returnEmptys)}"); + // 关闭弹窗 + dialogService.Close(false); + } + else + { + // 关闭弹窗 + dialogService.Close(true); + _message.Notify(new NotificationMessage { Style = "position: absolute; inset-inline-start: -1000px;", Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"还空瓶操作完成!", Duration = 4000 }); + + } + //重置状态 + this.RestData(); + } +} diff --git a/MasaBlazorApp3/Pages/ReturnRecord2.razor b/MasaBlazorApp3/Pages/ReturnRecord2.razor new file mode 100644 index 0000000..b0585d5 --- /dev/null +++ b/MasaBlazorApp3/Pages/ReturnRecord2.razor @@ -0,0 +1,101 @@ +@page "/return/record2" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + +
+
+
+ +@code { + @inject IMachineRecordDao machineRecordDao; + @inject DialogService dialogService; + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? _forecasts; + DateTime start; + DateTime end; + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await machineRecordDao.GetMachineRecordAsync(start, end, 0, "", 32, args.Top, args.Skip); + // Update the Data property + _forecasts = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + start = DateTime.MinValue; + end = DateTime.MinValue; + await grid.Reload(); + } + + + + + +} diff --git a/MasaBlazorApp3/Pages/Role.razor b/MasaBlazorApp3/Pages/Role.razor new file mode 100644 index 0000000..1a0a924 --- /dev/null +++ b/MasaBlazorApp3/Pages/Role.razor @@ -0,0 +1,268 @@ +@page "/manage/role" + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + @string.Join(", ", allPremissions.Where(g => role.permissionIds?.Contains(g.Id) == true).Take(dd.MaxSelectedLabels).Select(g => $"{g.PremissionName}")) + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +@code { + @inject IRoleDao roleDao; + @inject DialogService dialogService; + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? roleList; + + + RadzenDropDown> dd; + IEnumerable allPremissions; + + string RoleName; + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + List t = new Premission().getAdminPremission(); + IEnumerable t2 = Enumerable.Empty(); + for (var i = 0; i < t.Count; i++) + { + t2 = t2.Concat(new Premission[] { t[i] }); + t2 = t2.Concat(t[i].Items); + } + + allPremissions = t2; + } + + + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await roleDao.GetRolesByName(RoleName, args.Top, args.Skip); + // Update the Data property + roleList = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + RoleName = ""; + await grid.Reload(); + } + + + List rolesToInsert = new List(); + List rolesToUpdate = new List(); + + void Reset() + { + rolesToInsert.Clear(); + rolesToUpdate.Clear(); + } + + void Reset(Pojo.Role role) + { + rolesToInsert.Remove(role); + rolesToUpdate.Remove(role); + } + + async Task EditRow(Pojo.Role role) + { + + Reset(); + + rolesToUpdate.Add(role); + await grid.EditRow(role); + } + + void OnUpdateRow(Pojo.Role role) + { + Reset(role); + + // 数据库更新 + roleDao.UpdateRole(role); + } + + async Task SaveRow(Pojo.Role role) + { + await grid.UpdateRow(role); + } + + void CancelEdit(Pojo.Role role) + { + Reset(role); + + grid.CancelEditRow(role); + grid.Reload(); + } + + async Task DeleteRow(Pojo.Role role) + { + Reset(role); + + if (roleList.Contains(role)) + { + //弹出确认提示框 + var b = await dialogService.OpenAsync( + $"删除确认", + new Dictionary() { { "confirmInfo", "删除角色:" + role.RoleName } }, + new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false }); + if (b) + { + // 数据库删除 + roleDao.DeleteRole(role.Id); + } + await grid.Reload(); + } + else + { + grid.CancelEditRow(role); + await grid.Reload(); + } + } + + async Task InsertRow() + { + + Reset(); + var role = new Pojo.Role(); + rolesToInsert.Add(role); + await grid.InsertRow(role); + } + + void OnCreateRow(Pojo.Role role) + { + // 数据库添加用户 + int id = roleDao.InsertRole(role); + rolesToInsert.Remove(role); + grid.Reload(); + } + + void ItemRender(DropDownItemRenderEventArgs> args) + { + // Use this code to prevent default item selection. + args.Disabled = true; + args.Attributes.Add("style", $"opacity:1;{(((Premission)args.Item).Parent == null ? "" : "margin-inline-start:1rem")}"); + } + + + + + + bool? IsGroupSelected(Pojo.Role role,Premission p) + { + IEnumerable permissionIds = role.permissionIds; + if (p.Parent == null) + { + return p.Items.Any() && p.Items.All(i => permissionIds?.Contains(i.Id) == true) ? true : + p.Items.Any(i => permissionIds?.Contains(i.Id) == true) ? null : false; + } + + return permissionIds?.Contains(p.Id) == true; + } + + void SelectGroup(bool? value, Pojo.Role role, Premission p) + { + IEnumerable permissionIds = role.permissionIds; + var newValues = permissionIds ?? Enumerable.Empty(); + var items = p.Parent == null ? p.Items.Select(i => i.Id) : new int[] { p.Id }; + role.permissionIds = value == true ? newValues.Concat(items) : newValues.Except(items); + } + + + + +} diff --git a/MasaBlazorApp3/Pages/SelfTake.razor b/MasaBlazorApp3/Pages/SelfTake.razor new file mode 100644 index 0000000..dc57df3 --- /dev/null +++ b/MasaBlazorApp3/Pages/SelfTake.razor @@ -0,0 +1,294 @@ +@page "/take/self" +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + @* *@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+@code { + @inject IChannelListDao channelListDao; + @inject IDrugInfoDao drugInfoDao; + @inject NotificationService _message + @inject DialogService dialogService; + RadzenDataGrid grid; + List orderDetails = new(); + + List drugInfos = new(); + + List detailsToInsert = new(); + List detailsToUpdate = new(); + + + OrderInfo orderInfo = new OrderInfo() + { + OrderDate = DateTime.Now + }; + + + + void Reset() + { + detailsToInsert.Clear(); + detailsToUpdate.Clear(); + } + void Reset(OrderDetail orderDetail) + { + detailsToInsert.Remove(orderDetail); + detailsToUpdate.Remove(orderDetail); + } + + async Task InsertRow() + { + + Reset(); + var orderDetail = new OrderDetail(); + detailsToInsert.Add(orderDetail); + await grid.InsertRow(orderDetail); + } + + async Task EditRow(OrderDetail orderDetail) + { + + Reset(); + + detailsToUpdate.Add(orderDetail); + await grid.EditRow(orderDetail); + } + + async Task SaveRow(OrderDetail orderDetail) + { + await grid.UpdateRow(orderDetail); + } + + void CancelEdit(OrderDetail orderDetail) + { + Reset(orderDetail); + + grid.CancelEditRow(orderDetail); + grid.Reload(); + } + + async Task DeleteRow(OrderDetail orderDetail) + { + Reset(orderDetail); + orderDetails.Remove(orderDetail); + grid.CancelEditRow(orderDetail); + await grid.Reload(); + } + + void OnUpdateRow(OrderDetail orderDetail) + { + Reset(orderDetail); + + grid.Reload(); + } + + void OnCreateRow(OrderDetail orderDetail) + { + // 数据库添加用户 + detailsToInsert.Remove(orderDetail); + orderDetails.Add(orderDetail); + grid.Reload(); + } + + async void Submit(OrderInfo orderInfo) + { + if (orderDetails.Count == 0) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请添加用药详情", Duration = 3000 } + ); + } + else + { + //弹出待取药品所在库位、库存信息 + var b = await dialogService.OpenAsync( + $"取药详情", + new Dictionary() { { "order", orderInfo }, { "orderDetails", orderDetails } }, + new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false } + ); + if (b) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"取药完成", Duration = 3000 } + ); + } + } + } + async Task reloadGrid() + { + + await grid.Reload(); + } + bool ValidateDrug(DrugInfo drugInfo) + { + return !orderDetails.Any(od => od.Drug.DrugId.Equals(drugInfo?.DrugId)); + } + + protected override async Task OnInitializedAsync() + { + drugInfos = await drugInfoDao.GetAllDrugAndStock(); + + base.OnInitializedAsync(); + } + + void OnCurrentDateChanged(DateTime args) + { + orderInfo.OrderDate = new DateTime(args.Year, args.Month, args.Day, args.Hour, args.Minute, args.Second); + } +} diff --git a/MasaBlazorApp3/Pages/SelfTakeDialog.razor b/MasaBlazorApp3/Pages/SelfTakeDialog.razor new file mode 100644 index 0000000..c259387 --- /dev/null +++ b/MasaBlazorApp3/Pages/SelfTakeDialog.razor @@ -0,0 +1,247 @@ +@page "/selfDetail/{order}" +@using MasaBlazorApp3.Pojo.Config +@using MasaBlazorApp3.Pojo.Vo +@using MasaBlazorApp3.Util +@using Microsoft.Extensions.Options +@using Newtonsoft.Json +@using log4net + + + + + 处方号: + @(order?.OrderNo) + 患者姓名: + @(order?.PatientName) + 性别: + @(order?.Sex) + 年龄: + @(order?.Age) + + + @if (CanTakeDrug) + { + + + + + + + + + + + + + } + else + { + + + + + + + + + } + + + + + + @if (status < 2) + { + + } + @if (status == 2) + { + + } + @if (status <= 2) + { + + } + + +@code { +@inject Radzen.DialogService dialogService; + @inject NotificationService _message + @inject PortUtil PortUtil; + @inject ISelfTakeDao selfTakeDao; + @inject IOptions setting; + private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog)); + + int status; + + [Parameter] public OrderInfo order { get; set; } + [Parameter] public List orderDetails{ get; set; } + + private bool CanTakeDrug = true; + + public List data { get; set; } + protected override async Task OnInitializedAsync() + { + data = await selfTakeDao.getTakeInfoByOrderNo(orderDetails); + // 如果有【stockQuantity】字段说明有药品库存不足 + if (data.Any(it => it.ChannelStock == null)) + { + CanTakeDrug = false; + } + base.OnInitializedAsync(); + } + + async Task OpenDrawer() + { + this.status = 1; + // 解析需要打开的抽屉列表 + List drawerNos = this.data.GroupBy(it => it.ChannelStock.DrawerNo).Select(it => it.First()).ToList(); + + // 根据抽屉类型来决定打开前是否需要查询数量 + var promiseUtil = new PromiseUtil(); + + await promiseUtil.taskAsyncLoop(500, 0, async (options, next, stop) => + { + var orderTakeVo = drawerNos[options._data]; + var drawerNo = orderTakeVo.ChannelStock.DrawerNo; + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + if (orderTakeVo.Status == 0) + { + // 判断是否为单支抽屉 + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + orderTakeVo.BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,开抽屉前检测数量【{string.Join(",", orderTakeVo.BeforeQuantity)}】"); + + await PortUtil.HasLightOnByCol(drawerNo, data.Where(ot => ot.ChannelStock.DrawerNo == drawerNo).Select(ot => ot.ChannelStock.ColNo).ToArray()); + } + var b = await PortUtil.OpenDrawerStatus(drawerNo); + if (b) + { + PortUtil.Operate = true; + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药"); + orderTakeVo.Status = 1; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + PortUtil.AllLightOff(); + RestData(); + stop(); + } + } + // 检测状态 + else if (orderTakeVo.Status == 1) + { + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + + data.ForEach(cl => + { + if (cl.ChannelStock.DrawerNo == drawerNo) + { + cl.GetQuantity = cl.Quantity; + + } + }); + PortUtil.Operate = false; + orderTakeVo.Status = 2; + PortUtil.AllLightOff(); + if (options._data == drawerNos.Count - 1) + { + PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认"); + this.status = 2; + stop(); + } + else + { + options._data += 1; + next(); + } + } + else + { + if (setting.Value.single.Contains(drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo); + orderTakeVo.AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,抽屉未关检测数量【{string.Join(",", orderTakeVo.AfterQuantity)}】"); + + data.ForEach(cl => + { + if (cl.ChannelStock.DrawerNo == drawerNo) + { + logger.Info($"单支抽屉【{drawerNo}】,应取药品数量【{orderTakeVo.Quantity}】,现实取数量【{orderTakeVo.BeforeQuantity[cl.ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[cl.ChannelStock.ColNo - 1]}】"); + } + + }); + } + next(); // continue iteration + } + } + + + } + } + catch (Exception e) + { + RestData(); + logger.Info($"处方取药发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(drawerNo)) + { + PortUtil.AllLightOff(); + } + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + } + + async Task TakeFinish() + { + + // 保存账册、操作记录 + var b = await selfTakeDao.OrderTakeFinish(data,order); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"自选取药保存数据库失败,数据{JsonConvert.SerializeObject(data)}"); + // 关闭弹窗 + dialogService.Close(false); + } + else + { + // 关闭弹窗 + dialogService.Close(true); + + } + //重置状态 + this.RestData(); + } + +} diff --git a/MasaBlazorApp3/Pages/SignatureDialog.razor b/MasaBlazorApp3/Pages/SignatureDialog.razor new file mode 100644 index 0000000..86176ff --- /dev/null +++ b/MasaBlazorApp3/Pages/SignatureDialog.razor @@ -0,0 +1,66 @@ +@page "/signature/{user}" +@layout EmptyLayout + + @if (user.Sign != null) + { + + } +
+ +
+ + + + + +
+ + +
+
+ +@code { + @inject IJSRuntime JsRuntime; + @inject NotificationService _message; + @inject IUserDao userDao; + private IJSObjectReference module; + @inject DialogService dialogService; + [Parameter] public Pojo.User user { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + // 导入。路径是相对wwwroot写的,其他位置参考顶部链接 + module = await JsRuntime.InvokeAsync("import", "./signatureInit.js"); + await module.InvokeVoidAsync("createSignatrue"); + } + + } + + async Task handleClear() + { + await module.InvokeVoidAsync("clear"); + } + async Task handleUndo() + { + await module.InvokeVoidAsync("undo"); + } + async Task handlePreview() + { + bool flag = await module.InvokeAsync("isEmpty"); + if (flag) + { + } + else + { + string base64 = await module.InvokeAsync("getPNG"); + + await userDao.UpdateSign(user.Id, base64.Split(",")[1]); + + dialogService.Close(true); + + } + } + +} diff --git a/MasaBlazorApp3/Pages/StockBinding.razor b/MasaBlazorApp3/Pages/StockBinding.razor new file mode 100644 index 0000000..918cb8b --- /dev/null +++ b/MasaBlazorApp3/Pages/StockBinding.razor @@ -0,0 +1,290 @@ +@page "/stock/binding" + + +
+
+ @*
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
*@ +
+ + + + +
+
+
+ +@code { + @inject IChannelListDao channelListDao; + @inject IDrugInfoDao drugInfoDao; + @inject DialogService dialogService; + @inject NotificationService _message + RadzenDataList grid; + bool isLoading; + int count; + private IEnumerable? _forecasts; + + List drugInfos; + List drugManuNos; + + DrugInfo drugInfo; + + DrugManuNo drugManuNo; + + + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + //drugInfos = await drugInfoDao.GetAllDrug(); + } + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + // var result = await channelListDao.GetAllChannelList(0, "", args.Top, args.Skip); + var result = await channelListDao.GetAllChannelListWithDrug(0, "", args.Top, args.Skip); + + // Update the Data property + _forecasts = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + + drugInfos = result.Other; + } + + async Task reloadGrid() + { + await grid.Reload(); + } + + async Task EditChannel(ChannelStock stock) + { + if(stock.drugManuNo != null) + { + // 说明之前有绑定并且未改变,那么就是在进行解绑 + if(stock.drugManuNo.ManuNo.Equals(stock.ManuNo)) + { + var b = await channelListDao.UnBind(stock.Id); + if(b) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"解除绑定成功", Duration = 4000 } + ); + await reloadGrid(); + } + + } + // 否则是进行绑定 + else + { + var b = await channelListDao.Bind(stock); + if (b) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"绑定成功", Duration = 4000 } + ); + await reloadGrid(); + } + } + } else + { + if (stock.Drug != null) + { + // 说明只设置了药品 + var b = await channelListDao.Bind(stock); + if (b) + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"绑定成功", Duration = 4000 } + ); + await reloadGrid(); + } + } + // 什么都没有选择或者么有改变,只是点击了按钮,此时不操作 + else + { + + } + } + } + + + + + +} diff --git a/MasaBlazorApp3/Pages/StockCheck.razor b/MasaBlazorApp3/Pages/StockCheck.razor new file mode 100644 index 0000000..c4ff064 --- /dev/null +++ b/MasaBlazorApp3/Pages/StockCheck.razor @@ -0,0 +1,307 @@ +@page "/stock/check" +@using MasaBlazorApp3.Pojo.Config +@using MasaBlazorApp3.Util +@using Microsoft.Extensions.Options +@using Newtonsoft.Json +@using log4net + + + +
+
+ @* *@ +
+ @foreach (int i in DrawerNos) + { + + + } +
+ @*
*@ +
+
+ + + + @if (status < 3) + { + + } + @if (status == 3) + { + + } + @if (status > 0 && status <= 3) + { + + } + + + + + + + + + + + + @if (channel.Quantity == 0 && !String.IsNullOrEmpty(channel.DrugId)) + { + + + + + @((context as DrugManuNo)?.ManuNo) + @((context as DrugManuNo)?.EffDate) + + + + + } + else + { + + @channel.drugManuNo?.ManuNo + @channel.drugManuNo?.EffDate + } + + + + + + + + @if (cs.BoardType == 2) + { + @cs.CheckQuantity + } + else + { + + + } + + + + + +
+@code { + @inject IChannelListDao channelListDao; + @inject NavigationManager na; + @inject PortUtil PortUtil; + @inject NotificationService _message + @inject IOptions setting; + int status = 0; + int drawerNo = 1; + RadzenDataGrid grid; + private List? channels; + bool isLoading; + int count; + int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + int[] BeforeQuantity = new int[9]; + int[] AfterQuantity = new int[9]; + private readonly ILog logger = LogManager.GetLogger(typeof(DrawerAdd)); + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await channelListDao.GetChannelStockByDrawerNoWithDrawers(drawerNo); + // var result = await channelListDao.GetChannelStockByDrawerNo(drawerNo); + // Update the Data property + DrawerNos = result.DrawerArray; + // for (int i = 0; i < result.ChannelStocks.Count; i++) + // { + // result.ChannelStocks[i].CheckQuantity = result.ChannelStocks[i].Quantity; + // } + result.ChannelStocks.ForEach(cs => cs.CheckQuantity = cs.Quantity); + channels = result.ChannelStocks; + // Update the count + count = result.ChannelStocks.Count; + + + isLoading = false; + } + async Task OpenDrawer() + { + this.status = 1; + // 根据抽屉类型来决定打开前是否需要查询数量 + var promiseUtil = new PromiseUtil(); + await promiseUtil.taskAsyncLoop(500, null, async (data, next, stop) => + { + try + { + if (this.status == 0) + { + stop(); + } + // 开启抽屉 + else if (this.status == 1) + { + // 判断是否为单支抽屉 + if (setting.Value.single.Contains(this.drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo); + BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】"); + } + var b = await PortUtil.OpenDrawerStatus(this.drawerNo); + if (b) + { + PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,盘点"); + this.status = 2; + next(); + } + else + { + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 } + ); + logger.Info($"抽屉打开失败"); + RestData(); + stop(); + } + + } + // 检测状态 + else if (this.status == 2) + { + // 查询抽屉是否为关闭状态 + var b = await PortUtil.CheckDrawerStatus2(drawerNo); + // 关闭则改变状态并终止循环 + if (b) + { + PortUtil.SpeakAsync($"盘点完成,请,核对,或,录入,正确的,盘点数量"); + this.status = 3; + stop(); + } + else + { + if (setting.Value.single.Contains(this.drawerNo)) + { + byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo); + AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray(); + logger.Info($"单支抽屉,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】"); + + channels.ForEach(cl => + { + cl.CheckQuantity = this.AfterQuantity[cl.ColNo - 1];// - this.BeforeQuantity[cl.ColNo - 1]; + }); + } + next(); // continue iteration + } + + } + } + catch (Exception e) + { + logger.Info($"抽屉盘点发生错误,{e.Message}"); + _message.Notify( + new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 } + ); + if (setting.Value.single.Contains(this.drawerNo)) + { + PortUtil.AllLightOff(); + } + RestData(); + stop(); + } + }); + } + + void RestData() + { + this.status = 0; + this.BeforeQuantity = new int[9]; + this.AfterQuantity = new int[9]; + } + + async Task CheckFinish() + { + if (channels.Any(cl => cl.CheckQuantity != cl.Quantity && cl.DrugId != null && cl.drugManuNo != null)) + { + // 保存账册、操作记录 + var b = await channelListDao.DrawerCheckFinish(channels.Where(cl => cl.CheckQuantity != cl.Quantity).ToList()); + if (!b) + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 }); + logger.Error($"盘点保存数据库失败,数据{JsonConvert.SerializeObject(channels)}"); + } + else + { + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Info, Summary = "提示", Detail = $"盘点完成", Duration = 4000 }); + logger.Error($"盘点完成"); + + } + } + + //重置状态 + this.RestData(); + // 重新查询库存 + await grid.Reload(); + } + + void Cancel() + { + this.status = 0; + } + + void SelectDrawer(int drawerNo) + { + this.drawerNo = drawerNo; + grid.Reload(); + } + + void OnCellClick(DataGridCellMouseEventArgs args) + { + grid.EditRow(args.Data); + } + private IDisposable? registration; + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + registration = na.RegisterLocationChangingHandler(OnLocationChanging); + } + } + + private ValueTask OnLocationChanging(LocationChangingContext context) + { + // 操作中不可跳转页面 + if (status > 0) + { + context.PreventNavigation(); //阻止导航 + } + return ValueTask.CompletedTask; + } + //在生命周期函数Dispose中,移除订阅的事件,并销毁非托管资源registration=========================================== + public void Dispose() + { + registration?.Dispose(); + } +} diff --git a/MasaBlazorApp3/Pages/StockList.razor b/MasaBlazorApp3/Pages/StockList.razor new file mode 100644 index 0000000..300a7ca --- /dev/null +++ b/MasaBlazorApp3/Pages/StockList.razor @@ -0,0 +1,90 @@ +@page "/stock/list" + + +
+ + + + + + + + + + + + + + + +
+ +@code { + @inject IDrugInfoDao drugInfoDao; + @inject DialogService dialogService; + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? _forecasts; + DateTime start; + DateTime end; + + + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + isLoading = true; + + var result = await drugInfoDao.GetAllDrugAndStock(); + // Update the Data property + _forecasts = result; + isLoading = false; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + base.OnAfterRender(firstRender); + + if (firstRender) + { + await grid.ExpandRows(grid.PagedView.Where(di => di.Stocks.Count > 0)); + } + } + + void RowRender(RowRenderEventArgs args) + { + args.Expandable = args.Data.Stocks.Count > 0; + } + + + + + + + +} diff --git a/MasaBlazorApp3/Pages/TEST.razor b/MasaBlazorApp3/Pages/TEST.razor new file mode 100644 index 0000000..a283c7b --- /dev/null +++ b/MasaBlazorApp3/Pages/TEST.razor @@ -0,0 +1,87 @@ +@page "/TEST" +@layout EmptyLayout + + + + + + + @* TextProperty="@(PropertyAccess.GetDynamicPropertyExpression("LastName", typeof(string)))"> *@ + + @string.Join(", ", columns.Where(c => c.Value == typeof(string)).Take(grid.MaxSelectedLabels).Select(c => context[c.Key])) + + + @foreach (var column in columns) + { + + @* Property="@PropertyAccess.GetDynamicPropertyExpression(column.Key, column.Value)"> *@ + + + } + + + + + +@code { + RadzenDropDownDataGrid> grid; + IDictionary selectedItem; + + public IEnumerable> data { get; set; } + + public IDictionary columns { get; set; } + + public enum EnumTest + { + EnumValue1, + EnumValue2 + } + + void OnChange(object value) + { + selectedItem = (IDictionary)value; + } + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + columns = new Dictionary() + { + { "EmployeeID", typeof(int) }, + { "MyColumn", typeof(EnumTest) }, + { "FirstName", typeof(string) }, + { "LastName", typeof(string) }, + { "HireDate", typeof(DateTime) }, + }; + + foreach (var i in Enumerable.Range(0, 50)) + { + columns.Add($"Column{i}", typeof(string)); + } + + data = Enumerable.Range(0, 100).Select(i => + { + var row = new Dictionary(); + + foreach (var column in columns) + { + row.Add( + column.Key, + column.Value == typeof(EnumTest) + ? (i % 2 == 0 ? EnumTest.EnumValue1 : EnumTest.EnumValue2) + : column.Value == typeof(int) + ? i + : column.Value == typeof(DateTime) + ? DateTime.Now.AddMonths(i) + : $"{column.Key}{i}" + ); + } + + return row; + }); + } +} diff --git a/MasaBlazorApp3/Pages/User.razor b/MasaBlazorApp3/Pages/User.razor new file mode 100644 index 0000000..99efefb --- /dev/null +++ b/MasaBlazorApp3/Pages/User.razor @@ -0,0 +1,306 @@ +@page "/manage/user" + +@using log4net; + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +@code { + @inject IUserDao userDao; + @inject IRoleDao roleDao; + @inject DialogService dialogService; + @inject NotificationService _message + RadzenDataGrid grid; + bool isLoading; + int count; + private IEnumerable? userList; + string nickname; + DateTime OrderDate; + private readonly ILog logger = LogManager.GetLogger(typeof(Pages.User)); + + List roles; + + + + + List usersToInsert = new List(); + List usersToUpdate = new List(); + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + roles = await roleDao.GetAllRoles(); + } + + void Reset() + { + usersToInsert.Clear(); + usersToUpdate.Clear(); + } + + async Task Reg2ZWJ(Pojo.User user) + { + await dialogService.OpenAsync( + $"录入指纹", + new Dictionary() { { "userId", user.Id } }, + new DialogOptions() { Width = "55vw", Resizable = true, Draggable = true, ShowClose = false } + ); + } + + async Task Signatrue(Pojo.User user) + { + var flag = await dialogService.OpenAsync( + $"签名-{user.NickName}", + new Dictionary() { { "user", user } }, + new DialogOptions() { Width = "55vw", Resizable = true, Draggable = true, ShowClose = true } + ); + if(flag != null && flag) + { + await reloadGrid(); + } + } + + + void Reset(Pojo.User user) + { + usersToInsert.Remove(user); + usersToUpdate.Remove(user); + } + + void OnCurrentDateChanged(DateTime args) + { + OrderDate = new DateTime(args.Year, args.Month, args.Day); + } + + async Task LoadData(LoadDataArgs args) + { + isLoading = true; + + var result = await userDao.GetAllByNickname(nickname, args.Top, args.Skip); + // Update the Data property + userList = result.Desserts; + // Update the count + count = result.TotalDesserts; + + isLoading = false; + } + + async Task reloadGrid() + { + nickname = ""; + await grid.Reload(); + } + + async Task EditRow(Pojo.User user) + { + + Reset(); + + usersToUpdate.Add(user); + await grid.EditRow(user); + } + + void OnUpdateRow(Pojo.User user) + { + Reset(user); + + // 数据库更新 + userDao.UpdateUser(user); + if(user.role.Id != user.RoleId) + { + grid.Reload(); + } + } + + async Task SaveRow(Pojo.User user) + { + await grid.UpdateRow(user); + } + + void CancelEdit(Pojo.User user) + { + Reset(user); + + grid.CancelEditRow(user); + grid.Reload(); + } + + async Task DeleteRow(Pojo.User user) + { + Reset(user); + + if (userList.Contains(user)) + { + //弹出确认提示框 + var b = await dialogService.OpenAsync( + $"删除确认", + new Dictionary() { { "confirmInfo", "删除用户:"+user.Username } }, + new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false }); + if (b) + { + // 数据库删除 + userDao.DeleteeUser(user.Id); + } + await grid.Reload(); + } + else + { + grid.CancelEditRow(user); + await grid.Reload(); + } + } + //重置密码 + async Task ResetPasswordRow(Pojo.User user) + { + Reset(user); + + if (userList.Contains(user)) + { + //弹出确认提示框 + var b = await dialogService.OpenAsync( + $"密码重置确认", + new Dictionary() { { "confirmInfo", "重置用户:" + user.Username+" 的密码" } }, + new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false }); + if (b) + { + // 数据库重置密码 + userDao.ResetPassword(user.Id); + //提示密码已重置,下次登录请使用重置后的密码 + _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"密码已重置,下次登录请使用重置后的密码", Duration = 4000 }); + } + await grid.Reload(); + } + else + { + grid.CancelEditRow(user); + await grid.Reload(); + } + } + + async Task InsertRow() + { + + Reset(); + var user = new Pojo.User() + { + RoleId = roles[0].Id, + }; + usersToInsert.Add(user); + await grid.InsertRow(user); + } + + void OnCreateRow(Pojo.User user) + { + // 数据库添加用户 + userDao.InsertUser(user); + usersToInsert.Remove(user); + grid.Reload(); + } + + + + + + +} diff --git a/MasaBlazorApp3/Pojo/AccountBook.cs b/MasaBlazorApp3/Pojo/AccountBook.cs new file mode 100644 index 0000000..44cd26e --- /dev/null +++ b/MasaBlazorApp3/Pojo/AccountBook.cs @@ -0,0 +1,113 @@ +using LinqToDB.Mapping; +using MasaBlazorApp3.Pojo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo +{ + [Table("account_book")] + public class AccountBook + { + /// + /// 主键 + /// + [Column("id", IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + /// + /// 设备id + /// + [Column("machine_id")] + public string MachineId { get; set; } + /// + /// 药品id + /// + [Column("drug_id")] + public string DrugId { get; set; } + + + [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))] + public DrugInfo Drug { get; set; } + /// + /// 数量 + /// + [Column("add_quantity")] + public int AddQuantity { get; set; } + [Column("out_quantity")] + public int OutQuantity { get; set; } + + /// + /// 批号 + /// + [Column("manu_no")] + public string ManuNo { get; set; } + /// + /// 操作人id + /// + [Column("operator")] + public int? Operator { get; set; } + + + [Association(ThisKey = nameof(Operator), OtherKey = nameof(User.Id))] + public User OperatorUser { get; set; } + /// + /// 审核人id + /// + [Column("reviewer")] + public int? Reviewer { get; set; } + + + [Association(ThisKey = nameof(Reviewer), OtherKey = nameof(User.Id))] + public User ReviewerUser { get; set; } + /// + /// 操作时间 + /// 默认值: CURRENT_TIMESTAMP + /// + [Column("create_time")] + public DateTime OperationTime { get; set; } + /// + /// 效期 + /// + [Column("eff_date")] + public DateTime? EffDate { get; set; } + /// + /// 出库入库类型(1领入2发出3日结4日总结5转结) + /// + [Column("type")] + public int Type { get; set; } + /// + /// 出入库调拨单id + /// + [Column("invoice_id")] + public string InvoiceId { get; set; } + /// + /// 列号 + /// + [Column("yesterday_quantity")] + public int YesterdayQuantity { get; set; } + /// + /// 抽屉号 + /// + [Column("manu_stock")] + public int ManuStock { get; set; } + [Column("total_stock")] + public int TotalStock { get; set; } + + /// + /// 取药科室 + /// + [Column("department")] + public string department { get; set; } + /// + /// 退药量 + /// 默认值: 0 + /// + [Column("create_date")] + public string CreateDate { get; set; } + + + } +} diff --git a/MasaBlazorApp3/Pojo/ChannelList.cs b/MasaBlazorApp3/Pojo/ChannelList.cs new file mode 100644 index 0000000..4c21caf --- /dev/null +++ b/MasaBlazorApp3/Pojo/ChannelList.cs @@ -0,0 +1,48 @@ +using LinqToDB.Mapping; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo +{ + [Table("channel_list")] + public class ChannelList + { + + [PrimaryKey] + [Column("chnguid")] + public string Id { get; set; } + + + [Column("machine_id")] + public string MachineId { get; set; } + + [Column("row_no")] + public int DrawerNo { get; set; } + + [Column("col_no")] + public int ColNo { get; set; } + + [Column("drug_id")] + public string DrugId { get; set; } + + [Column("chn_type")] + public int DrawerType { get; set; } + + [Column("col_no1")] + public int IsBox { get; set; } + + + [Column("col_no2")] + public int IsWeight { get; set; } + + [Association(ThisKey = nameof(Id), OtherKey = nameof(ChannelStock.ListId))] + public List ChannelStocks { get; set; } = new(); + + [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))] + public DrugInfo Drug { get; set; } = new(); + + } +} diff --git a/MasaBlazorApp3/Pojo/ChannelStock.cs b/MasaBlazorApp3/Pojo/ChannelStock.cs new file mode 100644 index 0000000..bcb697a --- /dev/null +++ b/MasaBlazorApp3/Pojo/ChannelStock.cs @@ -0,0 +1,83 @@ +using LinqToDB.Common.Internal.Cache; +using LinqToDB.Mapping; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo +{ + [Table("channel_stock")] + public class ChannelStock + { + [PrimaryKey] + [Column("chsguid")] + public string Id { get; set; } + + [Column("chnguid")] + public string ListId { get; set; } + + [Column("machine_id")] + public string MachineId { get; set; } + + [Column("row_no")] + public int DrawerNo { get; set; } + + [Column("col_no")] + public int ColNo { get; set; } + + [Column("drug_id")] + public string DrugId { get; set; } + + [Column("quantity")] + public int Quantity { get; set; } + + + [Column("drawer_type")] + public int DrawerType { get; set; } + + + [Column("board_type")] + public int BoardType { get; set; } + + [Column("manu_no")] + public string ManuNo { get; set; } + + [Column("eff_date")] + public string EffDate { get; set; } + + [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))] + public DrugInfo? Drug { get; set; } + + + [Column(IsColumn = false)] + public int TakeQuantity { get; set; } = 0; + [Column(IsColumn = false)] + public int AddQuantity { get; set; } = 0; + + [Column(IsColumn = false)] + public int ReturnQuantity { get; set; } + + [Column("dmnguid")] + public string Dmnguid { get; set; } + + [Association(ThisKey = nameof(Dmnguid), OtherKey = nameof(DrugManuNo.Id))] + public DrugManuNo? drugManuNo { get; set; } + + + [Column(IsColumn =false)] + public string Location + { get=>DrawerNo+ "-" + ColNo; } + + [Column(IsColumn =false)] + public int CanReturnQuantity { get; set; } + + [Column(IsColumn = false)] + public int CheckQuantity + { + get; + set; + } + } +} diff --git a/MasaBlazorApp3/Pojo/Config/DrawerConfig.cs b/MasaBlazorApp3/Pojo/Config/DrawerConfig.cs new file mode 100644 index 0000000..0d9ff35 --- /dev/null +++ b/MasaBlazorApp3/Pojo/Config/DrawerConfig.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo.Config +{ + public class DrawerConfig + { + public int[] single { get; set; } + public int[] weigh { get; set; } + public int[] box { get; set; } + public int[] label { get; set; } + + } +} diff --git a/MasaBlazorApp3/Pojo/Config/FingerPojo.cs b/MasaBlazorApp3/Pojo/Config/FingerPojo.cs new file mode 100644 index 0000000..5aad883 --- /dev/null +++ b/MasaBlazorApp3/Pojo/Config/FingerPojo.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo.Config +{ + public class FingerPojo + { + public string ip { get; set; } + public int port { get; set; } + public int type { get; set; } + } +} diff --git a/MasaBlazorApp3/Pojo/Config/PortConfig.cs b/MasaBlazorApp3/Pojo/Config/PortConfig.cs new file mode 100644 index 0000000..b7089a3 --- /dev/null +++ b/MasaBlazorApp3/Pojo/Config/PortConfig.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo.Config +{ + public class PortConfig + { + public string drawerPortPath { get; set; } + + public int drawerProtocol { get; set; } + + public string scanCodePortPath { get; set; } + + public string canBusPortPath { get; set; } + + public bool canBusExsit { get; set; } + public int doorAddr { get; set; } + public int storageBoxAddr { get; set; } + } +} diff --git a/MasaBlazorApp3/Pojo/Config/SettingConfig.cs b/MasaBlazorApp3/Pojo/Config/SettingConfig.cs new file mode 100644 index 0000000..d945d95 --- /dev/null +++ b/MasaBlazorApp3/Pojo/Config/SettingConfig.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo.Config +{ + public class SettingConfig + { + public string machineId { get; set; } + public string storage { get; set; } + public int loginMode { get; set; } + public bool opFirst { get; set; } + //自动退出登录时间,单位秒(0不自动退出) + public int autoOutLog { get; set; } + + } +} diff --git a/MasaBlazorApp3/Pojo/DrugInfo.cs b/MasaBlazorApp3/Pojo/DrugInfo.cs new file mode 100644 index 0000000..1abea52 --- /dev/null +++ b/MasaBlazorApp3/Pojo/DrugInfo.cs @@ -0,0 +1,62 @@ +using LinqToDB.Mapping; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace MasaBlazorApp3.Pojo +{ + [Table("drug_info")] + public class DrugInfo + { + [PrimaryKey] + [Column("drug_id")] + public string DrugId { get; set; } + + [Column("drug_name")] + public string DrugName { get; set;} + + [Column("drug_type")] + public string DrugType { get; set;} + + [Column("drug_spec")] + public string DrugSpec { get; set;} + + + [Column("manufactory")] + public string Manufactory { get; set; } + + [Column("pack_unit")] + public string PackUnit { get; set;} + + + [Association(ThisKey = nameof(DrugId), OtherKey = nameof(ChannelStock.DrugId))] + public List Stocks { get; set;} = new List(); + + + [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugManuNo.DrugId))] + public List Manus { get; set; } = new List(); + + [Column(IsColumn = false)] + public int StockQuantity + { + get { return Stocks.Aggregate(0, (current, next) => current + next.Quantity); ; } + } + + public override bool Equals(object o) + { + var other = o as DrugInfo; + + return other?.DrugId == DrugId; + } + + public override string ToString() + { + return $"名称: {DrugName},规格:{DrugSpec}"; + } + + + } +} diff --git a/MasaBlazorApp3/Pojo/DrugManuNo.cs b/MasaBlazorApp3/Pojo/DrugManuNo.cs new file mode 100644 index 0000000..fd3ba4e --- /dev/null +++ b/MasaBlazorApp3/Pojo/DrugManuNo.cs @@ -0,0 +1,40 @@ +using LinqToDB.Mapping; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo +{ + [Table("drug_manu_no")] + public class DrugManuNo + { + [Column("dmnguid", IsPrimaryKey = true)] + public string Id { get; set; } + + [Column("drug_id")] + public string DrugId { get; set; } + + + [Column("manu_no")] + public string ManuNo { get; set; } + + + + [Column("manu_date")] + public string ManuDate { get; set; } + + + [Column("eff_date")] + public DateTime? EffDate { get; set; } + + + public override bool Equals(object o) + { + var other = o as DrugManuNo; + + return other?.DrugId == DrugId && other?.ManuNo == ManuNo; + } + } +} diff --git a/MasaBlazorApp3/Pojo/InOutInvoice.cs b/MasaBlazorApp3/Pojo/InOutInvoice.cs new file mode 100644 index 0000000..08f731d --- /dev/null +++ b/MasaBlazorApp3/Pojo/InOutInvoice.cs @@ -0,0 +1,146 @@ +using LinqToDB.Mapping; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo +{ + [Table("in_out_invoice")] + public class InOutInvoice + { + /// + /// 主键(序号) + /// + [Column("id", IsPrimaryKey = true, IsIdentity =true)] + public int Id { get; set; } + + [Column("in_pharmacy_id")] + public string InPharmacyId { get; set; } + + [Column("out_pharmacy_id")] + public string OutPharmacyId { get; set; } + + /// + /// 库存管理单位(入库单位代码) + /// + [Column("storage")] + public string storage { get; set; } + + /// + /// 单据号 + /// + [Column("invoice_no")] + public string InvoiceNo { get; set; } + + [Column("invoice_date")] + public string InvoiceDate { get; set; } + + /// + /// 药品id + /// + [Column("drug_id")] + public string DrugId { get; set; } + + + + [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))] + public DrugInfo Drug { get; set; } = new(); + + /// + /// 药品规格 + /// + [Column("drug_spec")] + public string DrugSpec { get; set; } + + /// + /// 计算单位 + /// + [Column("units")] + public string Units { get; set; } + + /// + /// 厂商标识 + /// + [Column("firm_id")] + public string FirmId { get; set; } + + /// + /// 包装规格(反映药品含量及包装信息,如0.25g*30) + /// + [Column("package_spec")] + public string PackageSpec { get; set; } + + /// + /// 数量(以包装单位所计的数量) + /// + [Column("quantity")] + public int quantity { get; set; } + + /// + /// 计量单位,可使用任一级管理上方便的包装 + /// + [Column("package_units")] + public string PackageUnits { get; set; } + + /// + /// 药品批次 + /// + [Column("drug_manu_no")] + public string DrugManuNo { get; set; } + + /// + /// 创建时间(入库日期) + /// + [Column("create_time")] + public DateTime CreateTime { get; set; } + + /// + /// 2调拨出库1.调拨入库 0.调拨 + /// + [Column("type")] + public int Type { get; set; } + + /// + /// 类型描述 + /// + [Column("type_describe")] + public string TypeDescribe { get; set; } + + /// + /// 供货方 + /// + [Column("supplier")] + public string Supplier { get; set; } + + /// + /// 操作人 + /// + [Column("operator")] + public string Operator { get; set; } + + /// + /// 存放库房 + /// + [Column("sub_storage")] + public string SubStorage { get; set; } + + /// + /// 备注 + /// + [Column("memos")] + public string Memos { get; set; } + + [Column("status")] + public int Status { get; set; } + + [Column("drug_eff_date")] + public string EffDate { get; set; } + + + [Column("cancel_flag")] + public int CancelFlag { get; set; } + + } +} diff --git a/MasaBlazorApp3/Pojo/MachineRecord.cs b/MasaBlazorApp3/Pojo/MachineRecord.cs new file mode 100644 index 0000000..5abf980 --- /dev/null +++ b/MasaBlazorApp3/Pojo/MachineRecord.cs @@ -0,0 +1,149 @@ +using LinqToDB.Mapping; +using MasaBlazorApp3.Pojo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo +{ + [Table("dm_machine_record")] + public class MachineRecord + { + /// + /// 主键 + /// + [Column("id", IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + /// + /// 设备id + /// + [Column("machine_id")] + public string MachineId { get; set; } + /// + /// 药品id + /// + [Column("drug_id")] + public string DrugId { get; set; } + + + [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))] + public DrugInfo Drug { get; set; } + /// + /// 数量 + /// + [Column("quantity")] + public int Quantity { get; set; } + + /// + /// 批号 + /// + [Column("manu_no")] + public string ManuNo { get; set; } + /// + /// 操作人id + /// + [Column("operator")] + public int? Operator { get; set; } + + + [Association(ThisKey = nameof(Operator), OtherKey = nameof(User.Id))] + public User OperatorUser { get; set; } + /// + /// 审核人id + /// + [Column("reviewer")] + public int? Reviewer { get; set; } + + + [Association(ThisKey = nameof(Reviewer), OtherKey = nameof(User.Id))] + public User ReviewerUser { get; set; } + /// + /// 操作时间 + /// 默认值: CURRENT_TIMESTAMP + /// + [Column("operation_time")] + public DateTime OperationTime { get; set; } + /// + /// 效期 + /// + [Column("eff_date")] + public DateTime? EffDate { get; set; } + /// + /// 出库入库类型(1入库2出库31还药32还空瓶) + /// + [Column("type")] + public int Type { get; set; } + /// + /// 出入库调拨单id + /// + [Column("invoice_id")] + public string InvoiceId { get; set; } + /// + /// 列号 + /// + [Column("col_no")] + public int ColNo { get; set; } + /// + /// 抽屉号 + /// + [Column("drawer_no")] + public int DrawerNo { get; set; } + /// + /// 取药科室 + /// + [Column("department_id")] + public string DepartmentId { get; set; } + /// + /// 是否已经退药(0:没有1:还了部分2:完成) + /// 默认值: 0 + /// + [Column("status")] + public int Status { get; set; } + /// + /// 退药量 + /// 默认值: 0 + /// + [Column("return_quantity1")] + public int ReturnQuantity1 { get; set; } + /// + /// 退空瓶量 + /// 默认值: 0 + /// + [Column("return_quantity2")] + public int ReturnQuantity2 { get; set; } + + + [Column(IsColumn = false)] + public int CurrentReturnQuantity { get; set; } + /// + /// 取药记录id + /// + [Column("get_id")] + public int? GetId { get; set; } + /// + /// 是否已经销毁 + /// 默认值: 0 + /// + [Column("is_destroy")] + public int? IsDestroy { get; set; } + + [Column(IsColumn = false)] + public int CanReturnQuantity + { + get => Quantity - ReturnQuantity1 - ReturnQuantity2; + + } + //是否选中 + [Column(IsColumn = false)] + public bool IsSelected { get; set; } + + [Column(IsColumn =false)] + public string Location + { + get => DrawerNo + "-" + ColNo; + } + } +} diff --git a/MasaBlazorApp3/Pojo/OrderDetail.cs b/MasaBlazorApp3/Pojo/OrderDetail.cs new file mode 100644 index 0000000..6c9faed --- /dev/null +++ b/MasaBlazorApp3/Pojo/OrderDetail.cs @@ -0,0 +1,133 @@ +using LinqToDB.Mapping; +using System; +using System.Collections.Generic; +using System.Linq; +namespace MasaBlazorApp3.Pojo +{ + /// + /// + /// + [Table("order_detail")] + public class OrderDetail + { + /// + /// + /// + /// + [PrimaryKey] + [Column("id")] + public int Id { get; set; } + /// + /// + /// 默认值: NULL + /// + //[SugarColumn(ColumnName = "order_id")] + //public int? OrderId { get; set; } + /// + /// + /// + [Column("patient_id")] + public string PatientId { get; set; } + /// + /// + /// + [Column("order_no")] + public string OrderNo { get; set; } + /// + /// + /// + [Column("charge_date")] + public DateTime ChargeDate { get; set; } + /// + /// + /// 默认值: NULL + /// + //[SugarColumn(ColumnName = "serial_no")] + //public int? SerialNo { get; set; } + /// + /// + /// + [Column("drug_id")] + public string DrugId { get; set; } + + [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))] + public DrugInfo Drug { get; set; } = new(); + /// + /// + /// + [Column("quantity")] + public int Quantity { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("order_unit")] + public string OrderUnit { get; set; } + /// + /// + /// 默认值: 1 + /// + [Column("unit_convercoef")] + public int? UnitConvercoef { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("set_manu_no")] + public string SetManuNo { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("set_eff_date")] + public string SetEffDate { get; set; } + /// + /// + /// 默认值: NULL + /// + //[SugarColumn(ColumnName = "price")] + //public string Price { get; set; } + /// + /// + /// 默认值: NULL + /// + //[SugarColumn(ColumnName = "total_price")] + //public string TotalPrice { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("use_discrip")] + public string UseDiscrip { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("use_frequ")] + public string UseFrequ { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("use_once")] + public string UseOnce { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("use_by")] + public string UseBy { get; set; } + /// + /// + /// 默认值: '0' + /// + [Column("use_self")] + public string UseSelf { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("use_dosage")] + public string UseDosage { get; set; } + } +} \ No newline at end of file diff --git a/MasaBlazorApp3/Pojo/OrderFinish.cs b/MasaBlazorApp3/Pojo/OrderFinish.cs new file mode 100644 index 0000000..de8fb09 --- /dev/null +++ b/MasaBlazorApp3/Pojo/OrderFinish.cs @@ -0,0 +1,33 @@ +using LinqToDB.Mapping; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo +{ + [Table("hkc_order_finish")] + public class OrderFinish + { + [PrimaryKey] + [Column("id")] + public int Id { get; set; } + + [Column("pharmacy")] + public string Pharmacy { get; set; } + + [Column("patient_id")] + public string PatientId { get; set; } + + [Column("order_no")] + public string OrderNo { get; set; } + + [Column("state")] + public int State { get; set; } + + [Column("operator")] + public string Operator { get; set; } + + } +} diff --git a/MasaBlazorApp3/Pojo/OrderInfo.cs b/MasaBlazorApp3/Pojo/OrderInfo.cs new file mode 100644 index 0000000..6a2e9b6 --- /dev/null +++ b/MasaBlazorApp3/Pojo/OrderInfo.cs @@ -0,0 +1,159 @@ +using LinqToDB.Mapping; +using System; +using System.Collections.Generic; +using System.Linq; +namespace MasaBlazorApp3.Pojo +{ + /// + /// + /// + [Table("order_info")] + public class OrderInfo + { + /// + /// + /// + /// + [PrimaryKey, Identity] + [Column("order_id")] + public int OrderId { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("pharmacy")] + public string Pharmacy { get; set; } + /// + /// + /// + [Column("order_no")] + public string OrderNo { get; set; } + /// + /// + /// + [Column("patient_id")] + public string PatientId { get; set; } + /// + /// + /// + [Column("p_name")] + public string PatientName { get; set; } + + /// + /// + /// 默认值: NULL + /// + [Column("sex")] + public string Sex { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("age")] + public string Age { get; set; } + + /// + /// + /// 默认值: NULL + /// + [Column("id_number")] + public string IdNumber { get; set; } + + + /// + /// + /// 默认值: NULL + /// + [Column("invoice_no")] + public string InvoiceNo { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("patient_no")] + public string PatientNo { get; set; } + + /// + /// + /// 默认值: NULL + /// + [Column("doctor_name")] + public string DoctorName { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("order_date")] + public DateTime OrderDate { get; set; } + /// + /// + /// + [Column("charge_date")] + public DateTime ChargeDate { get; set; } = DateTime.Now; + /// + /// + /// 默认值: NULL + /// + [Column("recv_date")] + public DateTime RecvDate { get; set; } + + + /// + /// + /// 默认值: NULL + /// + [Column("dept_name")] + public string DeptName { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("disease")] + public string Disease { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("order_type")] + public string OrderType { get; set; } + /// + /// + /// 默认值: NULL + /// + [Column("charge_type")] + public string ChargeType { get; set; } + /// + /// + /// + [Column("dm_status")] + public int Status { get; set; } + /// + /// + /// 默认值: 0 + /// + [Column("his_disp_flag")] + public int? HisDispFlag { get; set; } + + /// + /// + /// 默认值: 0 + /// + [Column("cancel_flag")] + public int? CancelFlag { get; set; } + + /// + /// + /// 默认值: 0 + /// + [Column("win_no")] + public int WinNo { get; set; } = 0; + /// + /// + /// 默认值: 0 + /// + [Column("state")] + public int state { get; set; } = 0; + + + } +} \ No newline at end of file diff --git a/MasaBlazorApp3/Pojo/Premission.cs b/MasaBlazorApp3/Pojo/Premission.cs new file mode 100644 index 0000000..3f47a1e --- /dev/null +++ b/MasaBlazorApp3/Pojo/Premission.cs @@ -0,0 +1,207 @@ +using Mysqlx.Crud; + +namespace MasaBlazorApp3.Pojo +{ + [Serializable] + public class Premission + { + + public Premission Parent { get; set; } = null; + + public void AddChild(Premission item) + { + item.Parent = this; + this.Items = this.Items.Concat(new Premission[] { item }); + } + + public int Id { get; set; } + public string PremissionName { get; set; } + /// + /// 菜单路径 + /// + public string PremissionPath { get; set; } + + + public IEnumerable Items { get; set; } = Enumerable.Empty(); + + public List getAdminPremission() + { + var list = new List(); + Premission q = new Premission + { + Id = 1, + PremissionName = "出库", + PremissionPath = "take" + }; + + q.AddChild(new Premission() + { + Id = 11, + PremissionName = "处方取药", + PremissionPath = "/take/order" + }); + q.AddChild(new Premission() + { + Id = 12, + PremissionName = "调拨取药", + PremissionPath = "/take/invoice" + }); + q.AddChild(new Premission() + { + Id = 13, + PremissionName = "抽屉取药", + PremissionPath = "/take/drawer" + }); + q.AddChild(new Premission() + { + Id = 14, + PremissionName = "自选取药", + PremissionPath = "/take/self" + }); + q.AddChild(new Premission() + { + Id = 15, + PremissionName = "取药记录", + PremissionPath = "/take/record/2" + }); + + Premission j = new Premission + { + Id = 2, + PremissionName = "入库", + PremissionPath = "add" + }; + j.AddChild(new Premission() + { + Id = 21, + PremissionName = "调拨入库", + PremissionPath = "/add/invoice" + }); + //j.AddChild(new Premission() + //{ + // Id = 22, + // PremissionName = "请领入库", + // PremissionPath = "/add/apply" + //}); + j.AddChild(new Premission() + { + Id = 23, + PremissionName = "抽屉入库", + PremissionPath = "/add/drawer" + }); + j.AddChild(new Premission() + { + Id = 24, + PremissionName = "入库记录", + PremissionPath = "/add/record/1" + }); + Premission h = new Premission + { + Id = 3, + PremissionName = "归还", + PremissionPath = "return" + }; + + h.AddChild(new Premission() + { + Id = 31, + PremissionName = "归还药品(处方)", + PremissionPath = "/return/order" + }); + h.AddChild(new Premission() + { + Id = 32, + PremissionName = "归还药品(记录)", + PremissionPath = "/return/byRecord" + }); + h.AddChild(new Premission() + { + Id = 33, + PremissionName = "归还空瓶", + PremissionPath = "/return/empty" + }); + h.AddChild(new Premission() + { + Id = 34, + PremissionName = "归还记录(药品)", + PremissionPath = "/return/record1/31" + }); + h.AddChild(new Premission() + { + Id = 35, + PremissionName = "归还记录(空瓶)", + PremissionPath = "/return/record2/32" + }); + + Premission k = new Premission + { + Id = 4, + PremissionName = "库存管理", + PremissionPath = "stock" + }; + k.AddChild(new Premission() + { + Id = 41, + PremissionName = "库存列表", + PremissionPath = "/stock/list" + }); + k.AddChild(new Premission() + { + Id = 42, + PremissionName = "库位绑定", + PremissionPath = "/stock/binding" + }); + k.AddChild(new Premission() + { + Id = 43, + PremissionName = "库存盘点", + //PremissionName = "盘点交接", + PremissionPath = "/stock/check" + }); + k.AddChild(new Premission() + { + Id = 44, + PremissionName = "盘点记录", + //PremissionPath = "/stock/checkRecord" + PremissionPath = "/stock/record/4" + }); + k.AddChild(new Premission() + { + Id = 45, + PremissionName = "药品信息", + PremissionPath = "/stock/drug" + }); + k.AddChild(new Premission() + { + Id = 46, + PremissionName = "药品标定", + PremissionPath = "/stock/biaoDing" + }); + Premission x = new Premission + { + Id = 5, + PremissionName = "系统管理", + PremissionPath = "manage" + }; + x.AddChild(new Premission() + { + Id = 51, + PremissionName = "用户管理", + PremissionPath = "/manage/user" + }); + x.AddChild(new Premission() + { + Id = 52, + PremissionName = "权限管理", + PremissionPath = "/manage/role" + }); + list.Add(q); + list.Add(j); + list.Add(h); + list.Add(k); + list.Add(x); + + return list; + } + } +} diff --git a/MasaBlazorApp3/Pojo/Role.cs b/MasaBlazorApp3/Pojo/Role.cs new file mode 100644 index 0000000..222e222 --- /dev/null +++ b/MasaBlazorApp3/Pojo/Role.cs @@ -0,0 +1,50 @@ +using LinqToDB.Mapping; + +namespace MasaBlazorApp3.Pojo +{ + [Table("role")] + public class Role + { + + [PrimaryKey, Identity] + [Column("id")] + public int Id { get; set; } + [Column("role_name")] + public string RoleName { get; set; } + //[Column("role_des")] + //public string Description { get; set; } + [Column("machine_id")] + public string MachineId { get; set; } + + [Column("permissions")] + public string permissions { get; set; } + + [Column(IsColumn = false)] + public List permissionList { + get + { + + return null; + } + } + + [Column(IsColumn = false)] + public IEnumerable permissionIds + { + get + { + return !String.IsNullOrEmpty(permissions) ? permissions.Split(",").Select(s => Convert.ToInt32(s)): Enumerable.Empty(); + } + set + { + if (value == null) + { + permissions = ""; + } else + { + permissions = string.Join(",", value); + } + } + } + } +} diff --git a/MasaBlazorApp3/Pojo/User.cs b/MasaBlazorApp3/Pojo/User.cs new file mode 100644 index 0000000..d6a12be --- /dev/null +++ b/MasaBlazorApp3/Pojo/User.cs @@ -0,0 +1,39 @@ + + +using LinqToDB.Mapping; + +namespace MasaBlazorApp3.Pojo +{ + [Table("user_list")] + public class User + { + [Column("id")] + [PrimaryKey, Identity] + public int Id { get; set; } + [Column("user_id")] + public string Username { get; set; } + + [Column("pass_word")] + public string Password { get; set; } + + + [Column("user_name")] + public string NickName { get; set; } + + + [Column("machine_id")] + public string MachineId { get; set; } + + + [Column("sign")] + public byte[] Sign { get; set; } + + + [Column("machine_role_id")] + public int RoleId { get; set; } + + + [Association(ThisKey = nameof(RoleId), OtherKey = nameof(Role.Id))] + public Role role { get; set; } + } +} diff --git a/MasaBlazorApp3/Pojo/Vo/InvoiceVo.cs b/MasaBlazorApp3/Pojo/Vo/InvoiceVo.cs new file mode 100644 index 0000000..b46667b --- /dev/null +++ b/MasaBlazorApp3/Pojo/Vo/InvoiceVo.cs @@ -0,0 +1,34 @@ +using Radzen.Blazor; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo.Vo +{ + public class InvoiceVo + { + public DrugInfo Drug { get; set; } + + public InOutInvoice Invoice { get; set; } + + public List ChannelStocks { get; set; } + + public int StockQuantity { get; set; } + + public int Quantity { get; set; } + + public int GetQuantity { get; set; } = 0; + + public int Status { get; set; } = 0; + + public int[] BeforeQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + public int[] AfterQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + public int AddQuantity { get; set; } = 0; + + public RadzenDataGrid Grid { get; set; } + } +} diff --git a/MasaBlazorApp3/Pojo/Vo/OperationVo.cs b/MasaBlazorApp3/Pojo/Vo/OperationVo.cs new file mode 100644 index 0000000..4b4dcce --- /dev/null +++ b/MasaBlazorApp3/Pojo/Vo/OperationVo.cs @@ -0,0 +1,37 @@ +using Radzen.Blazor; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo.Vo +{ + public class OperationVo + { + public DrugInfo Drug { get; set; } + + public T data { get; set; } + + public List ChannelStocks { get; set; } + + public int StockQuantity { get; set; } + + public int Quantity { get; set; } + + public int GetQuantity { get; set; } = 0; + + public int Status { get; set; } = 0; + + public int[] BeforeQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + public int[] AfterQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + public int AddQuantity { get; set; } = 0; + + + public int ReturnQuantity { get; set; } = 0; + + public RadzenDataGrid Grid { get; set; } + } +} diff --git a/MasaBlazorApp3/Pojo/Vo/OrderTakeVo.cs b/MasaBlazorApp3/Pojo/Vo/OrderTakeVo.cs new file mode 100644 index 0000000..570f9fa --- /dev/null +++ b/MasaBlazorApp3/Pojo/Vo/OrderTakeVo.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Pojo.Vo +{ + public class OrderTakeVo + { + public DrugInfo Drug { get; set; } + + public OrderDetail OrderDetail { get; set; } + + public ChannelStock ChannelStock { get; set; } + + public int StockQuantity { get; set; } + + public int Quantity { get; set;} + + public int GetQuantity { get; set; } = 0; + + public int Status { get; set; } = 0; + + public int[] BeforeQuantity { get; set; } = new int[] { 0,0,0,0,0,0,0,0,0 }; + + public int[] AfterQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + public int AddQuantity { get; set; } = 0; + + } +} diff --git a/MasaBlazorApp3/Port/PortUtil.cs b/MasaBlazorApp3/Port/PortUtil.cs new file mode 100644 index 0000000..d07c253 --- /dev/null +++ b/MasaBlazorApp3/Port/PortUtil.cs @@ -0,0 +1,987 @@ +using log4net; +using log4net.Repository.Hierarchy; +using System; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Configuration; +using System.IO.Ports; +using System.Linq; +using System.Reflection.Metadata; +using System.Speech.Synthesis; +using System.Text; +using System.Threading.Channels; +using System.Threading.Tasks; +using System.Timers; +using System.Windows; +using System.Windows.Markup; +using System.Reflection; +using MasaBlazorApp3.Pojo.Config; +using Microsoft.Extensions.Options; +using LinqToDB.Common; + +namespace MasaBlazorApp3.Port +{ + public class PortUtil + { + private readonly ILog logger = LogManager.GetLogger(typeof(PortUtil)); + // 抽屉串口 + public SerialPort drawerSerial; + // can总线串口 + public SerialPort canBusSerial; + + // 条码枪串口 + public SerialPort scanCodeSerial; + + + public bool Operate { get; set; } + public DateTime dateTime { get; set; } = DateTime.Now; + + // 当前操作的抽屉号 + public int DrawerNo { get; set; } + // 当前操作的库位号列表 + public int[] ColNos { get; set; } = new int[] { }; + // 当前操作查数的库位号列表 + public List ColNoLst { get; set; } = new List(); + // 当前操作开药盒的库位号 + public int OpenBoxColNo { get; set; } = 0; + + private readonly PortConfig _portConfig; + + public PortUtil(IOptions setting) + { + _portConfig = setting.Value; + try + { + string DrawerPortPath = _portConfig.drawerPortPath; + logger.Info($"打开抽屉串口【{DrawerPortPath}】"); + drawerSerial = new SerialPort(DrawerPortPath, 9600, Parity.None, 8); + drawerSerial.Open(); + logger.Info($"抽屉串口打开结果【{drawerSerial.IsOpen}】"); + } + catch (Exception e) + { + logger.Error("抽屉串口打开错误" + e.Message); + } + + try { + string ScanCodePortPath = _portConfig.scanCodePortPath; + logger.Info($"打开条码枪串口【{ScanCodePortPath}】"); + scanCodeSerial = new SerialPort(ScanCodePortPath, 9600, Parity.None, 8); + scanCodeSerial.DataReceived += (object sender, System.IO.Ports.SerialDataReceivedEventArgs e) => + { + string code = scanCodeSerial.ReadExisting(); + + }; + scanCodeSerial.Open(); + logger.Info($"条码枪串口打开结果【{scanCodeSerial.IsOpen}】"); + } + catch (Exception e) + { + logger.Error("条码枪串口打开错误" + e.Message); + } + if (_portConfig.canBusExsit) + { + try + { + string CanBusPortPath = _portConfig.canBusPortPath; + logger.Info($"打开can总线串口【{CanBusPortPath}】"); + canBusSerial = new SerialPort(CanBusPortPath, 57600, Parity.None, 8); + canBusSerial.Open(); + logger.Info($"can总线串口打开结果【{canBusSerial.IsOpen}】"); + } + catch (Exception e) + { + logger.Error("can总线串口打开错误" + e.Message); + } + + } + + } + + + private byte[] GetBufferByPort(SerialPort serialPort, int length, int timeout) + { + int _length = 0; + DateTime start = DateTime.Now; + DateTime end = DateTime.Now; + while(_length != length && end.Subtract(start).TotalMilliseconds < timeout) + { + _length = serialPort.BytesToRead; + end = DateTime.Now; + } + if(_length != length) + { + throw new TimeoutException($"串口【{serialPort.PortName}】交互超时"); + } + byte[] buffer = new byte[length]; + serialPort.Read(buffer, 0, length); + return buffer; + } + private Task GetBufferByPort(SerialPort serialPort, int length) + { + + return Task.Run(() => GetBufferByPort(serialPort, length, 3000)); + } + + + public static SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(); + public void SpeakAsync(string textinfo) + { + speechSynthesizer.SpeakAsync(textinfo); + } + + + + #region 抽屉串口操作 + // 打开抽屉 + public async Task OpenDrawer(int DrawerNo) + { + drawerSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xaa, 0x41, (byte)DrawerNo, 0xee }; + if (_portConfig.drawerProtocol == 485) + { + if (DrawerNo > 8) + { + buffer = new byte[] { 0xaa, 0x21, (byte)(DrawerNo - 8), 0xee }; + } + else + { + buffer = new byte[] { 0xaa, 0x11, (byte)DrawerNo, 0xee }; + } + + } + logger.Info($"打开抽屉,串口数据:{Convert.ToHexString(buffer)}"); + drawerSerial.Write(buffer, 0, 4); + + return await GetBufferByPort(drawerSerial, 11); + } + + public async Task OpenDrawerStatus(int DrawerNo) + { + byte[] buffer = await OpenDrawer(DrawerNo); + int[] r = buffer.Select(it => Convert.ToInt32(it)).ToArray(); + int index = DrawerNo > 8 ? DrawerNo - 7 : DrawerNo + 1; + return r[index] == 0; + + } + + + // 查询抽屉状态 + public async Task CheckDrawerStatus(int DrawerNo) + { + drawerSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xaa, 0x42, 0xee }; + if (_portConfig.drawerProtocol == 485) + { + if (DrawerNo > 8) + { + buffer = new byte[] { 0xaa, 0x22, 0xee }; + } + else + { + buffer = new byte[] { 0xaa, 0x12, 0xee }; + } + + } + + logger.Info($"查询抽屉状态,串口数据:{Convert.ToHexString(buffer)}"); + drawerSerial.Write(buffer, 0, 3); + + return await GetBufferByPort(drawerSerial, 11); + } + + public async Task CheckDrawerStatus2(int DrawerNo) + { + byte[] buffer = await CheckDrawerStatus(DrawerNo); + int[] r = buffer.Select(it => Convert.ToInt32(it)).ToArray(); + int index = DrawerNo > 8 ? DrawerNo - 7 : DrawerNo + 1; + return r[index] != 0; + + } + #endregion + + #region can总线串口操作 + #region 耗材板操作 + // 后门状态 + public async Task BackDoorState() + { + + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xaa, (byte)(_portConfig.doorAddr), 0x02, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + + return await GetBufferByPort(canBusSerial, 8); + + } + // 打开电控门储物箱(有灯使能) + public async Task OpenStorage() + { + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xaa, (byte)(_portConfig.doorAddr), 0x01, (byte)_portConfig.storageBoxAddr, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + + + return await GetBufferByPort(canBusSerial, 8); + } + // 关闭电控门储物箱(有灯失能) + public void CloseStorage() + { + byte[] buffer = new byte[] { 0xaa, (byte)(_portConfig.doorAddr), 0x04, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 打开普通储物箱(无灯) + public void OpenStorageBox() + { + byte[] buffer = new byte[] { 0xaa, (byte)(_portConfig.storageBoxAddr), 0x03, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 关闭普通储物箱(无灯) + public void CloseStorageBox() + { + byte[] buffer = new byte[] { 0xaa, (byte)(_portConfig.storageBoxAddr), 0x04, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + + private int[] CheckStorageStatus(int[] data) + { + int a = data[0]; + int b = data[1]; + int[] intA = Decimal2Chunks(a); + int[] intB = Decimal2Chunks(b); + int[] r = new int[intA.Length + intB.Length]; + Array.Copy(intA, 0, r, 0, intA.Length); + Array.Copy(intB, 0, r, intA.Length, intB.Length); + return r; + } + private int[] Decimal2Chunks(int d) + { + string s = Convert.ToString(d, 2); + List t = s.Split().Select(it => Convert.ToInt32(it)).Reverse().ToList(); + while (t.Count < 8) + { + t.Add(0); + } + return t.ToArray(); + } + + #endregion + + #region 单支操作 + // 以抽屉为单位获取抽屉内所有库位的药品数量 + public async Task CheckQuantityByDrawer(int DrawerNo) + { + canBusSerial.DiscardInBuffer(); + + byte[] buffer = new byte[] { 0xaa, (byte)(0xf0 + DrawerNo), 0x01, 0x00, 0x00, 0x00, 0x00, 0xee }; + + logger.Info($"单支板发送库位数量查询【{string.Join(",", buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + + return await GetBufferByPort(canBusSerial, 13); + } + // 获取单个单支板药品数量 + public async Task CheckQuantityByCol(int DrawerNo, int colNo) + { + canBusSerial.DiscardInBuffer(); + + var channel = Convert.ToInt32((DrawerNo * 10 + colNo).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x08, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + + return await GetBufferByPort(canBusSerial, 8); + + } + // 以抽屉为单位有药位置亮灯 + public void HasLightOnByDrawer(int DrawerNo) + { + byte[] buffer = new byte[] { 0xaa, (byte)(0xf0 + DrawerNo), 0x02, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 以抽屉为单位无药位置亮灯 + public void NoLightOnByDrawer(int DrawerNo) + { + byte[] buffer = new byte[] { 0xaa, (byte)(0xf0 + DrawerNo), 0x03, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 以抽屉为单位灭灯 + public void LightOffByDrawer(int DrawerNo) + { + byte[] buffer = new byte[] { 0xaa, (byte)(0xf0 + DrawerNo), 0x06, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 以单支板为单位有药位置亮灯 + public async Task HasLightOnByCol(int DrawerNo, int[] ColNos) + { + + for (int i = 0; i < ColNos.Length; i++) + { + + var channel = Convert.ToInt32((DrawerNo * 10 + ColNos[i]).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(TimeSpan.FromMilliseconds(20)); + } + + } + // 以单支板为单位无药位置亮灯 + public async Task NoLightOnByCol(int DrawerNo, int[] ColNos) + { + for (int i = 0; i < ColNos.Length; i++) + { + var channel = Convert.ToInt32((DrawerNo * 10 + ColNos[i]).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(TimeSpan.FromMilliseconds(20)); + } + } + // 广播灭灯 + public void AllLightOff() + { + byte[] buffer = new byte[] { 0xaa, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + #endregion + + #region 药盒操作 + // 指定药盒指示灯开启使能开锁 + public async Task BoxLockLightOn(int DrawerNo, int[] ColNos) + { + for (int i = 0; i < ColNos.Length; i++) + { + + var channel = Convert.ToInt32((DrawerNo * 10 + ColNos[i]).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x03, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(TimeSpan.FromMilliseconds(20)); + } + } + // 指定药盒指示灯开启失能开锁 + public async Task BoxLockLightOff(int DrawerNo, int[] ColNos) + { + for (int i = 0; i < ColNos.Length; i++) + { + var channel = Convert.ToInt32((DrawerNo * 10 + ColNos[i]).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x04, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(TimeSpan.FromMilliseconds(20)); + } + } + // 指定药盒状态查询 + public async Task BoxLockState(int DrawerNo, int ColNo) + { + canBusSerial.DiscardInBuffer(); + var channel = Convert.ToInt32((DrawerNo * 10 + ColNo).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x02, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + + return await GetBufferByPort(canBusSerial, 8); + + } + // 以抽屉为单位药盒指示灯开启使能开锁 + public async Task BoxLockLightOnByDrawer(int DrawerNo) + { + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xaa, (byte)(0xf0 + DrawerNo), 0x04, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 以抽屉为单位药盒指示灯开启失能开锁 + public async Task BoxLockLightOffByDrawer(int DrawerNo) + { + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xaa, (byte)(0xf0 + DrawerNo), 0x05, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + + /// + /// 开指定库位的药盒 + /// + /// + /// + public async Task OpenBoxByColNo(int colNo) + { + if (colNo > 0) + { + canBusSerial.DiscardInBuffer(); + int ColNo = colNo; + int[] iNum = new int[] { 4, 2, 1 }; + var colNo2 = ColNo % 3 > 0 ? (ColNo % 3) - 1 : 2; + var bColNo = iNum[colNo2]; + decimal decolNO = (decimal)ColNo; + var channel = Convert.ToInt32((DrawerNo * 10 + Math.Ceiling(decolNO / 3)).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 5, (byte)bColNo, 0x00, 0x00, 0x00, 0xee }; + //byte[] buffer = new byte[] { 0xaa, 0x11, 0x05,0x01, 0x00,0x00,0x00,0xee}; + logger.Info($"开药盒{ColNo}【{Convert.ToHexString(buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + byte[] retBuffer = await GetBufferByPort(canBusSerial, 8); + logger.Info($"开药盒返回{ColNo}【{Convert.ToHexString(retBuffer)}】"); + int[] r = retBuffer.Select(it => Convert.ToInt32(it)).ToArray(); + if (r[4] > 0) + { + return true; + } + else + { + return false; + } + } + return false; + } + /// + /// 打开药盒 + /// + /// + /// + public async Task OpenBox() + { + for (int i = 0; i < ColNos.Length; i++) + { + canBusSerial.DiscardInBuffer(); + int ColNo = ColNos[i]; + int[] iNum = new int[] { 4, 2, 1 }; + var colNo2 = ColNo % 3 > 0 ? (ColNo % 3) - 1 : 2; + var bColNo = iNum[colNo2]; + decimal decolNO = (decimal)ColNo; + var channel = Convert.ToInt32((DrawerNo * 10 + Math.Ceiling(decolNO / 3)).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 5, (byte)bColNo, 0x00, 0x00, 0x00, 0xee }; + //byte[] buffer = new byte[] { 0xaa, 0x11, 0x05,0x01, 0x00,0x00,0x00,0xee}; + logger.Info($"{Convert.ToHexString(buffer)}"); + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(800); + } + + } + // 以抽屉为单位药盒指示灯开启使能开锁 + public async Task BoxLockLightOnByDrawer() + { + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xaa, (byte)(0xf0 + DrawerNo), 0x04, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 以抽屉为单位药盒指示灯开启失能开锁 + public async Task BoxLockLightOffByDrawer() + { + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xaa, (byte)(0xf0 + DrawerNo), 0x05, 0x00, 0x00, 0x00, 0x00, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + + + + #endregion + + private string trim(string text) + { + //此处使用了转义字符如:\',\",\\,分别表示单引号,双引号,反斜杠 + char[] TrimChar = { ' ', '-', '\'', '\"', '\\','(', ')','(', ')', '①', '②' }; + return text.Trim(TrimChar); + } + + #region 2.4寸汉显屏 + // 基础数据写入方法 + public async void WriteChannelInfo(int type, string content, int drawerNo, int colNo) + { + + canBusSerial.DiscardInBuffer(); + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + byte[] contentBuf = Encoding.GetEncoding("gb2312").GetBytes(trim(content)); + int channel = (drawerNo * 10 + colNo); + if (contentBuf.Length % 2 != 0) + { + Array.Resize(ref contentBuf, contentBuf.Length + 1); + } + byte[] buffer = new byte[] { 0xaa, (byte)channel, 1, (byte)type, 0, 0, 0, 0xee }; + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(20); + buffer[4] = 1; + for (int i = 0; i < contentBuf.Length; i += 2) + { + buffer[5] = contentBuf[i]; + buffer[6] = contentBuf[i + 1]; + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(20); + } + buffer[4] = 2; + buffer[5] = 0; + buffer[6] = 0; + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(20); + } + + // 清除显示内容 + public void ClearContent(int drawerNo, int colNo) + { + canBusSerial.DiscardInBuffer(); + int channel = (drawerNo * 10 + colNo); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 4, 0, 0, 0, 0, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 刷新显示内容 + public void ShowContent(int drawerNo, int colNo) + { + canBusSerial.DiscardInBuffer(); + int channel = (drawerNo * 10 + colNo); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 2, 0, 0, 0, 0, 0xee }; + canBusSerial.Write(buffer, 0, 8); + } + // 取药或者加药亮灯 + public void TakeQuantity(int drawerNo, int colNo, int quantity, int stock) + { + canBusSerial.DiscardInBuffer(); + int channel = (drawerNo * 10 + colNo); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 6, 0, 0, 0, 0, 0xee }; + buffer[3] = (byte)(quantity >> 8); + buffer[4] = (byte)(quantity & 0xff); + buffer[5] = (byte)(stock >> 8); + buffer[6] = (byte)(stock & 0xff); + canBusSerial.Write(buffer, 0, 8); + } + // 写入数量 + public void WriteQuantity(int drawerNo, int colNo, int quantity) + { + canBusSerial.DiscardInBuffer(); + int channel = (drawerNo * 10 + colNo); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x21, 0, 0, 0, 0, 0xee }; + buffer[5] = (byte)(quantity >> 8); + buffer[6] = (byte)(quantity & 0xff); + canBusSerial.Write(buffer, 0, 8); + } + + //清屏 + public void ClearContentMethod(int drawerNo, int colNo) + { + decimal deColNo = colNo; + //var channel = drawerNo * 10 + Math.Ceiling(deColNo / 3); + int[] iNum = new int[] { 3, 2, 1 }; + var colNo2 = colNo % 3 > 0 ? (colNo % 3) - 1 : 2; + var bColNo = Convert.ToInt32((iNum[colNo2] + 10).ToString(), 16); + //var index = Convert.ToInt32(((colNo % 3 == 0 ? 3 : colNo % 3)+10).ToString(),16); + int channel = Convert.ToInt32((drawerNo * 10 + Math.Ceiling((decimal)colNo / 3)).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x09, (byte)bColNo, 0, 0, 0, 0xee }; + canBusSerial.Write(buffer, 0, 8); + logger.Info($"清屏指令:{Convert.ToHexString(buffer)}"); + } + //刷新内容 + public async Task ShowContentMethod(int drawerNo, int colNo) + { + int channel = Convert.ToInt32((drawerNo * 10 + Math.Ceiling((decimal)colNo / 3)).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)channel, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xee }; + logger.Info($"刷新内容指令:{Convert.ToHexString(buffer)}"); + canBusSerial.Write(buffer, 0, 8); + } + // 基础数据写入方法 + public async Task WriteChannelInfoMethod(int type, string content, int drawerNo, int colNo) + { + try + { + canBusSerial.DiscardInBuffer(); + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + if (content.Length > 10) + { + content = content.Substring(0, 10); + } + byte[] contentBuf = Encoding.GetEncoding("gb2312").GetBytes(trim(content)); + int channel = Convert.ToInt32((drawerNo * 10 + Math.Ceiling((decimal)colNo / 3)).ToString(), 16); + int[] iNum = new int[] { 3, 2, 1 }; + var colNo2 = colNo % 3 > 0 ? (colNo % 3) - 1 : 2; + var bColNo = iNum[colNo2] + 160; + //var index = (colNo % 3 == 0 ? 3 : colNo % 3)+160; + if (contentBuf.Length % 2 != 0) + { + Array.Resize(ref contentBuf, contentBuf.Length + 1); + } + byte[] buffer = new byte[] { 0xaa, (byte)channel, (byte)bColNo, (byte)type, 0, 0, 0, 0xee }; + + + canBusSerial.Write(buffer, 0, 8); + logger.Info($"开始写标签指令:{Convert.ToHexString(buffer)}"); + Thread.Sleep(20); + buffer[4] = 1; + for (int i = 0; i < contentBuf.Length; i += 2) + { + buffer[5] = contentBuf[i]; + buffer[6] = contentBuf[i + 1]; + canBusSerial.Write(buffer, 0, 8); + logger.Info($"写标签指令:{Convert.ToHexString(buffer)}"); + Thread.Sleep(50); + } + buffer[4] = 2; + buffer[5] = 0; + buffer[6] = 0; + canBusSerial.Write(buffer, 0, 8); + logger.Info($"结束写标签指令:{Convert.ToHexString(buffer)}"); + Thread.Sleep(20); + + } + catch (Exception ex) + { + logger.Info($"2.4寸汉显屏异常:ex:{ex.Message}"); + } + } + + public async Task WriteQuantityMethod(int quantity, int drawerNo, int colNo) + { + try + { + logger.Info($"写数量:{drawerNo}-{colNo}:{quantity}"); + canBusSerial.DiscardInBuffer(); + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + string strQuantity = quantity.ToString("X"); + if (strQuantity.Length % 2 != 0) + { + strQuantity = "0" + strQuantity; + } + int channel = Convert.ToInt32((drawerNo * 10 + Math.Ceiling((decimal)colNo / 3)).ToString(), 16); + int[] iNum = new int[] { 3, 2, 1 }; + var colNo2 = colNo % 3 > 0 ? (colNo % 3) - 1 : 2; + var bColNo = iNum[colNo2] + 160; + byte[] buffer = new byte[] { 0xaa, (byte)channel, (byte)bColNo, 0xf2, 01, 0, 0, 0xee }; + if (strQuantity.Length >= 4) + { + buffer[5] = Convert.ToByte(strQuantity.Substring(0, 2), 16); + buffer[6] = Convert.ToByte(strQuantity.Substring(2, 2), 16); + } + else + { + + buffer[6] = Convert.ToByte(strQuantity.Substring(0, 2), 16); + } + canBusSerial.Write(buffer, 0, 8); + logger.Info($"写标签指令:{Convert.ToHexString(buffer)}"); + } + catch (Exception ex) + { + logger.Info($"写标签数量异常:ex:{ex.Message}"); + } + } + + #endregion + + #region 回收箱操作 + // 打开回收箱 + public async Task OpenRecover() + { + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xAA, 0x9A, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEE }; + canBusSerial.Write(buffer, 0, 8); + + return await GetBufferByPort(canBusSerial, 8); + } + // 回收箱状态查询 + public async Task CheckRecoverStatus() + { + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xAA, 0x9A, 0x03, 0x00, 0x00, 0x00, 0x00, 0xEE }; + canBusSerial.Write(buffer, 0, 8); + + return await GetBufferByPort(canBusSerial, 8); + } + // 回收箱回收数量查询 + public async Task CheckRecoverQuantity(int ColNo) + { + canBusSerial.DiscardInBuffer(); + byte[] buffer = new byte[] { 0xAA, 0x9A, (byte)(ColNo > 3 ? 2 : 1), 0x00, 0x00, 0x00, 0x00, 0xEE }; + canBusSerial.Write(buffer, 0, 8); + + return await GetBufferByPort(canBusSerial, 8); + } + #endregion + + #region 称重操作 + // 以板子为单位获取抽屉内所有库位的药品数量 + public async Task CheckQuantityByAddr(int DrawerNo) + { + + canBusSerial.DiscardInBuffer(); + var channel = Convert.ToInt32((DrawerNo * 10 + 1).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x28, 0x00, 0x00, 0x00, 0x00, 0xee }; + logger.Info($"称重发送库位数量查询1【{string.Join(",", buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + byte[] result1 = await GetBufferByPort(canBusSerial, 8); + + + var channel2 = Convert.ToInt32((DrawerNo * 10 + 2).ToString(), 16); + byte[] buffer2 = new byte[] { 0xaa, (byte)(channel2), 0x28, 0x00, 0x00, 0x00, 0x00, 0xee }; + logger.Info($"称重发送库位数量查询2【{string.Join(",", buffer2)}】"); + canBusSerial.Write(buffer2, 0, 8); + byte[] result2 = await GetBufferByPort(canBusSerial, 8); + + byte[] res = new byte[6]; + Array.Copy(result1, 3, res, 0, 3); + Array.Copy(result2, 3, res, 3, 3); + + return res; + + } + + // 以板子为单位获取抽屉内所有库位的药品数量 + public async Task CheckQuantityByAddr2(int DrawerNo, int[] ColNos) + { + + + int[] res = new int[6]; + for (int i = 0; i < ColNos.Length; i++) + { + canBusSerial.DiscardInBuffer(); + var index = ColNos[i] > 3 ? 2 : 1; + var lock1 = ColNos[i] % 3 == 0 ? 3 : ColNos[i] % 3; + var channel = Convert.ToInt32((DrawerNo * 10 + index).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x27, (byte)lock1, 0x00, 0x00, 0x00, 0xee }; + + logger.Info($"称重发送库位数量查询1【{string.Join(",", buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + byte[] result = await GetBufferByPort(canBusSerial, 8); + logger.Info($"称重发送库位数量查询1返回结果【{string.Join(",", result)}】"); + byte[] hl = result.Skip(3).Take(2).ToArray(); + int quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + res[ColNos[i] - 1] = quantity; + } + + return res; + + } + + // 指定药盒指示灯开启使能开锁 + public async Task BoxLockLightOn2(int DrawerNo, int[] ColNos) + { + for (int i = 0; i < ColNos.Length; i++) + { + var index = ColNos[i] > 3 ? 2 : 1; + var lock1 = ColNos[i] % 3 == 0 ? 3 : ColNos[i] % 3; + var channel = Convert.ToInt32((DrawerNo * 10 + index).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x03, (byte)lock1, 0x00, 0x00, 0x00, 0xee }; + logger.Info($"称重发送药盒使能【{string.Join(",", buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(TimeSpan.FromMilliseconds(500)); + } + } + // 指定药盒指示灯开启失能开锁 + public async Task BoxLockLightOff2(int DrawerNo, int[] ColNos) + { + canBusSerial.DiscardInBuffer(); + for (int i = 0; i < ColNos.Length; i++) + { + var index = ColNos[i] > 3 ? 2 : 1; + var lock1 = ColNos[i] % 3 == 0 ? 3 : ColNos[i] % 3; + var channel = Convert.ToInt32((DrawerNo * 10 + index).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x04, (byte)lock1, 0x00, 0x00, 0x00, 0xee }; + logger.Info($"称重发送药盒失能【{string.Join(",", buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + await Task.Delay(TimeSpan.FromMilliseconds(50)); + } + } + + public async void ClearCount(int DrawerNo, int ColNo) + { + canBusSerial.DiscardInBuffer(); + var index = ColNo > 3 ? 2 : 1; + var lock1 = ColNo % 3 == 0 ? 3 : ColNo % 3; + var channel = Convert.ToInt32((DrawerNo * 10 + index).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x25, (byte)lock1, 0x00, 0x00, 0x00, 0xee }; + + logger.Info($"称重发送清空计数【{string.Join(",", buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + } + + public async void SetNumCount(int DrawerNo, int ColNo, int Quantity) + { + canBusSerial.DiscardInBuffer(); + var index = ColNo > 3 ? 2 : 1; + var lock1 = ColNo % 3 == 0 ? 3 : ColNo % 3; + var channel = Convert.ToInt32((DrawerNo * 10 + index).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x26, (byte)lock1, 0x00, 0x00, 0x00, 0xee }; + + + buffer[4] = (byte)(Quantity >> 8); + buffer[5] = (byte)(Quantity & 0xff); + + + logger.Info($"称重发送数量【{string.Join(",", buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + } + + // 以板子为单位获取抽屉内所有库位的药品数量 + public async Task CheckQuantityByAddr() + { + + canBusSerial.DiscardInBuffer(); + var channel = Convert.ToInt32((DrawerNo * 10 + 1).ToString(), 16); + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x28, 0x00, 0x00, 0x00, 0x00, 0xee }; + logger.Info($"称重发送库位数量查询1【{Convert.ToHexString(buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + byte[] result1 = await GetBufferByPort(canBusSerial, 8); + + + var channel2 = Convert.ToInt32((DrawerNo * 10 + 2).ToString(), 16); + byte[] buffer2 = new byte[] { 0xaa, (byte)(channel2), 0x28, 0x00, 0x00, 0x00, 0x00, 0xee }; + logger.Info($"称重发送库位数量查询2【{Convert.ToHexString(buffer2)}】"); + canBusSerial.Write(buffer2, 0, 8); + byte[] result2 = await GetBufferByPort(canBusSerial, 8); + + byte[] res = new byte[6]; + Array.Copy(result1, 3, res, 0, 3); + Array.Copy(result2, 3, res, 3, 3); + + return res; + + } + // 以板子为单位获取抽屉内所有库位的药品数量 + public async Task CheckQuantityByAddrForMulti() + { + + + int[] res = new int[9]; + for (int i = 0; i < ColNoLst.Count; i++) + { + Thread.Sleep(200); + canBusSerial.DiscardInBuffer(); + int colNo = ColNoLst[i]; + int[] iNum = new int[] { 3, 2, 1 }; + var colNo2 = colNo % 3 > 0 ? (colNo % 3) - 1 : 2; + var bColNo = iNum[colNo2]; + decimal decolNO = (decimal)colNo; + var channel = Convert.ToInt32((DrawerNo * 10 + Math.Ceiling(decolNO / 3)).ToString(), 16); + + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x27, (byte)bColNo, 0x00, 0x00, 0x00, 0xee }; + + logger.Info($"称重发送库位数量查询{ColNoLst[i]}【{Convert.ToHexString(buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + byte[] result = await GetBufferByPort(canBusSerial, 8); + logger.Info($"称重发送库位数量查询返回结果【{Convert.ToHexString(result)}】"); + byte[] hl = result.Skip(4).Take(2).ToArray(); + var r = Convert.ToHexString(result).Substring(8, 1); + int quantity = 0; + if (r == "8") + { + hl[0] -= 0x80; + quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + logger.Info($"获取值为负数{quantity}"); + quantity = 0 - quantity; + } + else + { + quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + logger.Info($"获取值为正数{quantity}"); + } + + res[ColNoLst[i] - 1] = quantity; + } + + return res; + + } + //获取单个称重药合的药品数量 --查数 + public async Task CheckQuantityForSingle(int colNo) + { + //await Task.Delay(300); + //canBusSerial.DiscardInBuffer(); + //var index = colNo % 3 == 0 ? 3 : colNo % 3; + //var lock1 = colNo <= 3 ? 3 : colNo >= 7 ? 1 : 2; + //var channel = Convert.ToInt32((DrawerNo * 10 + index).ToString(), 16); + + + canBusSerial.DiscardInBuffer(); + int[] iNum = new int[] { 3, 2, 1 }; + var colNo2 = colNo % 3 > 0 ? (colNo % 3) - 1 : 2; + var bColNo = iNum[colNo2]; + decimal decolNO = (decimal)colNo; + var channel = Convert.ToInt32((DrawerNo * 10 + Math.Ceiling(decolNO / 3)).ToString(), 16); + + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x27, (byte)bColNo, 0x00, 0x00, 0x00, 0xee }; + + logger.Info($"称重发送库位数量查询{colNo}【{Convert.ToHexString(buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + byte[] result = await GetBufferByPort(canBusSerial, 8); + byte[] hl = result.Skip(4).Take(2).ToArray(); + var r = Convert.ToHexString(result).Substring(8, 1); + logger.Info($"称重发送库位数量查询返回结果【{Convert.ToHexString(result)}】"); + + if (r == "8") + { + hl[0] -= 0x80; + int quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + logger.Info($"获取值为负数{quantity}"); + return 0 - quantity; + } + else + { + int quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + logger.Info($"获取值为正数{quantity}"); + return quantity; + } + + } + //获取单个称重药合的药品数量---标定(标定查数与库位查数区别在于用不用忽略0x80) + public async Task CheckQuantityForBiaoDing(int colNo) + { + canBusSerial.DiscardInBuffer(); + int[] iNum = new int[] { 3, 2, 1 }; + var colNo2 = colNo % 3 > 0 ? (colNo % 3) - 1 : 2; + var bColNo = iNum[colNo2]; + decimal decolNO = (decimal)colNo; + var channel = Convert.ToInt32((DrawerNo * 10 + Math.Ceiling(decolNO / 3)).ToString(), 16); + + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x27, (byte)bColNo, 0x00, 0x00, 0x00, 0xee }; + + logger.Info($"称重发送库位数量查询{colNo}【{Convert.ToHexString(buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + byte[] result = await GetBufferByPort(canBusSerial, 8); + logger.Info($"称重发送库位数量查询返回结果【{Convert.ToHexString(result)}】"); + byte[] hl = result.Skip(4).Take(2).ToArray(); + int quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + + return quantity; + + } + // 以板子为单位获取抽屉内所有库位的药品数量 + public async Task CheckQuantityByAddr2() + { + + + int[] res = new int[9]; + for (int i = 0; i < ColNos.Length; i++) + { + await Task.Delay(300); + canBusSerial.DiscardInBuffer(); + int colNo = ColNos[i]; + int[] iNum = new int[] { 3, 2, 1 }; + var colNo2 = colNo % 3 > 0 ? (colNo % 3) - 1 : 2; + var bColNo = iNum[colNo2]; + decimal decolNO = (decimal)colNo; + var channel = Convert.ToInt32((DrawerNo * 10 + Math.Ceiling(decolNO / 3)).ToString(), 16); + + byte[] buffer = new byte[] { 0xaa, (byte)(channel), 0x27, (byte)bColNo, 0x00, 0x00, 0x00, 0xee }; + + logger.Info($"称重发送库位数量查询{ColNos[i]}【{Convert.ToHexString(buffer)}】"); + canBusSerial.Write(buffer, 0, 8); + byte[] result = await GetBufferByPort(canBusSerial, 8); + logger.Info($"称重发送库位数量查询返回结果【{Convert.ToHexString(result)}】"); + byte[] hl = result.Skip(4).Take(2).ToArray(); + //int quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + var r = Convert.ToHexString(result).Substring(8, 1); + int quantity = 0; + if (r == "8") + { + hl[0] -= 0x80; + quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + logger.Info($"获取值为负数{quantity}"); + quantity = 0 - quantity; + } + else + { + quantity = BitConverter.ToInt16(hl.Reverse().ToArray(), 0); + logger.Info($"获取值为正数{quantity}"); + } + + + res[ColNos[i] - 1] = quantity; + } + + return res; + + } + + #endregion 称重操作 + #endregion + + } +} diff --git a/MasaBlazorApp3/Port/ScreenUtil.cs b/MasaBlazorApp3/Port/ScreenUtil.cs new file mode 100644 index 0000000..78cdce7 --- /dev/null +++ b/MasaBlazorApp3/Port/ScreenUtil.cs @@ -0,0 +1,171 @@ +using log4net; +using MasaBlazorApp3.Pojo; +using SuperSimpleTcp; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Channels; +using System.Threading.Tasks; +using System.Windows.Markup; + +namespace MasaBlazorApp3.Port +{ + public class ScreenUtil + { + private readonly ILog logger = LogManager.GetLogger(typeof(ScreenUtil)); + SimpleTcpServer server = new SimpleTcpServer("0.0.0.0:8888"); + + string ipport { get; set; } = ""; + public ScreenUtil() + { + server.Events.ClientConnected += (object sender, ConnectionEventArgs e) => + { + ipport = e.IpPort; + logger.Info($"[{e.IpPort}] client connected"); + }; + server.Events.ClientDisconnected += (object sender, ConnectionEventArgs e) => + { + logger.Info($"[{e.IpPort}] client disconnected: {e.Reason}"); + }; + server.Events.DataReceived += (object sender, DataReceivedEventArgs e) => + { + logger.Info($"[{e.IpPort}]: {e.Data.Array}"); + }; + // let's go! + server.Start(); + } + + + private byte[] head = new byte[] { 0xee, 0xb1, 0x12 }; + + private byte[] end = new byte[] { 0xFF, 0xFC, 0xFF, 0xFF }; + public void SetStockInfo(ChannelStock channel, int screenId) + { + // 添加画面id + byte[] a = Copy2NewArr(head, HighLow(screenId)); + + + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + //if (channel.DrugInfo.DrugName != null) + //{ + byte[] content = Encoding.GetEncoding("gb2312").GetBytes(channel.Drug?.DrugName??""); + a = WriteInfo(a, content, channel.ColNo * 10 + 1); + //} + //if (channel.DrugInfo.Manufactory != null) + //{ + byte[] content1 = Encoding.GetEncoding("gb2312").GetBytes(channel.Drug?.Manufactory?? ""); + a = WriteInfo(a, content1, channel.ColNo * 10 + 2); + //} + //if (channel.DrugInfo.DrugSpec != null) + //{ + byte[] content2 = Encoding.GetEncoding("gb2312").GetBytes(channel.Drug?.DrugSpec ?? ""); + a = WriteInfo(a, content2, channel.ColNo * 10 + 3); + //} + //if (channel.ManuNo != null) + //{ + + byte[] content3 = Encoding.GetEncoding("gb2312").GetBytes(channel.ManuNo); + a = WriteInfo(a, content3, channel.ColNo * 10 + 4); + //} + //if (channel.EffDate != null) + //{ + byte[] content4 = Encoding.GetEncoding("gb2312").GetBytes(channel.EffDate); + a = WriteInfo(a, content4, channel.ColNo * 10 + 5); + //} + //if (channel.Quantity != null) + //{ + byte[] content5 = Encoding.GetEncoding("gb2312").GetBytes(channel.Quantity.ToString()); + a = WriteInfo(a, content5, channel.ColNo * 10 + 6); + //} + // 添加结束块 + byte[] b = Copy2NewArr(a, end); + server.Send(ipport, b); + } + + + public void TellChange(int d) + { + byte[] buffer = new byte[] { 0xee, 0xb5, 0x01, 0x00, 0xFF, 0xFC, 0xFF, 0xFF }; + + } + + public void SetStockInfo(List channels, int screenId) + { + // 添加画面id + byte[] a = Copy2NewArr(head, HighLow(screenId)); + + + for (int i = 0; i < channels.Count; i++) + { + ChannelStock channel = channels[i]; + if (channel.Drug.DrugName != null) + { + byte[] content = Encoding.ASCII.GetBytes(channel.Drug.DrugName); + a = WriteInfo(a, content, channels[0].DrawerNo * 10 + 1); + } + if (channel.Drug.Manufactory != null) + { + byte[] content = Encoding.ASCII.GetBytes(channel.Drug.Manufactory); + a = WriteInfo(a, content, channels[0].DrawerNo * 10 + 2); + } + if (channel.Drug.DrugSpec != null) + { + byte[] content = Encoding.ASCII.GetBytes(channel.Drug.DrugSpec); + a = WriteInfo(a, content, channels[0].DrawerNo * 10 + 3); + } + if (channel.ManuNo != null) + { + + byte[] content = Encoding.ASCII.GetBytes(channel.ManuNo); + a = WriteInfo(a, content, channels[0].DrawerNo * 10 + 4); + } + if (channel.EffDate != null) + { + byte[] content = Encoding.ASCII.GetBytes(channel.EffDate); + a = WriteInfo(a, content, channels[0].DrawerNo * 10 + 5); + } + if (channel.Quantity != null) + { + byte[] content = Encoding.ASCII.GetBytes(channel.Quantity.ToString()); + a = WriteInfo(a, content, channels[0].DrawerNo * 10 + 6); + } + + + } + // 添加结束块 + byte[] b = Copy2NewArr(a, end); + server.Send(ipport, b); + } + + + public byte[] WriteInfo(byte[] a, byte[] content, int id) + { + // 添加控件id + byte[] b = Copy2NewArr(a, HighLow(id)); + // 添加需要向控件内写入的字节长度 + byte[] c = Copy2NewArr(b, HighLow(content.Length)); + // 写入内容 + return Copy2NewArr(c, content); + } + + public byte[] HighLow(int data) + { + byte high = Convert.ToByte((data >> 8) & 0x00ff); //位运算:右移8位 + byte low = Convert.ToByte(data & 0x00ff); //去掉高位 + return new byte[] {high, low}; + } + + public byte[] Copy2NewArr(byte[] source1, byte[] source2) + { + byte[] target = new byte[source1.Length + source2.Length]; + Buffer.BlockCopy(source1, 0, target, 0, source1.Length); + Buffer.BlockCopy(source2, 0, target, source1.Length, source2.Length); + return target; + } + + + + } +} diff --git a/MasaBlazorApp3/Program.cs b/MasaBlazorApp3/Program.cs new file mode 100644 index 0000000..6cae607 --- /dev/null +++ b/MasaBlazorApp3/Program.cs @@ -0,0 +1,92 @@ +using log4net.Config; +using MasaBlazorApp3; +using MasaBlazorApp3.DataAccess.Dao; +using MasaBlazorApp3.DataAccess.Impl; +using MasaBlazorApp3.DataAccess; +using MasaBlazorApp3.Finger; +using Microsoft.Extensions.DependencyInjection; +using Photino.Blazor; +using LinqToDB.AspNet; +using LinqToDB; +using Microsoft.Extensions.Configuration; +using LinqToDB.AspNet.Logging; +using Radzen; +using MasaBlazorApp3.Pojo.Config; +using MasaBlazorApp3.Port; + +internal class Program +{ + + [STAThread] + private static void Main(string[] args) + { + var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args); + + appBuilder.RootComponents.Add("#app"); + appBuilder.Services.AddRadzenComponents(); + // 指纹机工具类 + appBuilder.Services.AddSingleton(); + // 串口工具类 + appBuilder.Services.AddSingleton(); + // 登录用户全局存放 + appBuilder.Services.AddSingleton(); + // 框架自带通知服务注入 + appBuilder.Services.AddScoped(); + appBuilder.Services.AddScoped(); + appBuilder.Services.AddScoped(); + + // 注入log + XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config")); + + //设置配置文件 + var config = new ConfigurationBuilder() + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .Build(); + // 注入配置 + appBuilder.Services.Configure(config.GetSection("finger")); + appBuilder.Services.Configure(config.GetSection("setting")); + appBuilder.Services.Configure(config.GetSection("port")); + appBuilder.Services.Configure(config.GetSection("drawer")); + + // i18n + //appBuilder.Services.AddI18nText(); + // 数据库 + appBuilder.Services.AddLinqToDBContext((provider, options) => + options.UseMySql(config.GetValue("connectionStrings")) + .UseDefaultLogging(provider)); + // dao层数据库操作 + appBuilder.Services.AddScoped(); + appBuilder.Services.AddScoped(); + appBuilder.Services.AddScoped(); + appBuilder.Services.AddScoped(); + appBuilder.Services.AddScoped(); + appBuilder.Services.AddScoped(); + appBuilder.Services.AddScoped(); + + //自选取药 + appBuilder.Services.AddScoped(); + + //药品批次 + appBuilder.Services.AddScoped(); + + var app = appBuilder.Build(); + app.MainWindow + .SetHeight(768) + .SetWidth(1024) + .SetIconFile("favicon.ico") + .SetContextMenuEnabled(false) +#if DEBUG + .SetFullScreen(false) +#else + .SetChromeless(true) + .SetFullScreen(true) +#endif + ; + + + AppDomain.CurrentDomain.UnhandledException += (sender, error) => + { + }; + app.Run(); + } +} \ No newline at end of file diff --git a/MasaBlazorApp3/Report/GridReportUtil.cs b/MasaBlazorApp3/Report/GridReportUtil.cs new file mode 100644 index 0000000..b1057df --- /dev/null +++ b/MasaBlazorApp3/Report/GridReportUtil.cs @@ -0,0 +1,38 @@ +using gregn6Lib; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Configuration; + +namespace MasaBlazorApp3.Report +{ + public class GridReportUtil + { + + // 定义Grid++Report报表主对象 + public static GridppReport Report = new GridppReport(); + /** + * 打印预览 + * tempname: 模板文件名称 + * data: 模板数据 + */ + public static void PrintReport(string tempname, object data) + { + // 定义Grid++Report报表主对象 + // 加载模板文件 + Report.LoadFromFile(new FileInfo(AppDomain.CurrentDomain.BaseDirectory) + "ReportTemp//" + tempname); + string s = JsonConvert.SerializeObject(data); + // 加载数据 + Report.LoadDataFromXML(JsonConvert.SerializeObject(data)); + Report.PrintPreview(true); + } + + + + + } +} diff --git a/MasaBlazorApp3/ReportTemp/account_book_temp.grf b/MasaBlazorApp3/ReportTemp/account_book_temp.grf new file mode 100644 index 0000000..fad67cd --- /dev/null +++ b/MasaBlazorApp3/ReportTemp/account_book_temp.grf @@ -0,0 +1,612 @@ +{ + "Version":"6.8.5.2", + "Font":{ + "Name":"宋体", + "Size":105000, + "Weight":400, + "Charset":134 + }, + "Printer":{ + "Oriention":"Landscape", + "LeftMargin":1, + "TopMargin":1.42875, + "RightMargin":1, + "BottomMargin":1.8 + }, + "DetailGrid":{ + "CenterView":true, + "AppendBlankRow":true, + "Recordset":{ + "ConnectionString":"MYSQL;\r\nDatabase=hkcdb;\r\nPassword=qq1223;\r\nPort=3307;\r\nServer=127.0.0.1;\r\nUser=root;", + "QuerySQL":"SELECT \r\n mr.`stock_quantity` AS `stockQuantity`,\r\n IF(mr.`type` IN (1, 31), mr.`quantity`, IF(mr.`type` = 4 AND mr.`quantity` > 0, mr.`quantity`, 0)) AS `inQuantity`,\r\n IF(mr.`type` = 2, mr.`quantity`, IF(mr.`type` = 4 AND mr.`quantity` < 0, (0 - mr.`quantity`), 0)) AS `outQuantity`,\r\n mr.`operation_time` AS `operationTime`,\r\n mr.`invoice_id` AS `invoiceId`,\r\n di.`drug_name` AS `drugName`,\r\n di.`drug_id` AS `drugId`,\r\n di.`drug_spec` AS `drugSpec`,\r\n di.`pack_unit` AS `packUnit`,\r\n di.`dosage` AS `dosage`,\r\n di.`manufactory` AS `manufactory`,\r\n mr.`manu_no` AS `manuNo`,\r\n mr.`eff_date` AS `effDate`,\r\n u1.`user_name` AS `operatorName`,\r\n u2.`user_name` AS `reviewerName`\r\nFROM\r\n dm_machine_record mr \r\n LEFT JOIN drug_info di ON mr.`drug_id` = di.`drug_id` \r\n LEFT JOIN user_list u1 ON mr.`operator` = u1.`id`\r\n LEFT JOIN user_list u2 ON mr.`reviewer` = u2.`id`\r\n ORDER BY mr.`drug_id`, mr.`operation_time`, mr.`id`", + "Field":[ + { + "Name":"日期", + "Type":"DateTime", + "Format":"M/d", + "DBFieldName":"operationTime" + }, + { + "Name":"操作类型", + "DBFieldName":"type" + }, + { + "Name":"批号", + "DBFieldName":"manuNo" + }, + { + "Name":"上次批次结存", + "Type":"Integer", + "DBFieldName":"beforeManuQuan" + }, + { + "Name":"入库数量", + "Type":"Integer", + "DBFieldName":"inQuantity" + }, + { + "Name":"出库数量", + "Type":"Integer", + "DBFieldName":"outQuantity" + }, + { + "Name":"批号结存", + "Type":"Integer", + "DBFieldName":"manuQuantity" + }, + { + "Name":"总结存", + "Type":"Integer", + "DBFieldName":"stockQuantity" + }, + { + "Name":"收/发药人", + "DBFieldName":"operatorName" + }, + { + "Name":"复核人", + "DBFieldName":"reviewName" + }, + { + "Name":"药品名称", + "DBFieldName":"drugName" + }, + { + "Name":"规格", + "DBFieldName":"drugSpec" + }, + { + "Name":"单位", + "DBFieldName":"packUnit" + }, + { + "Name":"剂型", + "DBFieldName":"dosage" + }, + { + "Name":"厂家", + "DBFieldName":"manuFactory" + }, + { + "Name":"有效期", + "Type":"DateTime", + "Format":"yy/M/d", + "DBFieldName":"effDate" + }, + { + "Name":"sign1", + "Type":"Binary" + }, + { + "Name":"sign2", + "Type":"Binary" + }, + { + "Name":"drugId" + } + ] + }, + "Column":[ + { + "Name":"日期", + "Width":1.77271 + }, + { + "Name":"操作类型", + "Width":2.19604 + }, + { + "Name":"批号", + "Width":3.99521 + }, + { + "Name":"有效期", + "Width":2.43417 + }, + { + "Name":"入库数量", + "Width":1.79917 + }, + { + "Name":"出库数量", + "Width":1.79917 + }, + { + "Name":"Column4", + "Width":1.98438 + }, + { + "Name":"收/发药人", + "Width":2.80458 + }, + { + "Name":"复核人", + "Width":2.80458 + }, + { + "Name":"Column2", + "Width":2.35479 + }, + { + "Name":"Column3", + "Width":2.38125 + } + ], + "ColumnContent":{ + "Height":0.85, + "ColumnContentCell":[ + { + "Column":"日期", + "TextAlign":"MiddleCenter", + "DataField":"日期" + }, + { + "Column":"操作类型", + "FreeCell":true, + "Control":[ + { + "Type":"StaticBox", + "Name":"StaticBox10", + "Dock":"Fill", + "TextAlign":"MiddleCenter" + } + ] + }, + { + "Column":"批号", + "TextAlign":"MiddleCenter", + "DataField":"批号" + }, + { + "Column":"有效期", + "TextAlign":"MiddleCenter", + "DataField":"有效期" + }, + { + "Column":"入库数量", + "TextAlign":"MiddleCenter", + "DataField":"入库数量" + }, + { + "Column":"出库数量", + "TextAlign":"MiddleCenter", + "DataField":"出库数量" + }, + { + "Column":"Column4", + "TextAlign":"MiddleCenter", + "DataField":"总结存" + }, + { + "Column":"收/发药人", + "FreeCell":true, + "Control":[ + { + "Type":"FieldBox", + "Name":"FieldBox12", + "Dock":"Fill", + "TextAlign":"MiddleCenter", + "DataField":"收/发药人" + } + ] + }, + { + "Column":"复核人", + "FreeCell":true, + "Control":[ + { + "Type":"FieldBox", + "Name":"FieldBox13", + "Dock":"Fill", + "TextAlign":"MiddleCenter", + "DataField":"复核人" + } + ] + }, + { + "Column":"Column2", + "FreeCell":true, + "Control":[ + { + "Type":"StaticBox", + "Name":"StaticBox6", + "Dock":"Fill", + "TextAlign":"MiddleCenter", + "Text":"药库" + } + ] + }, + { + "Column":"Column3", + "FreeCell":true, + "Control":[ + { + "Type":"StaticBox", + "Name":"StaticBox7", + "Dock":"Fill", + "TextAlign":"MiddleCenter", + "Text":"门诊药房" + } + ] + } + ] + }, + "ColumnTitle":{ + "Height":1.19063, + "RepeatStyle":"OnGroupHeaderPage", + "ColumnTitleCell":[ + { + "GroupTitle":false, + "Column":"日期", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"日期" + }, + { + "GroupTitle":false, + "Column":"操作类型", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"凭证号" + }, + { + "GroupTitle":false, + "Column":"批号", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"批号" + }, + { + "GroupTitle":false, + "Column":"有效期", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"有效\r\n期" + }, + { + "GroupTitle":false, + "Column":"入库数量", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"借入\r\n数量" + }, + { + "GroupTitle":false, + "Column":"出库数量", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"发出\r\n数量" + }, + { + "GroupTitle":false, + "Column":"Column4", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"总结存" + }, + { + "GroupTitle":false, + "Column":"收/发药人", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"发药人" + }, + { + "GroupTitle":false, + "Column":"复核人", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"复核人" + }, + { + "GroupTitle":false, + "Column":"Column2", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"供应单位" + }, + { + "GroupTitle":false, + "Column":"Column3", + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"领用部门" + } + ] + }, + "Group":[ + { + "Name":"Group1", + "ByFields":"drugId", + "GroupHeader":{ + "PrintGridBorder":false, + "RepeatOnPage":true, + "Control":[ + { + "Type":"StaticBox", + "Name":"StaticBox15", + "Left":28.3898, + "Top":0.238125, + "Width":2.01083, + "Height":0.79375, + "Text":"生产厂家:" + }, + { + "Type":"MemoBox", + "Name":"MemoBox11", + "Left":30.3742, + "Top":0.211667, + "Width":5.3975, + "Height":0.79375, + "Text":"[#manuFactory#]" + }, + { + "Type":"StaticBox", + "Name":"StaticBox16", + "Top":0.0529167, + "Width":1.19063, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "Text":"品名:" + }, + { + "Type":"FieldBox", + "Name":"FieldBox7", + "Left":1.16417, + "Top":0.0529167, + "Width":5.63563, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "DataField":"药品名称" + }, + { + "Type":"StaticBox", + "Name":"StaticBox17", + "Left":6.93208, + "Top":0.0529167, + "Width":1.11125, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "Text":"规格:" + }, + { + "Type":"FieldBox", + "Name":"FieldBox8", + "Left":8.01688, + "Top":0.0529167, + "Width":3.175, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "DataField":"规格" + }, + { + "Type":"StaticBox", + "Name":"StaticBox18", + "Left":11.5888, + "Top":0.0529167, + "Width":1.21708, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "Text":"单位:" + }, + { + "Type":"FieldBox", + "Name":"FieldBox9", + "Left":12.7794, + "Top":0.0529167, + "Width":1.87854, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "DataField":"单位" + }, + { + "Type":"StaticBox", + "Name":"StaticBox19", + "Left":15.3988, + "Top":0.0529167, + "Width":1.16417, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "Text":"剂型:" + }, + { + "Type":"FieldBox", + "Name":"FieldBox10", + "Left":16.5365, + "Top":0.0529167, + "Width":2.83104, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "DataField":"剂型" + }, + { + "Type":"StaticBox", + "Name":"StaticBox20", + "Left":19.7379, + "Top":0.0529167, + "Width":2.01083, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "Text":"生产厂家:" + }, + { + "Type":"FieldBox", + "Name":"FieldBox11", + "Left":21.7223, + "Top":0.05, + "Width":5.92667, + "Height":0.978958, + "Font":{ + "Name":"宋体", + "Size":105000, + "Bold":true, + "Charset":134 + }, + "DataField":"厂家" + } + ], + "NewPageColumn":"Before" + }, + "GroupFooter":{ + "Visible":false + } + } + ] + }, + "Parameter":[ + { + "Name":"machine_id" + }, + { + "Name":"startDate", + "DataType":"DateTime" + }, + { + "Name":"endDate", + "DataType":"DateTime" + } + ], + "ReportHeader":[ + { + "Name":"ReportHeader1", + "Height":1.79917, + "Control":[ + { + "Type":"MemoBox", + "Name":"MemoBox1", + "Dock":"Fill", + "Center":"Both", + "Font":{ + "Name":"宋体", + "Size":262500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"麻醉、精神药品逐笔专用账册" + } + ], + "RepeatOnPage":true + } + ] +} \ No newline at end of file diff --git a/MasaBlazorApp3/ReportTemp/machine_log_add.grf b/MasaBlazorApp3/ReportTemp/machine_log_add.grf new file mode 100644 index 0000000..cb34783 --- /dev/null +++ b/MasaBlazorApp3/ReportTemp/machine_log_add.grf @@ -0,0 +1,284 @@ +{ + "Version":"6.8.5.2", + "Font":{ + "Name":"宋体", + "Size":105000, + "Weight":400, + "Charset":134 + }, + "Printer":{ + "LeftMargin":0.3175, + "TopMargin":0.899583, + "RightMargin":0.396875 + }, + "DetailGrid":{ + "CenterView":true, + "AppendBlankRow":true, + "Recordset":{ + "ConnectionString":"MYSQL;\r\nDatabase=hkcdb;\r\nPassword=qq1223;\r\nPort=3307;\r\nServer=127.0.0.1;\r\nUser=root;", + "QuerySQL":"SELECT \r\n dmr.`drawer_no` AS drawerNo,\r\n dmr.`col_no` AS colNo,\r\n dmr.`type` AS `type`,\r\n dmr.`quantity` AS quantity,\r\n dmr.`manu_no` AS manuNo,\r\n dmr.`eff_date` AS effDate,\r\n dmr.`operation_time` AS operationTime,\r\n di.`drug_name` AS drugName,\r\n di.`drug_spec` AS drugSpec,\r\n di.`pack_unit` AS packUnit,\r\n di.`manufactory` AS manuFactory,\r\n di.`max_stock` AS baseQuantity,\r\n dmr.`drug_id` AS drugId,\r\n ul.`user_name` AS nickname\r\nFROM\r\n dm_machine_record dmr\r\nLEFT JOIN drug_info di ON di.`drug_id` = dmr.`drug_id`\r\nLEFT JOIN user_list ul ON ul.`id` = dmr.`Operator`\r\nWHERE dmr.`type` = 1 \r\n AND dmr.`machine_id` = :machine_id\r\n AND dmr.`operation_time` > :startDate\r\n AND dmr.`operation_time` < :endDate", + "Field":[ + { + "Name":"操作人", + "DBFieldName":"Nickname" + }, + { + "Name":"时间", + "Type":"DateTime", + "Format":"yyyy/MM/dd HH:mm:ss", + "DBFieldName":"operationTime" + }, + { + "Name":"药品名称", + "DBFieldName":"DrugName" + }, + { + "Name":"数量", + "DBFieldName":"quantity" + }, + { + "Name":"批次", + "DBFieldName":"manuNo" + }, + { + "Name":"效期", + "Type":"DateTime", + "Format":"yyyy/MM/dd", + "DBFieldName":"effDate" + }, + { + "Name":"库位", + "DBFieldName":"drawerNo" + }, + { + "Name":"colNo" + }, + { + "Name":"type2", + "Type":"Integer", + "DBFieldName":"type" + } + ] + }, + "Column":[ + { + "Name":"操作人", + "Width":2.38125 + }, + { + "Name":"时间", + "Width":3.78354 + }, + { + "Name":"药品名称", + "Width":4.63021 + }, + { + "Name":"数量", + "Width":1.98438 + }, + { + "Name":"批次", + "Width":2.61938 + }, + { + "Name":"效期", + "Width":2.38125 + }, + { + "Name":"库位", + "Width":2.59292 + } + ], + "ColumnContent":{ + "Height":1.00542, + "ColumnContentCell":[ + { + "Column":"操作人", + "TextAlign":"MiddleCenter", + "DataField":"操作人" + }, + { + "Column":"时间", + "TextAlign":"MiddleCenter", + "DataField":"时间" + }, + { + "Column":"药品名称", + "TextAlign":"MiddleCenter", + "DataField":"药品名称" + }, + { + "Column":"数量", + "TextAlign":"MiddleCenter", + "DataField":"数量" + }, + { + "Column":"批次", + "TextAlign":"MiddleCenter", + "DataField":"批次" + }, + { + "Column":"效期", + "TextAlign":"MiddleCenter", + "DataField":"效期" + }, + { + "Column":"库位", + "FreeCell":true, + "Control":[ + { + "Type":"FieldBox", + "Name":"FieldBox1", + "Left":9.60438, + "Top":-2.16958, + "Width":2.80458, + "Height":0.661458 + }, + { + "Type":"MemoBox", + "Name":"MemoBox1", + "Dock":"Fill", + "Center":"Both", + "TextAlign":"MiddleCenter", + "Text":"[#库位#] - [#colNo#]" + } + ] + } + ] + }, + "ColumnTitle":{ + "Height":1.40229, + "RepeatStyle":"OnPage", + "ColumnTitleCell":[ + { + "GroupTitle":false, + "Column":"操作人", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"操作人" + }, + { + "GroupTitle":false, + "Column":"时间", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"时间" + }, + { + "GroupTitle":false, + "Column":"药品名称", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"药品名称" + }, + { + "GroupTitle":false, + "Column":"数量", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"数量" + }, + { + "GroupTitle":false, + "Column":"批次", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"批次" + }, + { + "GroupTitle":false, + "Column":"效期", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"效期" + }, + { + "GroupTitle":false, + "Column":"库位", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"库位" + } + ] + } + }, + "Parameter":[ + { + "Name":"startDate", + "DataType":"DateTime", + "Format":"yyyy-MM-dd hh:mm:ss", + "Value":"2023/1/1" + }, + { + "Name":"endDate", + "DataType":"DateTime", + "Format":"yyyy-MM-dd hh:mm:ss", + "Value":"2023/4/28 23:59:59" + }, + { + "Name":"machine_id", + "Value":"DM1" + } + ], + "ReportHeader":[ + { + "Name":"ReportHeader1", + "Height":1.79917, + "Control":[ + { + "Type":"MemoBox", + "Name":"MemoBox2", + "Left":7.59354, + "Top":0.211667, + "Width":5.60917, + "Height":1.19063, + "Font":{ + "Name":"宋体", + "Size":217500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"入库记录" + } + ], + "RepeatOnPage":true + } + ] +} \ No newline at end of file diff --git a/MasaBlazorApp3/ReportTemp/machine_log_check.grf b/MasaBlazorApp3/ReportTemp/machine_log_check.grf new file mode 100644 index 0000000..95463f8 --- /dev/null +++ b/MasaBlazorApp3/ReportTemp/machine_log_check.grf @@ -0,0 +1,284 @@ +{ + "Version":"6.8.5.2", + "Font":{ + "Name":"宋体", + "Size":105000, + "Weight":400, + "Charset":134 + }, + "Printer":{ + "LeftMargin":0.3175, + "TopMargin":0.899583, + "RightMargin":0.396875 + }, + "DetailGrid":{ + "CenterView":true, + "AppendBlankRow":true, + "Recordset":{ + "ConnectionString":"MYSQL;\r\nDatabase=hkcdb;\r\nPassword=qq1223;\r\nPort=3307;\r\nServer=127.0.0.1;\r\nUser=root;", + "QuerySQL":"SELECT \r\n dmr.`drawer_no` AS drawerNo,\r\n dmr.`col_no` AS colNo,\r\n dmr.`type` AS `type`,\r\n dmr.`quantity` AS quantity,\r\n dmr.`manu_no` AS manuNo,\r\n dmr.`eff_date` AS effDate,\r\n dmr.`operation_time` AS operationTime,\r\n di.`drug_name` AS drugName,\r\n di.`drug_spec` AS drugSpec,\r\n di.`pack_unit` AS packUnit,\r\n di.`manufactory` AS manuFactory,\r\n di.`max_stock` AS baseQuantity,\r\n dmr.`drug_id` AS drugId,\r\n ul.`user_name` AS nickname\r\nFROM\r\n dm_machine_record dmr\r\nLEFT JOIN drug_info di ON di.`drug_id` = dmr.`drug_id`\r\nLEFT JOIN user_list ul ON ul.`id` = dmr.`Operator`\r\nWHERE dmr.`type` = 4 \r\n AND dmr.`machine_id` = :machine_id\r\n AND dmr.`operation_time` > :startDate\r\n AND dmr.`operation_time` < :endDate", + "Field":[ + { + "Name":"操作人", + "DBFieldName":"Nickname" + }, + { + "Name":"时间", + "Type":"DateTime", + "Format":"yyyy/MM/dd HH:mm:ss", + "DBFieldName":"operationTime" + }, + { + "Name":"药品名称", + "DBFieldName":"DrugName" + }, + { + "Name":"数量", + "DBFieldName":"quantity" + }, + { + "Name":"批次", + "DBFieldName":"manuNo" + }, + { + "Name":"效期", + "Type":"DateTime", + "Format":"yyyy/MM/dd", + "DBFieldName":"effDate" + }, + { + "Name":"库位", + "DBFieldName":"drawerNo" + }, + { + "Name":"colNo" + }, + { + "Name":"type2", + "Type":"Integer", + "DBFieldName":"type" + } + ] + }, + "Column":[ + { + "Name":"操作人", + "Width":2.38125 + }, + { + "Name":"时间", + "Width":3.78354 + }, + { + "Name":"药品名称", + "Width":4.63021 + }, + { + "Name":"数量", + "Width":1.98438 + }, + { + "Name":"批次", + "Width":2.61938 + }, + { + "Name":"效期", + "Width":2.38125 + }, + { + "Name":"库位", + "Width":2.59292 + } + ], + "ColumnContent":{ + "Height":1.00542, + "ColumnContentCell":[ + { + "Column":"操作人", + "TextAlign":"MiddleCenter", + "DataField":"操作人" + }, + { + "Column":"时间", + "TextAlign":"MiddleCenter", + "DataField":"时间" + }, + { + "Column":"药品名称", + "TextAlign":"MiddleCenter", + "DataField":"药品名称" + }, + { + "Column":"数量", + "TextAlign":"MiddleCenter", + "DataField":"数量" + }, + { + "Column":"批次", + "TextAlign":"MiddleCenter", + "DataField":"批次" + }, + { + "Column":"效期", + "TextAlign":"MiddleCenter", + "DataField":"效期" + }, + { + "Column":"库位", + "FreeCell":true, + "Control":[ + { + "Type":"FieldBox", + "Name":"FieldBox1", + "Left":9.60438, + "Top":-2.16958, + "Width":2.80458, + "Height":0.661458 + }, + { + "Type":"MemoBox", + "Name":"MemoBox1", + "Dock":"Fill", + "Center":"Both", + "TextAlign":"MiddleCenter", + "Text":"[#库位#] - [#colNo#]" + } + ] + } + ] + }, + "ColumnTitle":{ + "Height":1.40229, + "RepeatStyle":"OnPage", + "ColumnTitleCell":[ + { + "GroupTitle":false, + "Column":"操作人", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"操作人" + }, + { + "GroupTitle":false, + "Column":"时间", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"时间" + }, + { + "GroupTitle":false, + "Column":"药品名称", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"药品名称" + }, + { + "GroupTitle":false, + "Column":"数量", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"数量" + }, + { + "GroupTitle":false, + "Column":"批次", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"批次" + }, + { + "GroupTitle":false, + "Column":"效期", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"效期" + }, + { + "GroupTitle":false, + "Column":"库位", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"库位" + } + ] + } + }, + "Parameter":[ + { + "Name":"startDate", + "DataType":"DateTime", + "Format":"yyyy-MM-dd hh:mm:ss", + "Value":"2023/1/1" + }, + { + "Name":"endDate", + "DataType":"DateTime", + "Format":"yyyy-MM-dd hh:mm:ss", + "Value":"2023/4/28 23:59:59" + }, + { + "Name":"machine_id", + "Value":"DM1" + } + ], + "ReportHeader":[ + { + "Name":"ReportHeader1", + "Height":1.79917, + "Control":[ + { + "Type":"MemoBox", + "Name":"MemoBox2", + "Left":7.59354, + "Top":0.211667, + "Width":5.60917, + "Height":1.19063, + "Font":{ + "Name":"宋体", + "Size":217500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"盘点记录" + } + ], + "RepeatOnPage":true + } + ] +} \ No newline at end of file diff --git a/MasaBlazorApp3/ReportTemp/machine_log_return.grf b/MasaBlazorApp3/ReportTemp/machine_log_return.grf new file mode 100644 index 0000000..106b501 --- /dev/null +++ b/MasaBlazorApp3/ReportTemp/machine_log_return.grf @@ -0,0 +1,284 @@ +{ + "Version":"6.8.5.2", + "Font":{ + "Name":"宋体", + "Size":105000, + "Weight":400, + "Charset":134 + }, + "Printer":{ + "LeftMargin":0.3175, + "TopMargin":0.899583, + "RightMargin":0.396875 + }, + "DetailGrid":{ + "CenterView":true, + "AppendBlankRow":true, + "Recordset":{ + "ConnectionString":"MYSQL;\r\nDatabase=hkcdb;\r\nPassword=qq1223;\r\nPort=3307;\r\nServer=127.0.0.1;\r\nUser=root;", + "QuerySQL":"SELECT \r\n dmr.`drawer_no` AS drawerNo,\r\n dmr.`col_no` AS colNo,\r\n dmr.`type` AS `type`,\r\n CONCAT(dmr.`quantity`,IF(dmr.`type`=32,\"(空瓶)\",\"\")) AS quantity,\r\n dmr.`manu_no` AS manuNo,\r\n dmr.`eff_date` AS effDate,\r\n dmr.`operation_time` AS operationTime,\r\n di.`drug_name` AS drugName,\r\n di.`drug_spec` AS drugSpec,\r\n di.`pack_unit` AS packUnit,\r\n di.`manufactory` AS manuFactory,\r\n di.`max_stock` AS baseQuantity,\r\n dmr.`drug_id` AS drugId,\r\n ul.`user_name` AS nickname\r\nFROM\r\n dm_machine_record dmr\r\nLEFT JOIN drug_info di ON di.`drug_id` = dmr.`drug_id`\r\nLEFT JOIN user_list ul ON ul.`id` = dmr.`Operator`\r\nWHERE dmr.`type` in (31, 32)\r\n AND dmr.`machine_id` = :machine_id\r\n AND dmr.`operation_time` > :startDate\r\n AND dmr.`operation_time` < :endDate", + "Field":[ + { + "Name":"操作人", + "DBFieldName":"Nickname" + }, + { + "Name":"时间", + "Type":"DateTime", + "Format":"yyyy/MM/dd HH:mm:ss", + "DBFieldName":"operationTime" + }, + { + "Name":"药品名称", + "DBFieldName":"DrugName" + }, + { + "Name":"数量", + "DBFieldName":"quantity" + }, + { + "Name":"批次", + "DBFieldName":"manuNo" + }, + { + "Name":"效期", + "Type":"DateTime", + "Format":"yyyy/MM/dd", + "DBFieldName":"effDate" + }, + { + "Name":"库位", + "DBFieldName":"drawerNo" + }, + { + "Name":"colNo" + }, + { + "Name":"type2", + "Type":"Integer", + "DBFieldName":"type" + } + ] + }, + "Column":[ + { + "Name":"操作人", + "Width":2.38125 + }, + { + "Name":"时间", + "Width":3.78354 + }, + { + "Name":"药品名称", + "Width":4.63021 + }, + { + "Name":"数量", + "Width":1.98438 + }, + { + "Name":"批次", + "Width":2.61938 + }, + { + "Name":"效期", + "Width":2.38125 + }, + { + "Name":"库位", + "Width":2.59292 + } + ], + "ColumnContent":{ + "Height":1.00542, + "ColumnContentCell":[ + { + "Column":"操作人", + "TextAlign":"MiddleCenter", + "DataField":"操作人" + }, + { + "Column":"时间", + "TextAlign":"MiddleCenter", + "DataField":"时间" + }, + { + "Column":"药品名称", + "TextAlign":"MiddleCenter", + "DataField":"药品名称" + }, + { + "Column":"数量", + "TextAlign":"MiddleCenter", + "DataField":"数量" + }, + { + "Column":"批次", + "TextAlign":"MiddleCenter", + "DataField":"批次" + }, + { + "Column":"效期", + "TextAlign":"MiddleCenter", + "DataField":"效期" + }, + { + "Column":"库位", + "FreeCell":true, + "Control":[ + { + "Type":"FieldBox", + "Name":"FieldBox1", + "Left":9.60438, + "Top":-2.16958, + "Width":2.80458, + "Height":0.661458 + }, + { + "Type":"MemoBox", + "Name":"MemoBox1", + "Dock":"Fill", + "Center":"Both", + "TextAlign":"MiddleCenter", + "Text":"[#库位#] - [#colNo#]" + } + ] + } + ] + }, + "ColumnTitle":{ + "Height":1.40229, + "RepeatStyle":"OnPage", + "ColumnTitleCell":[ + { + "GroupTitle":false, + "Column":"操作人", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"操作人" + }, + { + "GroupTitle":false, + "Column":"时间", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"时间" + }, + { + "GroupTitle":false, + "Column":"药品名称", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"药品名称" + }, + { + "GroupTitle":false, + "Column":"数量", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"数量" + }, + { + "GroupTitle":false, + "Column":"批次", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"批次" + }, + { + "GroupTitle":false, + "Column":"效期", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"效期" + }, + { + "GroupTitle":false, + "Column":"库位", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"库位" + } + ] + } + }, + "Parameter":[ + { + "Name":"startDate", + "DataType":"DateTime", + "Format":"yyyy-MM-dd hh:mm:ss", + "Value":"2023/1/1" + }, + { + "Name":"endDate", + "DataType":"DateTime", + "Format":"yyyy-MM-dd hh:mm:ss", + "Value":"2023/4/28 23:59:59" + }, + { + "Name":"machine_id", + "Value":"DM1" + } + ], + "ReportHeader":[ + { + "Name":"ReportHeader1", + "Height":1.79917, + "Control":[ + { + "Type":"MemoBox", + "Name":"MemoBox2", + "Left":7.59354, + "Top":0.211667, + "Width":5.60917, + "Height":1.19063, + "Font":{ + "Name":"宋体", + "Size":217500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"归还记录" + } + ], + "RepeatOnPage":true + } + ] +} \ No newline at end of file diff --git a/MasaBlazorApp3/ReportTemp/machine_log_take.grf b/MasaBlazorApp3/ReportTemp/machine_log_take.grf new file mode 100644 index 0000000..c17fb9f --- /dev/null +++ b/MasaBlazorApp3/ReportTemp/machine_log_take.grf @@ -0,0 +1,284 @@ +{ + "Version":"6.8.5.2", + "Font":{ + "Name":"宋体", + "Size":105000, + "Weight":400, + "Charset":134 + }, + "Printer":{ + "LeftMargin":0.3175, + "TopMargin":0.899583, + "RightMargin":0.396875 + }, + "DetailGrid":{ + "CenterView":true, + "AppendBlankRow":true, + "Recordset":{ + "ConnectionString":"MYSQL;\r\nDatabase=hkcdb;\r\nPassword=qq1223;\r\nPort=3307;\r\nServer=127.0.0.1;\r\nUser=root;", + "QuerySQL":"SELECT \r\n dmr.`drawer_no` AS drawerNo,\r\n dmr.`col_no` AS colNo,\r\n dmr.`type` AS `type`,\r\n dmr.`quantity` AS quantity,\r\n dmr.`manu_no` AS manuNo,\r\n dmr.`eff_date` AS effDate,\r\n dmr.`operation_time` AS operationTime,\r\n di.`drug_name` AS drugName,\r\n di.`drug_spec` AS drugSpec,\r\n di.`pack_unit` AS packUnit,\r\n di.`manufactory` AS manuFactory,\r\n di.`max_stock` AS baseQuantity,\r\n dmr.`drug_id` AS drugId,\r\n ul.`user_name` AS nickname\r\nFROM\r\n dm_machine_record dmr\r\nLEFT JOIN drug_info di ON di.`drug_id` = dmr.`drug_id`\r\nLEFT JOIN user_list ul ON ul.`id` = dmr.`Operator`\r\nWHERE dmr.`type` = 2 \r\n AND dmr.`machine_id` = :machine_id\r\n AND dmr.`operation_time` > :startDate\r\n AND dmr.`operation_time` < :endDate", + "Field":[ + { + "Name":"操作人", + "DBFieldName":"Nickname" + }, + { + "Name":"时间", + "Type":"DateTime", + "Format":"yyyy/MM/dd HH:mm:ss", + "DBFieldName":"operationTime" + }, + { + "Name":"药品名称", + "DBFieldName":"DrugName" + }, + { + "Name":"数量", + "DBFieldName":"quantity" + }, + { + "Name":"批次", + "DBFieldName":"manuNo" + }, + { + "Name":"效期", + "Type":"DateTime", + "Format":"yyyy/MM/dd", + "DBFieldName":"effDate" + }, + { + "Name":"库位", + "DBFieldName":"drawerNo" + }, + { + "Name":"colNo" + }, + { + "Name":"type2", + "Type":"Integer", + "DBFieldName":"type" + } + ] + }, + "Column":[ + { + "Name":"操作人", + "Width":2.38125 + }, + { + "Name":"时间", + "Width":3.78354 + }, + { + "Name":"药品名称", + "Width":4.63021 + }, + { + "Name":"数量", + "Width":1.98438 + }, + { + "Name":"批次", + "Width":2.61938 + }, + { + "Name":"效期", + "Width":2.38125 + }, + { + "Name":"库位", + "Width":2.59292 + } + ], + "ColumnContent":{ + "Height":1.00542, + "ColumnContentCell":[ + { + "Column":"操作人", + "TextAlign":"MiddleCenter", + "DataField":"操作人" + }, + { + "Column":"时间", + "TextAlign":"MiddleCenter", + "DataField":"时间" + }, + { + "Column":"药品名称", + "TextAlign":"MiddleCenter", + "DataField":"药品名称" + }, + { + "Column":"数量", + "TextAlign":"MiddleCenter", + "DataField":"数量" + }, + { + "Column":"批次", + "TextAlign":"MiddleCenter", + "DataField":"批次" + }, + { + "Column":"效期", + "TextAlign":"MiddleCenter", + "DataField":"效期" + }, + { + "Column":"库位", + "FreeCell":true, + "Control":[ + { + "Type":"FieldBox", + "Name":"FieldBox1", + "Left":9.60438, + "Top":-2.16958, + "Width":2.80458, + "Height":0.661458 + }, + { + "Type":"MemoBox", + "Name":"MemoBox1", + "Dock":"Fill", + "Center":"Both", + "TextAlign":"MiddleCenter", + "Text":"[#库位#] - [#colNo#]" + } + ] + } + ] + }, + "ColumnTitle":{ + "Height":1.40229, + "RepeatStyle":"OnPage", + "ColumnTitleCell":[ + { + "GroupTitle":false, + "Column":"操作人", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"操作人" + }, + { + "GroupTitle":false, + "Column":"时间", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"时间" + }, + { + "GroupTitle":false, + "Column":"药品名称", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"药品名称" + }, + { + "GroupTitle":false, + "Column":"数量", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"数量" + }, + { + "GroupTitle":false, + "Column":"批次", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"批次" + }, + { + "GroupTitle":false, + "Column":"效期", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"效期" + }, + { + "GroupTitle":false, + "Column":"库位", + "Font":{ + "Name":"宋体", + "Size":120000, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"库位" + } + ] + } + }, + "Parameter":[ + { + "Name":"startDate", + "DataType":"DateTime", + "Format":"yyyy-MM-dd hh:mm:ss", + "Value":"2023/1/1" + }, + { + "Name":"endDate", + "DataType":"DateTime", + "Format":"yyyy-MM-dd hh:mm:ss", + "Value":"2023/4/28 23:59:59" + }, + { + "Name":"machine_id", + "Value":"DM1" + } + ], + "ReportHeader":[ + { + "Name":"ReportHeader1", + "Height":1.79917, + "Control":[ + { + "Type":"MemoBox", + "Name":"MemoBox2", + "Left":7.59354, + "Top":0.211667, + "Width":5.60917, + "Height":1.19063, + "Font":{ + "Name":"宋体", + "Size":217500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"出库记录" + } + ], + "RepeatOnPage":true + } + ] +} \ No newline at end of file diff --git a/MasaBlazorApp3/ReportTemp/stock_template.grf b/MasaBlazorApp3/ReportTemp/stock_template.grf new file mode 100644 index 0000000..f580f28 --- /dev/null +++ b/MasaBlazorApp3/ReportTemp/stock_template.grf @@ -0,0 +1,348 @@ +{ + "Version":"6.8.5.2", + "Font":{ + "Name":"宋体", + "Size":105000, + "Weight":400, + "Charset":134 + }, + "Printer":{ + "Oriention":"Landscape" + }, + "DetailGrid":{ + "CenterView":true, + "PrintAdaptMethod":"ResizeToFit", + "AppendBlankRow":true, + "Recordset":{ + "ConnectionString":"MYSQL;\r\nDatabase=hkcdb;\r\nPassword=qq1223;\r\nPort=3307;\r\nServer=127.0.0.1;\r\nUser=root;", + "QuerySQL":"SELECT \r\n cl.`row_no` AS drawerNo,\r\n cl.`col_no` AS colNo,\r\n cl.`quantity` AS quantity,\r\n cl.`manu_no` AS manuNo,\r\n cl.`eff_date` AS effDate,\r\n di.`drug_name` AS drugName,\r\n di.`drug_spec` AS drugSpec,\r\n di.`pack_unit` AS packUnit,\r\n di.`manufactory` AS manuFactory,\r\n di.`max_stock` AS baseQuantity,\r\n cl.`drug_id` AS drugId\r\nFROM\r\n channel_stock cl\r\nINNER JOIN drug_info di ON di.`drug_id` = cl.`drug_id`\r\nWHERE cl.`machine_id` = :machine_id\r\n AND cl.`drawer_type` = 1\r\n ORDER BY cl.`drug_id`", + "Field":[ + { + "Name":"drugName" + }, + { + "Name":"drugSpec" + }, + { + "Name":"manuFactory" + }, + { + "Name":"quantityCount" + }, + { + "Name":"manuNo" + }, + { + "Name":"effDate" + }, + { + "Name":"quantity", + "Type":"Integer", + "Format":"0" + }, + { + "Name":"drawerNo" + }, + { + "Name":"drugId" + }, + { + "Name":"baseQuantity", + "Type":"Integer" + } + ] + }, + "Column":[ + { + "Name":"drugName", + "Width":5.37104 + }, + { + "Name":"drugSpec" + }, + { + "Name":"manuFactory", + "Width":4.60375 + }, + { + "Name":"Column1" + }, + { + "Name":"quantityCount", + "Width":2.59292 + }, + { + "Name":"manuNo" + }, + { + "Name":"effDate" + }, + { + "Name":"quantity", + "Width":2.43417 + } + ], + "ColumnContent":{ + "Height":0.79375, + "ColumnContentCell":[ + { + "Column":"drugName", + "TextAlign":"MiddleCenter", + "DataField":"drugName" + }, + { + "Column":"drugSpec", + "TextAlign":"MiddleCenter", + "DataField":"drugSpec" + }, + { + "Column":"manuFactory", + "TextAlign":"MiddleCenter", + "DataField":"manuFactory" + }, + { + "Column":"Column1", + "FreeCell":true + }, + { + "Column":"quantityCount", + "FreeCell":true + }, + { + "Column":"manuNo", + "TextAlign":"MiddleCenter", + "DataField":"manuNo" + }, + { + "Column":"effDate", + "TextAlign":"MiddleCenter", + "DataField":"effDate" + }, + { + "Column":"quantity", + "TextAlign":"MiddleCenter", + "DataField":"quantity" + } + ] + }, + "ColumnTitle":{ + "Height":1.19063, + "RepeatStyle":"OnPage", + "BeforeHeaders":true, + "ColumnTitleCell":[ + { + "GroupTitle":false, + "Column":"drugName", + "Font":{ + "Name":"宋体", + "Size":142500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"药品名称" + }, + { + "GroupTitle":false, + "Column":"drugSpec", + "Font":{ + "Name":"宋体", + "Size":142500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"规格" + }, + { + "GroupTitle":false, + "Column":"manuFactory", + "Font":{ + "Name":"宋体", + "Size":142500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"厂家" + }, + { + "GroupTitle":false, + "Column":"Column1", + "Font":{ + "Name":"宋体", + "Size":142500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"基数" + }, + { + "GroupTitle":false, + "Column":"quantityCount", + "Font":{ + "Name":"宋体", + "Size":142500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"总库存" + }, + { + "GroupTitle":false, + "Column":"manuNo", + "Font":{ + "Name":"宋体", + "Size":142500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"批次" + }, + { + "GroupTitle":false, + "Column":"effDate", + "Font":{ + "Name":"宋体", + "Size":142500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"效期" + }, + { + "GroupTitle":false, + "Column":"quantity", + "Font":{ + "Name":"宋体", + "Size":142500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"数量" + } + ] + }, + "Group":[ + { + "Name":"drugId", + "ByFields":"drugId", + "GroupHeader":{ + "Visible":false, + "Height":0.79375, + "RepeatOnPage":true, + "OccupyColumn":true, + "IncludeFooter":true, + "OccupiedColumns":"drugName;drugSpec;manuFactory;quantityCount;Column1", + "VAlign":"Middle" + }, + "GroupFooter":{ + "Visible":false, + "Height":0.396875 + } + }, + { + "Name":"Group1", + "ByFields":"drugId", + "GroupHeader":{ + "Control":[ + { + "Type":"MemoBox", + "Name":"MemoBox3", + "AlignColumn":"drugName", + "Width":5.34458, + "Height":1.19063, + "TextAlign":"MiddleCenter", + "Text":"[#drugName#]" + }, + { + "Type":"MemoBox", + "Name":"MemoBox4", + "AlignColumn":"drugSpec", + "Left":5.37104, + "Width":2.96333, + "Height":1.19063, + "TextAlign":"MiddleCenter", + "Text":"[#drugSpec#]" + }, + { + "Type":"MemoBox", + "Name":"MemoBox5", + "AlignColumn":"manuFactory", + "Left":8.36083, + "Width":4.57729, + "Height":1.19063, + "TextAlign":"MiddleCenter", + "Text":"[#manuFactory#]" + }, + { + "Type":"MemoBox", + "Name":"MemoBox6", + "AlignColumn":"Column1", + "Left":12.9646, + "Width":2.96333, + "Height":1.19063, + "TextAlign":"MiddleCenter", + "Text":"[#baseQuantity#]" + }, + { + "Type":"SummaryBox", + "Name":"SummaryBox1", + "AlignColumn":"quantityCount", + "Left":15.9544, + "Width":2.56646, + "Height":1.19063, + "TextAlign":"MiddleCenter", + "DataField":"quantity", + "Format":"0" + } + ], + "OccupyColumn":true, + "SameAsColumn":false, + "OccupiedColumns":"Column1;drugName;drugSpec;manuFactory;quantityCount", + "VAlign":"Middle" + }, + "GroupFooter":{ + "Visible":false + } + } + ] + }, + "Parameter":[ + { + "Name":"machine_id", + "Value":"DM1" + } + ], + "ReportHeader":[ + { + "Name":"ReportHeader1", + "Height":2.40771, + "Control":[ + { + "Type":"StaticBox", + "Name":"StaticBox1", + "Center":"Horizontal", + "Left":7.77875, + "Top":0.608542, + "Width":9.18104, + "Height":1.21708, + "Font":{ + "Name":"宋体", + "Size":217500, + "Bold":true, + "Charset":134 + }, + "TextAlign":"MiddleCenter", + "Text":"毒麻药品库存信息" + } + ], + "RepeatOnPage":true + } + ] +} \ No newline at end of file diff --git a/MasaBlazorApp3/Shared/EmptyLayout.razor b/MasaBlazorApp3/Shared/EmptyLayout.razor new file mode 100644 index 0000000..13157f2 --- /dev/null +++ b/MasaBlazorApp3/Shared/EmptyLayout.razor @@ -0,0 +1,6 @@ +@inherits LayoutComponentBase + +
+ @Body +
+ \ No newline at end of file diff --git a/MasaBlazorApp3/Shared/MainLayout.razor b/MasaBlazorApp3/Shared/MainLayout.razor new file mode 100644 index 0000000..2a89746 --- /dev/null +++ b/MasaBlazorApp3/Shared/MainLayout.razor @@ -0,0 +1,154 @@ +@namespace MasaBlazorApp3 +@using MasaBlazorApp3.Pojo.Config +@using MasaBlazorApp3.Util +@using log4net +@inherits LayoutComponentBase + + + + + + + + + + + + + + @foreach (Premission p in children) + { + if (childrenIds.Any(id => id == p.Id)) + { + @p.PremissionName + } + } + + + + + @* 退出 *@ + + + + + + +
+ + @Body + +
+
+ + +
+ +@code +{ + @inject GlobalStateService globalStateService; + @inject NavigationManager na; + int selectedIndex = 0; + Pojo.User Operator; + List childrenIds; + List children; + @inject Microsoft.Extensions.Options.IOptions setting; + @inject PortUtil _portUtil; + private readonly ILog logger = LogManager.GetLogger(typeof(MainLayout)); + bool currentPage = true; + + protected override void OnInitialized() + { + string Uri = na.Uri; + string[] s = Uri.Split("/"); + + Operator = globalStateService.Operator; + Premission parent = new Premission().getAdminPremission().Find(p => p.PremissionPath == s[3]); + childrenIds = Operator.role.permissionIds.Where(id => id - (parent .Id* 10) < 10).ToList(); + children = parent.Items.ToList(); + + if(setting.Value.autoOutLog>0) + { + // 是否需要自动退出 + var promiseUtil = new PromiseUtil(); + promiseUtil.taskAsyncLoop(500, null, async (data, next, stop) => + { + if (globalStateService.Operator == null||!currentPage) + { + + logger.Info($"MainLayout页自动退出循环停止{globalStateService.Operator==null},{!currentPage}"); + stop(); + } + else + { + try + { + //没有在操作抽屉 + if(!_portUtil.Operate) + { + // 无人操作鼠标键盘 + if((DateTime.Now - _portUtil.dateTime).TotalSeconds > setting.Value.autoOutLog && CheckComputerFreeState.GetLastInputTime() > setting.Value.autoOutLog) + { + logger.Info($"设备{setting.Value.autoOutLog}内无人操作,用户【{Operator?.NickName}】自动退出登录,_portUtil.Operate:{_portUtil.Operate},totalSecond:{(DateTime.Now - _portUtil.dateTime).TotalSeconds},lastInputTime:{CheckComputerFreeState.GetLastInputTime()},autoOutLog:{setting.Value.autoOutLog}"); + globalStateService.Operator = null; + globalStateService.Reviewer = null; + na.NavigateTo(""); + stop(); + } + else + { + next(); + } + } + else + { + next(); + } + } + catch (Exception ex) + { + logger.Info($"检查是否自动退出循环异常:{ex.Message}"); + next(); + } + } + }); + } + + base.OnInitialized(); + } + + + + void backHome() + { + currentPage = false; + na.NavigateTo("/home"); + } + + void logout() + { + globalStateService.Operator = null; + globalStateService.Reviewer = null; + na.NavigateTo(""); + } +} + +@code +{ +} \ No newline at end of file diff --git a/MasaBlazorApp3/Util/CheckComputerFreeState.cs b/MasaBlazorApp3/Util/CheckComputerFreeState.cs new file mode 100644 index 0000000..13d7bc0 --- /dev/null +++ b/MasaBlazorApp3/Util/CheckComputerFreeState.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace MasaBlazorApp3.Util +{ + public class CheckComputerFreeState + { + /// + /// 创建结构体用于返回捕获时间 + /// + [StructLayout(LayoutKind.Sequential)] + struct LASTINPUTINFO + { + /// + /// 设置结构体块容量 + /// + [MarshalAs(UnmanagedType.U4)] + public int cbSize; + + /// + /// 抓获的时间 + /// + [MarshalAs(UnmanagedType.U4)] + public uint dwTime; + } + + [DllImport("user32.dll")] + private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); + /// + /// 获取键盘和鼠标没有操作的时间 + /// + /// 用户上次使用系统到现在的时间间隔,单位为秒 + public static long GetLastInputTime() + { + LASTINPUTINFO vLastInputInfo = new LASTINPUTINFO(); + vLastInputInfo.cbSize = Marshal.SizeOf(vLastInputInfo); + if (!GetLastInputInfo(ref vLastInputInfo)) + { + return 0; + } + else + { + var count = (Environment.TickCount & Int32.MaxValue) - (long)vLastInputInfo.dwTime; + var icount = count / 1000; + return icount; + } + } + } +} diff --git a/MasaBlazorApp3/Util/MD5.cs b/MasaBlazorApp3/Util/MD5.cs new file mode 100644 index 0000000..272f5ff --- /dev/null +++ b/MasaBlazorApp3/Util/MD5.cs @@ -0,0 +1,30 @@ +using System.Text; +using System.Security.Cryptography; + +namespace MasaBlazorApp3.Util +{ + public class MD5 + { + public static string GetMD5Hash(string password) + { + //就是比string往后一直加要好的优化容器 + StringBuilder sb = new StringBuilder(); + using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) + { + //将输入字符串转换为字节数组并计算哈希。 + byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(password)); + + //X为 十六进制 X都是大写 x都为小写 + //2为 每次都是两位数 + //假设有两个数10和26,正常情况十六进制显示0xA、0x1A,这样看起来不整齐,为了好看,可以指定"X2",这样显示出来就是:0x0A、0x1A。 + //遍历哈希数据的每个字节 + //并将每个字符串格式化为十六进制字符串。 + int length = data.Length; + for (int i = 0; i < length; i++) + sb.Append(data[i].ToString("x2")); + + } + return sb.ToString(); + } + } +} diff --git a/MasaBlazorApp3/Util/PromiseUtil.cs b/MasaBlazorApp3/Util/PromiseUtil.cs new file mode 100644 index 0000000..26e7779 --- /dev/null +++ b/MasaBlazorApp3/Util/PromiseUtil.cs @@ -0,0 +1,44 @@ +using SharpPromise; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static LinqToDB.Reflection.Methods.LinqToDB.Insert; + +namespace MasaBlazorApp3.Util +{ + public class PromiseUtil + { + + public int _delay { get; set; } + + public T? _data { get; set; } + + public async Task taskAsyncLoop(int delay, T data, Action, Action, Action> action) + { + _data = data; + _delay = 0; + while (_delay >= 0) + { + await new Promise(async (Action onResolve, Action onReject) => + { + await Task.Delay(_delay); + try + { + await Task.Run(() => action(this, onResolve, onReject)); + } catch (Exception ex) + { + onReject(); + } + }).Then(() => + { + _delay = delay; + }).Catch((Exception e) => + { + _delay = -1; + }); + } + } + } +} diff --git a/MasaBlazorApp3/Util/VirtualKeyboardHelper.cs b/MasaBlazorApp3/Util/VirtualKeyboardHelper.cs new file mode 100644 index 0000000..4e564a2 --- /dev/null +++ b/MasaBlazorApp3/Util/VirtualKeyboardHelper.cs @@ -0,0 +1,342 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Management; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; +namespace MasaBlazorApp3.Util +{ + public class VirtualKeyboardHelper + { + private const uint WS_VISIBLE = 0x10000000; + private const int GWL_STYLE = -16; + private const int WM_SYSCOMMAND = 0x0112; + private const uint SC_CLOSE = 0xF060; + private const int WS_DISABLED = 0x08000000; + private const int DWMWA_CLOAKED = 14; + + private const string ApplicationFrameHostClassName = "ApplicationFrameWindow"; + private const string CoreWindowClassName = "Windows.UI.Core.CoreWindow"; + + private const string TextInputApplicationCaption = "Microsoft Text Input Application"; + + + /// + /// win10 虚拟键盘路径 + /// + private const string Win10TabTipPath = @"C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe"; + + /// + /// win7 虚拟键盘路径 + /// + private const string Win7OskPath = @"C:\WINDOWS\system32\osk.exe"; + + /// + /// 虚拟键盘 窗口名称 + /// + private const string TabTipWindowClassName = "IPTIP_Main_Window"; + + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + + [DllImport("user32.dll", EntryPoint = "FindWindowEx")] + private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, + string lpszWindow); + + + [DllImport("user32.dll", EntryPoint = "GetWindowLong")] + private static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + private static extern bool PostMessage(IntPtr hWnd, int msg, uint wParam, uint lParam); + + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr); + + + [DllImport("user32.dll", EntryPoint = "GetDesktopWindow", SetLastError = false)] + private static extern IntPtr GetDesktopWindow(); + + [DllImport("dwmapi.dll", EntryPoint = "DwmGetWindowAttribute")] + private static extern int DwmGetWindowAttribute(IntPtr intPtr, int dwAttribute, out int pvAttribute, + uint cbAttribute); + + + + /// + /// 判断键盘是否连接 + /// + /// + public static bool IsKeyboardAttached() + { + try + { + ManagementObjectSearcher searcher = + new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Keyboard"); + + int devCount = 0; + + foreach (ManagementObject obj in searcher.Get()) + { + if (obj["Status"].ToString().Contains("OK")) // if device is ready + { + //surface测试时发现,HID设备,不是键盘,比较特殊 + if (!obj["Description"].ToString().Contains("HID Keyboard Device")) + { + devCount++; + } + } + } + + return devCount > 0; + } + catch (Exception) + { + return false; + } + } + + /// + /// 打开虚拟键盘,目前支持win7 64位,win10 64位,exe编译为x86。 + /// + public static void ShowVirtualKeyboard() + { + //+------------------------------------------------------------------------------+ + //| | PlatformID | Major version | Minor version | + //+------------------------------------------------------------------------------+ + //| Windows 95 | Win32Windows | 4 | 0 | + //| Windows 98 | Win32Windows | 4 | 10 | + //| Windows Me | Win32Windows | 4 | 90 | + //| Windows NT 4.0 | Win32NT | 4 | 0 | + //| Windows 2000 | Win32NT | 5 | 0 | + //| Windows XP | Win32NT | 5 | 1 | + //| Windows 2003 | Win32NT | 5 | 2 | + //| Windows Vista | Win32NT | 6 | 0 | + //| Windows 2008 | Win32NT | 6 | 0 | + //| Windows 7 | Win32NT | 6 | 1 | + //| Windows 2008 R2 | Win32NT | 6 | 1 | + //| Windows 8 | Win32NT | 6 | 2 | + //| Windows 8.1 | Win32NT | 6 | 3 | + //+------------------------------------------------------------------------------+ + //| Windows 10 | Win32NT | 10 | 0 | + + try + { + var isWin7 = Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1; + var isWin8OrWin10 = + Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 2; + var isWin10 = Environment.OSVersion.Version.Major == 10 && Environment.OSVersion.Version.Minor == 0; + if (isWin7) + { + //win7 + ShowWin7VirtualKeyboard(); + } + else if (isWin8OrWin10 || isWin10) + { + //win10 + ShowWin10VirtualKeyboard(); + } + } + catch (Exception) + { + // ignored + } + } + /// + /// 关闭虚拟键盘 + /// + public void CloseVirtualKeyboard() + { + var touchhWnd = FindWindow("IPTip_Main_Window", null); + if (touchhWnd == IntPtr.Zero) + { + return; + } + + PostMessage(touchhWnd, WM_SYSCOMMAND, SC_CLOSE, 0); + } + private static void ShowWin7VirtualKeyboard() + { + if (!Environment.Is64BitProcess && Environment.Is64BitOperatingSystem) + { + //32位程序 运行在64位系统上,打开32位程序,需要禁用文件重定向 + var ptr = new IntPtr(); + var isWow64FsRedirectionDisabled = Wow64DisableWow64FsRedirection(ref ptr); + + Process.Start(Win7OskPath); + + if (isWow64FsRedirectionDisabled) + { + Wow64RevertWow64FsRedirection(ptr); + } + } + else if (Environment.Is64BitProcess && Environment.Is64BitOperatingSystem) + { + Process.Start(Win7OskPath); + } + } + + private static void ShowWin10VirtualKeyboard() + { + if (!IsTabTipProcessPresent()) + { + + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.FileName = Win10TabTipPath; + startInfo.UseShellExecute = true; + startInfo.Verb = "runas"; + Process.Start(startInfo); + while (!IsValidHandle(FindWindow("IPTIP_Main_Window", ""))) + { + Thread.Sleep(100); + } + } + + //判断可见性 + if (!IsWin10OnScreenKeyboardVisible()) + { + ShowByCom(); + } + } + + private static bool IsWin10OnScreenKeyboardVisible() + { + var handle = FindWindow(TabTipWindowClassName, ""); + if (!IsValidHandle(handle)) + { + return false; + } + + var isVisible = IsWindowVisibleByHandle(handle); + if (isVisible.HasValue) + { + return isVisible.Value; + } + + // hard way + var textInputHandle = FindTextInputWindow(); + return IsValidHandle(textInputHandle); + } + + private static IntPtr FindTextInputWindow() + { + var lastProbed = IntPtr.Zero; + do + { + lastProbed = FindWindowEx(IntPtr.Zero, lastProbed, ApplicationFrameHostClassName, null); + if (IsValidHandle(lastProbed)) + { + var textInput = FindWindowEx(lastProbed, IntPtr.Zero, CoreWindowClassName, + TextInputApplicationCaption); + return textInput; + } + } while (IsValidHandle(lastProbed)); + + return IntPtr.Zero; + } + + + + private static bool? IsWindowVisibleByHandle(IntPtr handle) + { + var style = GetWindowLong(handle, GWL_STYLE); + //Console.WriteLine( "Style {0:X8}", style ); + + // if is disabled - not visible + if ((style & WS_DISABLED) != 0) + { + return false; + } + + // if has visible style - visible :) + if ((style & WS_VISIBLE) != 0) + { + return true; + } + + // DWM Window can be cloaked + // see https://social.msdn.microsoft.com/Forums/vstudio/en-US/f8341376-6015-4796-8273-31e0be91da62/difference-between-actually-visible-and-not-visiblewhich-are-there-but-we-cant-see-windows-of?forum=vcgeneral + if (DwmGetWindowAttribute(handle, DWMWA_CLOAKED, out var cloaked, 4) == 0) + { + if (cloaked != 0) + { + return false; + } + } + + // undefined + return null; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsValidHandle(IntPtr handle) + { + // if (?:) will be eliminated by jit + return IntPtr.Size == 4 + ? handle.ToInt32() > 0 + : handle.ToInt64() > 0; + } + + private static bool IsTabTipProcessPresent() + { + var handle = FindWindow(TabTipWindowClassName, ""); + return IntPtr.Size == 4 + ? handle.ToInt32() > 0 + : handle.ToInt64() > 0; + } + + private static void ShowByCom() + { + ITipInvocation instance = null; + try + { + instance = (ITipInvocation)Activator.CreateInstance(ComTypes.TipInvocationType); + instance.Toggle(GetDesktopWindow()); + } + finally + { + if (!ReferenceEquals(instance, null)) + { + Marshal.ReleaseComObject(instance); + } + } + } + } + + [ComImport] + [Guid("37c994e7-432b-4834-a2f7-dce1f13b834b")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface ITipInvocation + { + void Toggle(IntPtr hwnd); + } + + internal static class ComTypes + { + internal static readonly Guid ImmersiveShellBrokerGuid; + internal static readonly Type ImmersiveShellBrokerType; + + internal static readonly Guid TipInvocationGuid; + internal static readonly Type TipInvocationType; + + static ComTypes() + { + TipInvocationGuid = Guid.Parse("4ce576fa-83dc-4F88-951c-9d0782b4e376"); + TipInvocationType = Type.GetTypeFromCLSID(TipInvocationGuid); + + ImmersiveShellBrokerGuid = new Guid("228826af-02e1-4226-a9e0-99a855e455a6"); + ImmersiveShellBrokerType = Type.GetTypeFromCLSID(ImmersiveShellBrokerGuid); + } + } +} diff --git a/MasaBlazorApp3/Validator/LoginModelValidator.cs b/MasaBlazorApp3/Validator/LoginModelValidator.cs new file mode 100644 index 0000000..7018b4e --- /dev/null +++ b/MasaBlazorApp3/Validator/LoginModelValidator.cs @@ -0,0 +1,22 @@ +using FluentValidation; +using MasaBlazorApp3.Pojo; + +namespace MasaBlazorApp3.Validator +{ + public class LoginModelValidator : AbstractValidator + { + public LoginModelValidator() + { + RuleFor(u => u.Username).NotEmpty().WithMessage("用户名不能为空"); + RuleFor(u => u.Password).NotEmpty(); + } + + public Func>> ValidateValue => async (model, propertyName) => + { + var result = await ValidateAsync(ValidationContext.CreateWithOptions((User)model, x => x.IncludeProperties(propertyName))); + if (result.IsValid) + return Array.Empty(); + return result.Errors.Select(e => e.ErrorMessage); + }; + } +} diff --git a/MasaBlazorApp3/_Imports.razor b/MasaBlazorApp3/_Imports.razor new file mode 100644 index 0000000..0237b18 --- /dev/null +++ b/MasaBlazorApp3/_Imports.razor @@ -0,0 +1,24 @@ +@using System.Net.Http +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using Radzen +@using Radzen.Blazor +@using MasaBlazorApp3.Shared; +@using System.Net.Http.Json +@using System.IO; +@using System.Text.Json; + +@using MasaBlazorApp3.Pojo +@using MasaBlazorApp3.Validator +@using MasaBlazorApp3.Finger +@using MasaBlazorApp3.Port + + + +@using MasaBlazorApp3.DataAccess.Impl; +@using MasaBlazorApp3.DataAccess.Dao; +@using MasaBlazorApp3.DataAccess; +@using MasaBlazorApp3; \ No newline at end of file diff --git a/MasaBlazorApp3/appsettings.json b/MasaBlazorApp3/appsettings.json new file mode 100644 index 0000000..dc03ca1 --- /dev/null +++ b/MasaBlazorApp3/appsettings.json @@ -0,0 +1,32 @@ +{ + "connectionStrings": "server=127.0.0.1;port=3306;database=hkcdb;userid=root;password=root;Charset=utf8mb4;", + "finger": { + "ip": "192.168.50.201", + "port": 4370, + "type": 2 + }, + "setting": { + "machineId": "DM1", + "storage": null, + "loginMode": 1, + "opFirst": true, + //自动退出登录时间,单位秒(0不自动退出) + "autoOutLog": 0 + }, + "port": { + "drawerPortPath": "COM1", + "drawerProtocol": 485, + "scanCodePortPath": "COM8", + "canBusPortPath": "COM5", + "canBusExsit": true, + "doorAddr": 0, + "storageBoxAddr": 0 + }, + "drawer": { + "single": [ 3 ], + "weigh": [1], + "box": [], + "label": [] + } + +} \ No newline at end of file diff --git a/MasaBlazorApp3/favicon.ico b/MasaBlazorApp3/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8a22d00e0617de4f53f0f794137426446f9286ef GIT binary patch literal 270398 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 Ryl{LyHv@8fzF>U+{{am4pp*ar literal 0 HcmV?d00001 diff --git a/MasaBlazorApp3/i18ntext/MyText.en.json b/MasaBlazorApp3/i18ntext/MyText.en.json new file mode 100644 index 0000000..41ec533 --- /dev/null +++ b/MasaBlazorApp3/i18ntext/MyText.en.json @@ -0,0 +1,4 @@ +{ + "login": "LOGIN", + "exit": "EXIT" +} diff --git a/MasaBlazorApp3/i18ntext/MyText.zh.json b/MasaBlazorApp3/i18ntext/MyText.zh.json new file mode 100644 index 0000000..6360d23 --- /dev/null +++ b/MasaBlazorApp3/i18ntext/MyText.zh.json @@ -0,0 +1,4 @@ +{ + "login": "登录", + "exit": "退出" +} diff --git a/MasaBlazorApp3/log4net.config b/MasaBlazorApp3/log4net.config new file mode 100644 index 0000000..a5c3389 --- /dev/null +++ b/MasaBlazorApp3/log4net.config @@ -0,0 +1,53 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MasaBlazorApp3/wwwroot/css/app.css b/MasaBlazorApp3/wwwroot/css/app.css new file mode 100644 index 0000000..6c60549 --- /dev/null +++ b/MasaBlazorApp3/wwwroot/css/app.css @@ -0,0 +1,62 @@ +html, body { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif, SimHei !important; +} + +h1:focus { + outline: none; +} + +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; +} + +.blazor-error-boundary { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; + padding: 1rem 1rem 1rem 3.7rem; + color: white; +} + +.blazor-error-boundary::after { + content: "An error has occurred." +} + +.status-bar-safe-area { + display: none; +} + +@supports (-webkit-touch-callout: none) { + .status-bar-safe-area { + display: flex; + position: sticky; + top: 0; + height: env(safe-area-inset-top); + background-color: #f7f7f7; + width: 100%; + z-index: 1; + } + + .flex-column, .navbar-brand { + padding-left: env(safe-area-inset-left); + } +} +.rz-datatable-thead th .rz-column-title, .rz-grid-table thead th .rz-column-title { + font-weight: 600 !important; +} +.rz-grid-table thead th { + background-color: #f2fafb !important; +} diff --git a/MasaBlazorApp3/wwwroot/css/bootstrap/bootstrap.min.css b/MasaBlazorApp3/wwwroot/css/bootstrap/bootstrap.min.css new file mode 100644 index 0000000..bd25b2e --- /dev/null +++ b/MasaBlazorApp3/wwwroot/css/bootstrap/bootstrap.min.css @@ -0,0 +1,11599 @@ +@charset "UTF-8"; /*! + * Bootstrap v5.1.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ + +:root { + --bs-blue: #0d6efd; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #d63384; + --bs-red: #dc3545; + --bs-orange: #fd7e14; + --bs-yellow: #ffc107; + --bs-green: #198754; + --bs-teal: #20c997; + --bs-cyan: #0dcaf0; + --bs-white: #fff; + --bs-gray: #6c757d; + --bs-gray-dark: #343a40; + --bs-gray-100: #f8f9fa; + --bs-gray-200: #e9ecef; + --bs-gray-300: #dee2e6; + --bs-gray-400: #ced4da; + --bs-gray-500: #adb5bd; + --bs-gray-600: #6c757d; + --bs-gray-700: #495057; + --bs-gray-800: #343a40; + --bs-gray-900: #212529; + --bs-primary: #0d6efd; + --bs-secondary: #6c757d; + --bs-success: #198754; + --bs-info: #0dcaf0; + --bs-warning: #ffc107; + --bs-danger: #dc3545; + --bs-light: #f8f9fa; + --bs-dark: #212529; + --bs-primary-rgb: 13,110,253; + --bs-secondary-rgb: 108,117,125; + --bs-success-rgb: 25,135,84; + --bs-info-rgb: 13,202,240; + --bs-warning-rgb: 255,193,7; + --bs-danger-rgb: 220,53,69; + --bs-light-rgb: 248,249,250; + --bs-dark-rgb: 33,37,41; + --bs-white-rgb: 255,255,255; + --bs-black-rgb: 0,0,0; + --bs-body-rgb: 33,37,41; + --bs-font-sans-serif: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; + --bs-font-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --bs-body-font-family: var(--bs-font-sans-serif); + --bs-body-font-size: 1rem; + --bs-body-font-weight: 400; + --bs-body-line-height: 1.5; + --bs-body-color: #212529; + --bs-body-bg: #fff +} + +*, ::after, ::before { + box-sizing: border-box +} + +@media (prefers-reduced-motion:no-preference) { + :root { + scroll-behavior: smooth + } +} + +body { + margin: 0; + font-family: var(--bs-body-font-family); + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); + color: var(--bs-body-color); + text-align: var(--bs-body-text-align); + background-color: var(--bs-body-bg); + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent +} + +hr { + margin: 1rem 0; + color: inherit; + background-color: currentColor; + border: 0; + opacity: .25 +} + + hr:not([size]) { + height: 1px + } + +.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: .5rem; + font-weight: 500; + line-height: 1.2 +} + +.h1, h1 { + font-size: calc(1.375rem + 1.5vw) +} + +@media (min-width:1200px) { + .h1, h1 { + font-size: 2.5rem + } +} + +.h2, h2 { + font-size: calc(1.325rem + .9vw) +} + +@media (min-width:1200px) { + .h2, h2 { + font-size: 2rem + } +} + +.h3, h3 { + font-size: calc(1.3rem + .6vw) +} + +@media (min-width:1200px) { + .h3, h3 { + font-size: 1.75rem + } +} + +.h4, h4 { + font-size: calc(1.275rem + .3vw) +} + +@media (min-width:1200px) { + .h4, h4 { + font-size: 1.5rem + } +} + +.h5, h5 { + font-size: 1.25rem +} + +.h6, h6 { + font-size: 1rem +} + +p { + margin-top: 0; + margin-bottom: 1rem +} + +abbr[data-bs-original-title], abbr[title] { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit +} + +ol, ul { + padding-left: 2rem +} + +dl, ol, ul { + margin-top: 0; + margin-bottom: 1rem +} + + ol ol, ol ul, ul ol, ul ul { + margin-bottom: 0 + } + +dt { + font-weight: 700 +} + +dd { + margin-bottom: .5rem; + margin-left: 0 +} + +blockquote { + margin: 0 0 1rem +} + +b, strong { + font-weight: bolder +} + +.small, small { + font-size: .875em +} + +.mark, mark { + padding: .2em; + background-color: #fcf8e3 +} + +sub, sup { + position: relative; + font-size: .75em; + line-height: 0; + vertical-align: baseline +} + +sub { + bottom: -.25em +} + +sup { + top: -.5em +} + +a { + color: #0d6efd; + text-decoration: underline +} + + a:hover { + color: #0a58ca + } + + a:not([href]):not([class]), a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none + } + +code, kbd, pre, samp { + font-family: var(--bs-font-monospace); + font-size: 1em; + direction: ltr; + unicode-bidi: bidi-override +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: .875em +} + + pre code { + font-size: inherit; + color: inherit; + word-break: normal + } + +code { + font-size: .875em; + color: #d63384; + word-wrap: break-word +} + +a > code { + color: inherit +} + +kbd { + padding: .2rem .4rem; + font-size: .875em; + color: #fff; + background-color: #212529; + border-radius: .2rem +} + + kbd kbd { + padding: 0; + font-size: 1em; + font-weight: 700 + } + +figure { + margin: 0 0 1rem +} + +img, svg { + vertical-align: middle +} + +table { + caption-side: bottom; + border-collapse: collapse +} + +caption { + padding-top: .5rem; + padding-bottom: .5rem; + color: #6c757d; + text-align: left +} + +th { + text-align: inherit; + text-align: -webkit-match-parent +} + +tbody, td, tfoot, th, thead, tr { + border-color: inherit; + border-style: solid; + border-width: 0 +} + +label { + display: inline-block +} + +button { + border-radius: 0 +} + + button:focus:not(:focus-visible) { + outline: 0 + } + +button, input, optgroup, select, textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit +} + +button, select { + text-transform: none +} + +[role=button] { + cursor: pointer +} + +select { + word-wrap: normal +} + + select:disabled { + opacity: 1 + } + +[list]::-webkit-calendar-picker-indicator { + display: none +} + +[type=button], [type=reset], [type=submit], button { + -webkit-appearance: button +} + + [type=button]:not(:disabled), [type=reset]:not(:disabled), [type=submit]:not(:disabled), button:not(:disabled) { + cursor: pointer + } + +::-moz-focus-inner { + padding: 0; + border-style: none +} + +textarea { + resize: vertical +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0 +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: calc(1.275rem + .3vw); + line-height: inherit +} + +@media (min-width:1200px) { + legend { + font-size: 1.5rem + } +} + +legend + * { + clear: left +} + +::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-fields-wrapper, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-text, ::-webkit-datetime-edit-year-field { + padding: 0 +} + +::-webkit-inner-spin-button { + height: auto +} + +[type=search] { + outline-offset: -2px; + -webkit-appearance: textfield +} + +::-webkit-search-decoration { + -webkit-appearance: none +} + +::-webkit-color-swatch-wrapper { + padding: 0 +} + +::file-selector-button { + font: inherit +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button +} + +output { + display: inline-block +} + +iframe { + border: 0 +} + +summary { + display: list-item; + cursor: pointer +} + +progress { + vertical-align: baseline +} + +[hidden] { + display: none !important +} + +.lead { + font-size: 1.25rem; + font-weight: 300 +} + +.display-1 { + font-size: calc(1.625rem + 4.5vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width:1200px) { + .display-1 { + font-size: 5rem + } +} + +.display-2 { + font-size: calc(1.575rem + 3.9vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width:1200px) { + .display-2 { + font-size: 4.5rem + } +} + +.display-3 { + font-size: calc(1.525rem + 3.3vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width:1200px) { + .display-3 { + font-size: 4rem + } +} + +.display-4 { + font-size: calc(1.475rem + 2.7vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width:1200px) { + .display-4 { + font-size: 3.5rem + } +} + +.display-5 { + font-size: calc(1.425rem + 2.1vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width:1200px) { + .display-5 { + font-size: 3rem + } +} + +.display-6 { + font-size: calc(1.375rem + 1.5vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width:1200px) { + .display-6 { + font-size: 2.5rem + } +} + +.list-unstyled { + padding-left: 0; + list-style: none +} + +.list-inline { + padding-left: 0; + list-style: none +} + +.list-inline-item { + display: inline-block +} + + .list-inline-item:not(:last-child) { + margin-right: .5rem + } + +.initialism { + font-size: .875em; + text-transform: uppercase +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem +} + + .blockquote > :last-child { + margin-bottom: 0 + } + +.blockquote-footer { + margin-top: -1rem; + margin-bottom: 1rem; + font-size: .875em; + color: #6c757d +} + + .blockquote-footer::before { + content: "— " + } + +.img-fluid { + max-width: 100%; + height: auto +} + +.img-thumbnail { + padding: .25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: .25rem; + max-width: 100%; + height: auto +} + +.figure { + display: inline-block +} + +.figure-img { + margin-bottom: .5rem; + line-height: 1 +} + +.figure-caption { + font-size: .875em; + color: #6c757d +} + +.container, .container-fluid, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { + width: 100%; + padding-right: var(--bs-gutter-x,.75rem); + padding-left: var(--bs-gutter-x,.75rem); + margin-right: auto; + margin-left: auto +} + +@media (min-width:576px) { + .container, .container-sm { + max-width: 540px + } +} + +@media (min-width:768px) { + .container, .container-md, .container-sm { + max-width: 720px + } +} + +@media (min-width:992px) { + .container, .container-lg, .container-md, .container-sm { + max-width: 960px + } +} + +@media (min-width:1200px) { + .container, .container-lg, .container-md, .container-sm, .container-xl { + max-width: 1140px + } +} + +@media (min-width:1400px) { + .container, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { + max-width: 1320px + } +} + +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(var(--bs-gutter-y) * -1); + margin-right: calc(var(--bs-gutter-x) * -.5); + margin-left: calc(var(--bs-gutter-x) * -.5) +} + + .row > * { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * .5); + padding-left: calc(var(--bs-gutter-x) * .5); + margin-top: var(--bs-gutter-y) + } + +.col { + flex: 1 0 0% +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100% +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50% +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.3333333333% +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25% +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20% +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.6666666667% +} + +.col-auto { + flex: 0 0 auto; + width: auto +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333% +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667% +} + +.col-3 { + flex: 0 0 auto; + width: 25% +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333% +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667% +} + +.col-6 { + flex: 0 0 auto; + width: 50% +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333% +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667% +} + +.col-9 { + flex: 0 0 auto; + width: 75% +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333% +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667% +} + +.col-12 { + flex: 0 0 auto; + width: 100% +} + +.offset-1 { + margin-left: 8.33333333% +} + +.offset-2 { + margin-left: 16.66666667% +} + +.offset-3 { + margin-left: 25% +} + +.offset-4 { + margin-left: 33.33333333% +} + +.offset-5 { + margin-left: 41.66666667% +} + +.offset-6 { + margin-left: 50% +} + +.offset-7 { + margin-left: 58.33333333% +} + +.offset-8 { + margin-left: 66.66666667% +} + +.offset-9 { + margin-left: 75% +} + +.offset-10 { + margin-left: 83.33333333% +} + +.offset-11 { + margin-left: 91.66666667% +} + +.g-0, .gx-0 { + --bs-gutter-x: 0 +} + +.g-0, .gy-0 { + --bs-gutter-y: 0 +} + +.g-1, .gx-1 { + --bs-gutter-x: 0.25rem +} + +.g-1, .gy-1 { + --bs-gutter-y: 0.25rem +} + +.g-2, .gx-2 { + --bs-gutter-x: 0.5rem +} + +.g-2, .gy-2 { + --bs-gutter-y: 0.5rem +} + +.g-3, .gx-3 { + --bs-gutter-x: 1rem +} + +.g-3, .gy-3 { + --bs-gutter-y: 1rem +} + +.g-4, .gx-4 { + --bs-gutter-x: 1.5rem +} + +.g-4, .gy-4 { + --bs-gutter-y: 1.5rem +} + +.g-5, .gx-5 { + --bs-gutter-x: 3rem +} + +.g-5, .gy-5 { + --bs-gutter-y: 3rem +} + +@media (min-width:576px) { + .col-sm { + flex: 1 0 0% + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-sm-auto { + flex: 0 0 auto; + width: auto + } + + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-sm-3 { + flex: 0 0 auto; + width: 25% + } + + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-sm-6 { + flex: 0 0 auto; + width: 50% + } + + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-sm-9 { + flex: 0 0 auto; + width: 75% + } + + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-sm-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-sm-0 { + margin-left: 0 + } + + .offset-sm-1 { + margin-left: 8.33333333% + } + + .offset-sm-2 { + margin-left: 16.66666667% + } + + .offset-sm-3 { + margin-left: 25% + } + + .offset-sm-4 { + margin-left: 33.33333333% + } + + .offset-sm-5 { + margin-left: 41.66666667% + } + + .offset-sm-6 { + margin-left: 50% + } + + .offset-sm-7 { + margin-left: 58.33333333% + } + + .offset-sm-8 { + margin-left: 66.66666667% + } + + .offset-sm-9 { + margin-left: 75% + } + + .offset-sm-10 { + margin-left: 83.33333333% + } + + .offset-sm-11 { + margin-left: 91.66666667% + } + + .g-sm-0, .gx-sm-0 { + --bs-gutter-x: 0 + } + + .g-sm-0, .gy-sm-0 { + --bs-gutter-y: 0 + } + + .g-sm-1, .gx-sm-1 { + --bs-gutter-x: 0.25rem + } + + .g-sm-1, .gy-sm-1 { + --bs-gutter-y: 0.25rem + } + + .g-sm-2, .gx-sm-2 { + --bs-gutter-x: 0.5rem + } + + .g-sm-2, .gy-sm-2 { + --bs-gutter-y: 0.5rem + } + + .g-sm-3, .gx-sm-3 { + --bs-gutter-x: 1rem + } + + .g-sm-3, .gy-sm-3 { + --bs-gutter-y: 1rem + } + + .g-sm-4, .gx-sm-4 { + --bs-gutter-x: 1.5rem + } + + .g-sm-4, .gy-sm-4 { + --bs-gutter-y: 1.5rem + } + + .g-sm-5, .gx-sm-5 { + --bs-gutter-x: 3rem + } + + .g-sm-5, .gy-sm-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width:768px) { + .col-md { + flex: 1 0 0% + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-md-auto { + flex: 0 0 auto; + width: auto + } + + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-md-3 { + flex: 0 0 auto; + width: 25% + } + + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-md-6 { + flex: 0 0 auto; + width: 50% + } + + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-md-9 { + flex: 0 0 auto; + width: 75% + } + + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-md-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-md-0 { + margin-left: 0 + } + + .offset-md-1 { + margin-left: 8.33333333% + } + + .offset-md-2 { + margin-left: 16.66666667% + } + + .offset-md-3 { + margin-left: 25% + } + + .offset-md-4 { + margin-left: 33.33333333% + } + + .offset-md-5 { + margin-left: 41.66666667% + } + + .offset-md-6 { + margin-left: 50% + } + + .offset-md-7 { + margin-left: 58.33333333% + } + + .offset-md-8 { + margin-left: 66.66666667% + } + + .offset-md-9 { + margin-left: 75% + } + + .offset-md-10 { + margin-left: 83.33333333% + } + + .offset-md-11 { + margin-left: 91.66666667% + } + + .g-md-0, .gx-md-0 { + --bs-gutter-x: 0 + } + + .g-md-0, .gy-md-0 { + --bs-gutter-y: 0 + } + + .g-md-1, .gx-md-1 { + --bs-gutter-x: 0.25rem + } + + .g-md-1, .gy-md-1 { + --bs-gutter-y: 0.25rem + } + + .g-md-2, .gx-md-2 { + --bs-gutter-x: 0.5rem + } + + .g-md-2, .gy-md-2 { + --bs-gutter-y: 0.5rem + } + + .g-md-3, .gx-md-3 { + --bs-gutter-x: 1rem + } + + .g-md-3, .gy-md-3 { + --bs-gutter-y: 1rem + } + + .g-md-4, .gx-md-4 { + --bs-gutter-x: 1.5rem + } + + .g-md-4, .gy-md-4 { + --bs-gutter-y: 1.5rem + } + + .g-md-5, .gx-md-5 { + --bs-gutter-x: 3rem + } + + .g-md-5, .gy-md-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width:992px) { + .col-lg { + flex: 1 0 0% + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-lg-auto { + flex: 0 0 auto; + width: auto + } + + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-lg-3 { + flex: 0 0 auto; + width: 25% + } + + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-lg-6 { + flex: 0 0 auto; + width: 50% + } + + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-lg-9 { + flex: 0 0 auto; + width: 75% + } + + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-lg-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-lg-0 { + margin-left: 0 + } + + .offset-lg-1 { + margin-left: 8.33333333% + } + + .offset-lg-2 { + margin-left: 16.66666667% + } + + .offset-lg-3 { + margin-left: 25% + } + + .offset-lg-4 { + margin-left: 33.33333333% + } + + .offset-lg-5 { + margin-left: 41.66666667% + } + + .offset-lg-6 { + margin-left: 50% + } + + .offset-lg-7 { + margin-left: 58.33333333% + } + + .offset-lg-8 { + margin-left: 66.66666667% + } + + .offset-lg-9 { + margin-left: 75% + } + + .offset-lg-10 { + margin-left: 83.33333333% + } + + .offset-lg-11 { + margin-left: 91.66666667% + } + + .g-lg-0, .gx-lg-0 { + --bs-gutter-x: 0 + } + + .g-lg-0, .gy-lg-0 { + --bs-gutter-y: 0 + } + + .g-lg-1, .gx-lg-1 { + --bs-gutter-x: 0.25rem + } + + .g-lg-1, .gy-lg-1 { + --bs-gutter-y: 0.25rem + } + + .g-lg-2, .gx-lg-2 { + --bs-gutter-x: 0.5rem + } + + .g-lg-2, .gy-lg-2 { + --bs-gutter-y: 0.5rem + } + + .g-lg-3, .gx-lg-3 { + --bs-gutter-x: 1rem + } + + .g-lg-3, .gy-lg-3 { + --bs-gutter-y: 1rem + } + + .g-lg-4, .gx-lg-4 { + --bs-gutter-x: 1.5rem + } + + .g-lg-4, .gy-lg-4 { + --bs-gutter-y: 1.5rem + } + + .g-lg-5, .gx-lg-5 { + --bs-gutter-x: 3rem + } + + .g-lg-5, .gy-lg-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width:1200px) { + .col-xl { + flex: 1 0 0% + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-xl-auto { + flex: 0 0 auto; + width: auto + } + + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-xl-3 { + flex: 0 0 auto; + width: 25% + } + + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-xl-6 { + flex: 0 0 auto; + width: 50% + } + + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-xl-9 { + flex: 0 0 auto; + width: 75% + } + + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-xl-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-xl-0 { + margin-left: 0 + } + + .offset-xl-1 { + margin-left: 8.33333333% + } + + .offset-xl-2 { + margin-left: 16.66666667% + } + + .offset-xl-3 { + margin-left: 25% + } + + .offset-xl-4 { + margin-left: 33.33333333% + } + + .offset-xl-5 { + margin-left: 41.66666667% + } + + .offset-xl-6 { + margin-left: 50% + } + + .offset-xl-7 { + margin-left: 58.33333333% + } + + .offset-xl-8 { + margin-left: 66.66666667% + } + + .offset-xl-9 { + margin-left: 75% + } + + .offset-xl-10 { + margin-left: 83.33333333% + } + + .offset-xl-11 { + margin-left: 91.66666667% + } + + .g-xl-0, .gx-xl-0 { + --bs-gutter-x: 0 + } + + .g-xl-0, .gy-xl-0 { + --bs-gutter-y: 0 + } + + .g-xl-1, .gx-xl-1 { + --bs-gutter-x: 0.25rem + } + + .g-xl-1, .gy-xl-1 { + --bs-gutter-y: 0.25rem + } + + .g-xl-2, .gx-xl-2 { + --bs-gutter-x: 0.5rem + } + + .g-xl-2, .gy-xl-2 { + --bs-gutter-y: 0.5rem + } + + .g-xl-3, .gx-xl-3 { + --bs-gutter-x: 1rem + } + + .g-xl-3, .gy-xl-3 { + --bs-gutter-y: 1rem + } + + .g-xl-4, .gx-xl-4 { + --bs-gutter-x: 1.5rem + } + + .g-xl-4, .gy-xl-4 { + --bs-gutter-y: 1.5rem + } + + .g-xl-5, .gx-xl-5 { + --bs-gutter-x: 3rem + } + + .g-xl-5, .gy-xl-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width:1400px) { + .col-xxl { + flex: 1 0 0% + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-xxl-auto { + flex: 0 0 auto; + width: auto + } + + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-xxl-3 { + flex: 0 0 auto; + width: 25% + } + + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-xxl-6 { + flex: 0 0 auto; + width: 50% + } + + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-xxl-9 { + flex: 0 0 auto; + width: 75% + } + + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-xxl-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-xxl-0 { + margin-left: 0 + } + + .offset-xxl-1 { + margin-left: 8.33333333% + } + + .offset-xxl-2 { + margin-left: 16.66666667% + } + + .offset-xxl-3 { + margin-left: 25% + } + + .offset-xxl-4 { + margin-left: 33.33333333% + } + + .offset-xxl-5 { + margin-left: 41.66666667% + } + + .offset-xxl-6 { + margin-left: 50% + } + + .offset-xxl-7 { + margin-left: 58.33333333% + } + + .offset-xxl-8 { + margin-left: 66.66666667% + } + + .offset-xxl-9 { + margin-left: 75% + } + + .offset-xxl-10 { + margin-left: 83.33333333% + } + + .offset-xxl-11 { + margin-left: 91.66666667% + } + + .g-xxl-0, .gx-xxl-0 { + --bs-gutter-x: 0 + } + + .g-xxl-0, .gy-xxl-0 { + --bs-gutter-y: 0 + } + + .g-xxl-1, .gx-xxl-1 { + --bs-gutter-x: 0.25rem + } + + .g-xxl-1, .gy-xxl-1 { + --bs-gutter-y: 0.25rem + } + + .g-xxl-2, .gx-xxl-2 { + --bs-gutter-x: 0.5rem + } + + .g-xxl-2, .gy-xxl-2 { + --bs-gutter-y: 0.5rem + } + + .g-xxl-3, .gx-xxl-3 { + --bs-gutter-x: 1rem + } + + .g-xxl-3, .gy-xxl-3 { + --bs-gutter-y: 1rem + } + + .g-xxl-4, .gx-xxl-4 { + --bs-gutter-x: 1.5rem + } + + .g-xxl-4, .gy-xxl-4 { + --bs-gutter-y: 1.5rem + } + + .g-xxl-5, .gx-xxl-5 { + --bs-gutter-x: 3rem + } + + .g-xxl-5, .gy-xxl-5 { + --bs-gutter-y: 3rem + } +} + +.table { + --bs-table-bg: transparent; + --bs-table-accent-bg: transparent; + --bs-table-striped-color: #212529; + --bs-table-striped-bg: rgba(0, 0, 0, 0.05); + --bs-table-active-color: #212529; + --bs-table-active-bg: rgba(0, 0, 0, 0.1); + --bs-table-hover-color: #212529; + --bs-table-hover-bg: rgba(0, 0, 0, 0.075); + width: 100%; + margin-bottom: 1rem; + color: #212529; + vertical-align: top; + border-color: #dee2e6 +} + + .table > :not(caption) > * > * { + padding: .5rem .5rem; + background-color: var(--bs-table-bg); + border-bottom-width: 1px; + box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg) + } + + .table > tbody { + vertical-align: inherit + } + + .table > thead { + vertical-align: bottom + } + + .table > :not(:last-child) > :last-child > * { + border-bottom-color: currentColor + } + +.caption-top { + caption-side: top +} + +.table-sm > :not(caption) > * > * { + padding: .25rem .25rem +} + +.table-bordered > :not(caption) > * { + border-width: 1px 0 +} + + .table-bordered > :not(caption) > * > * { + border-width: 0 1px + } + +.table-borderless > :not(caption) > * > * { + border-bottom-width: 0 +} + +.table-striped > tbody > tr:nth-of-type(odd) { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color) +} + +.table-active { + --bs-table-accent-bg: var(--bs-table-active-bg); + color: var(--bs-table-active-color) +} + +.table-hover > tbody > tr:hover { + --bs-table-accent-bg: var(--bs-table-hover-bg); + color: var(--bs-table-hover-color) +} + +.table-primary { + --bs-table-bg: #cfe2ff; + --bs-table-striped-bg: #c5d7f2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bacbe6; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfd1ec; + --bs-table-hover-color: #000; + color: #000; + border-color: #bacbe6 +} + +.table-secondary { + --bs-table-bg: #e2e3e5; + --bs-table-striped-bg: #d7d8da; + --bs-table-striped-color: #000; + --bs-table-active-bg: #cbccce; + --bs-table-active-color: #000; + --bs-table-hover-bg: #d1d2d4; + --bs-table-hover-color: #000; + color: #000; + border-color: #cbccce +} + +.table-success { + --bs-table-bg: #d1e7dd; + --bs-table-striped-bg: #c7dbd2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bcd0c7; + --bs-table-active-color: #000; + --bs-table-hover-bg: #c1d6cc; + --bs-table-hover-color: #000; + color: #000; + border-color: #bcd0c7 +} + +.table-info { + --bs-table-bg: #cff4fc; + --bs-table-striped-bg: #c5e8ef; + --bs-table-striped-color: #000; + --bs-table-active-bg: #badce3; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfe2e9; + --bs-table-hover-color: #000; + color: #000; + border-color: #badce3 +} + +.table-warning { + --bs-table-bg: #fff3cd; + --bs-table-striped-bg: #f2e7c3; + --bs-table-striped-color: #000; + --bs-table-active-bg: #e6dbb9; + --bs-table-active-color: #000; + --bs-table-hover-bg: #ece1be; + --bs-table-hover-color: #000; + color: #000; + border-color: #e6dbb9 +} + +.table-danger { + --bs-table-bg: #f8d7da; + --bs-table-striped-bg: #eccccf; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfc2c4; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5c7ca; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfc2c4 +} + +.table-light { + --bs-table-bg: #f8f9fa; + --bs-table-striped-bg: #ecedee; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfe0e1; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5e6e7; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfe0e1 +} + +.table-dark { + --bs-table-bg: #212529; + --bs-table-striped-bg: #2c3034; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #373b3e; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #323539; + --bs-table-hover-color: #fff; + color: #fff; + border-color: #373b3e +} + +.table-responsive { + overflow-x: auto; + -webkit-overflow-scrolling: touch +} + +@media (max-width:575.98px) { + .table-responsive-sm { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width:767.98px) { + .table-responsive-md { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width:991.98px) { + .table-responsive-lg { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width:1199.98px) { + .table-responsive-xl { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width:1399.98px) { + .table-responsive-xxl { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +.form-label { + margin-bottom: .5rem +} + +.col-form-label { + padding-top: calc(.375rem + 1px); + padding-bottom: calc(.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5 +} + +.col-form-label-lg { + padding-top: calc(.5rem + 1px); + padding-bottom: calc(.5rem + 1px); + font-size: 1.25rem +} + +.col-form-label-sm { + padding-top: calc(.25rem + 1px); + padding-bottom: calc(.25rem + 1px); + font-size: .875rem +} + +.form-text { + margin-top: .25rem; + font-size: .875em; + color: #6c757d +} + +.form-control { + display: block; + width: 100%; + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: .25rem; + transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .form-control { + transition: none + } +} + +.form-control[type=file] { + overflow: hidden +} + + .form-control[type=file]:not(:disabled):not([readonly]) { + cursor: pointer + } + +.form-control:focus { + color: #212529; + background-color: #fff; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13,110,253,.25) +} + +.form-control::-webkit-date-and-time-value { + height: 1.5em +} + +.form-control::-moz-placeholder { + color: #6c757d; + opacity: 1 +} + +.form-control::placeholder { + color: #6c757d; + opacity: 1 +} + +.form-control:disabled, .form-control[readonly] { + background-color: #e9ecef; + opacity: 1 +} + +.form-control::file-selector-button { + padding: .375rem .75rem; + margin: -.375rem -.75rem; + -webkit-margin-end: .75rem; + margin-inline-end: .75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .form-control::file-selector-button { + transition: none + } +} + +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: #dde0e3 +} + +.form-control::-webkit-file-upload-button { + padding: .375rem .75rem; + margin: -.375rem -.75rem; + -webkit-margin-end: .75rem; + margin-inline-end: .75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + -webkit-transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .form-control::-webkit-file-upload-button { + -webkit-transition: none; + transition: none + } +} + +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: #dde0e3 +} + +.form-control-plaintext { + display: block; + width: 100%; + padding: .375rem 0; + margin-bottom: 0; + line-height: 1.5; + color: #212529; + background-color: transparent; + border: solid transparent; + border-width: 1px 0 +} + + .form-control-plaintext.form-control-lg, .form-control-plaintext.form-control-sm { + padding-right: 0; + padding-left: 0 + } + +.form-control-sm { + min-height: calc(1.5em + .5rem + 2px); + padding: .25rem .5rem; + font-size: .875rem; + border-radius: .2rem +} + + .form-control-sm::file-selector-button { + padding: .25rem .5rem; + margin: -.25rem -.5rem; + -webkit-margin-end: .5rem; + margin-inline-end: .5rem + } + + .form-control-sm::-webkit-file-upload-button { + padding: .25rem .5rem; + margin: -.25rem -.5rem; + -webkit-margin-end: .5rem; + margin-inline-end: .5rem + } + +.form-control-lg { + min-height: calc(1.5em + 1rem + 2px); + padding: .5rem 1rem; + font-size: 1.25rem; + border-radius: .3rem +} + + .form-control-lg::file-selector-button { + padding: .5rem 1rem; + margin: -.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem + } + + .form-control-lg::-webkit-file-upload-button { + padding: .5rem 1rem; + margin: -.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem + } + +textarea.form-control { + min-height: calc(1.5em + .75rem + 2px) +} + +textarea.form-control-sm { + min-height: calc(1.5em + .5rem + 2px) +} + +textarea.form-control-lg { + min-height: calc(1.5em + 1rem + 2px) +} + +.form-control-color { + width: 3rem; + height: auto; + padding: .375rem +} + + .form-control-color:not(:disabled):not([readonly]) { + cursor: pointer + } + + .form-control-color::-moz-color-swatch { + height: 1.5em; + border-radius: .25rem + } + + .form-control-color::-webkit-color-swatch { + height: 1.5em; + border-radius: .25rem + } + +.form-select { + display: block; + width: 100%; + padding: .375rem 2.25rem .375rem .75rem; + -moz-padding-start: calc(0.75rem - 3px); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right .75rem center; + background-size: 16px 12px; + border: 1px solid #ced4da; + border-radius: .25rem; + transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +@media (prefers-reduced-motion:reduce) { + .form-select { + transition: none + } +} + +.form-select:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13,110,253,.25) +} + +.form-select[multiple], .form-select[size]:not([size="1"]) { + padding-right: .75rem; + background-image: none +} + +.form-select:disabled { + background-color: #e9ecef +} + +.form-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #212529 +} + +.form-select-sm { + padding-top: .25rem; + padding-bottom: .25rem; + padding-left: .5rem; + font-size: .875rem +} + +.form-select-lg { + padding-top: .5rem; + padding-bottom: .5rem; + padding-left: 1rem; + font-size: 1.25rem +} + +.form-check { + display: block; + min-height: 1.5rem; + padding-left: 1.5em; + margin-bottom: .125rem +} + + .form-check .form-check-input { + float: left; + margin-left: -1.5em + } + +.form-check-input { + width: 1em; + height: 1em; + margin-top: .25em; + vertical-align: top; + background-color: #fff; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + border: 1px solid rgba(0,0,0,.25); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-print-color-adjust: exact; + color-adjust: exact +} + + .form-check-input[type=checkbox] { + border-radius: .25em + } + + .form-check-input[type=radio] { + border-radius: 50% + } + + .form-check-input:active { + filter: brightness(90%) + } + + .form-check-input:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13,110,253,.25) + } + + .form-check-input:checked { + background-color: #0d6efd; + border-color: #0d6efd + } + + .form-check-input:checked[type=checkbox] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e") + } + + .form-check-input:checked[type=radio] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e") + } + + .form-check-input[type=checkbox]:indeterminate { + background-color: #0d6efd; + border-color: #0d6efd; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e") + } + + .form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: .5 + } + + .form-check-input:disabled ~ .form-check-label, .form-check-input[disabled] ~ .form-check-label { + opacity: .5 + } + +.form-switch { + padding-left: 2.5em +} + + .form-switch .form-check-input { + width: 2em; + margin-left: -2.5em; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); + background-position: left center; + border-radius: 2em; + transition: background-position .15s ease-in-out + } + +@media (prefers-reduced-motion:reduce) { + .form-switch .form-check-input { + transition: none + } +} + +.form-switch .form-check-input:focus { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e") +} + +.form-switch .form-check-input:checked { + background-position: right center; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e") +} + +.form-check-inline { + display: inline-block; + margin-right: 1rem +} + +.btn-check { + position: absolute; + clip: rect(0,0,0,0); + pointer-events: none +} + + .btn-check:disabled + .btn, .btn-check[disabled] + .btn { + pointer-events: none; + filter: none; + opacity: .65 + } + +.form-range { + width: 100%; + height: 1.5rem; + padding: 0; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + + .form-range:focus { + outline: 0 + } + + .form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25) + } + + .form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25) + } + + .form-range::-moz-focus-outer { + border: 0 + } + + .form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -.25rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + -webkit-transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + -webkit-appearance: none; + appearance: none + } + +@media (prefers-reduced-motion:reduce) { + .form-range::-webkit-slider-thumb { + -webkit-transition: none; + transition: none + } +} + +.form-range::-webkit-slider-thumb:active { + background-color: #b6d4fe +} + +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem +} + +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + -moz-transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + -moz-appearance: none; + appearance: none +} + +@media (prefers-reduced-motion:reduce) { + .form-range::-moz-range-thumb { + -moz-transition: none; + transition: none + } +} + +.form-range::-moz-range-thumb:active { + background-color: #b6d4fe +} + +.form-range::-moz-range-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem +} + +.form-range:disabled { + pointer-events: none +} + + .form-range:disabled::-webkit-slider-thumb { + background-color: #adb5bd + } + + .form-range:disabled::-moz-range-thumb { + background-color: #adb5bd + } + +.form-floating { + position: relative +} + + .form-floating > .form-control, .form-floating > .form-select { + height: calc(3.5rem + 2px); + line-height: 1.25 + } + + .form-floating > label { + position: absolute; + top: 0; + left: 0; + height: 100%; + padding: 1rem .75rem; + pointer-events: none; + border: 1px solid transparent; + transform-origin: 0 0; + transition: opacity .1s ease-in-out,transform .1s ease-in-out + } + +@media (prefers-reduced-motion:reduce) { + .form-floating > label { + transition: none + } +} + +.form-floating > .form-control { + padding: 1rem .75rem +} + + .form-floating > .form-control::-moz-placeholder { + color: transparent + } + + .form-floating > .form-control::placeholder { + color: transparent + } + + .form-floating > .form-control:not(:-moz-placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: .625rem + } + + .form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: .625rem + } + + .form-floating > .form-control:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: .625rem + } + +.form-floating > .form-select { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating > .form-control:focus ~ label, .form-floating > .form-control:not(:placeholder-shown) ~ label, .form-floating > .form-select ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating > .form-control:-webkit-autofill ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100% +} + + .input-group > .form-control, .input-group > .form-select { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0 + } + + .input-group > .form-control:focus, .input-group > .form-select:focus { + z-index: 3 + } + + .input-group .btn { + position: relative; + z-index: 2 + } + + .input-group .btn:focus { + z-index: 3 + } + +.input-group-text { + display: flex; + align-items: center; + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: .25rem +} + +.input-group-lg > .btn, .input-group-lg > .form-control, .input-group-lg > .form-select, .input-group-lg > .input-group-text { + padding: .5rem 1rem; + font-size: 1.25rem; + border-radius: .3rem +} + +.input-group-sm > .btn, .input-group-sm > .form-control, .input-group-sm > .form-select, .input-group-sm > .input-group-text { + padding: .25rem .5rem; + font-size: .875rem; + border-radius: .2rem +} + +.input-group-lg > .form-select, .input-group-sm > .form-select { + padding-right: 3rem +} + +.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3), .input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4), .input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: .25rem; + font-size: .875em; + color: #198754 +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .25rem .5rem; + margin-top: .1rem; + font-size: .875rem; + color: #fff; + background-color: rgba(25,135,84,.9); + border-radius: .25rem +} + +.is-valid ~ .valid-feedback, .is-valid ~ .valid-tooltip, .was-validated :valid ~ .valid-feedback, .was-validated :valid ~ .valid-tooltip { + display: block +} + +.form-control.is-valid, .was-validated .form-control:valid { + border-color: #198754; + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem) +} + + .form-control.is-valid:focus, .was-validated .form-control:valid:focus { + border-color: #198754; + box-shadow: 0 0 0 .25rem rgba(25,135,84,.25) + } + +.was-validated textarea.form-control:valid, textarea.form-control.is-valid { + padding-right: calc(1.5em + .75rem); + background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem) +} + +.form-select.is-valid, .was-validated .form-select:valid { + border-color: #198754 +} + + .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"], .was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-position: right .75rem center,center right 2.25rem; + background-size: 16px 12px,calc(.75em + .375rem) calc(.75em + .375rem) + } + + .form-select.is-valid:focus, .was-validated .form-select:valid:focus { + border-color: #198754; + box-shadow: 0 0 0 .25rem rgba(25,135,84,.25) + } + +.form-check-input.is-valid, .was-validated .form-check-input:valid { + border-color: #198754 +} + + .form-check-input.is-valid:checked, .was-validated .form-check-input:valid:checked { + background-color: #198754 + } + + .form-check-input.is-valid:focus, .was-validated .form-check-input:valid:focus { + box-shadow: 0 0 0 .25rem rgba(25,135,84,.25) + } + + .form-check-input.is-valid ~ .form-check-label, .was-validated .form-check-input:valid ~ .form-check-label { + color: #198754 + } + +.form-check-inline .form-check-input ~ .valid-feedback { + margin-left: .5em +} + +.input-group .form-control.is-valid, .input-group .form-select.is-valid, .was-validated .input-group .form-control:valid, .was-validated .input-group .form-select:valid { + z-index: 1 +} + + .input-group .form-control.is-valid:focus, .input-group .form-select.is-valid:focus, .was-validated .input-group .form-control:valid:focus, .was-validated .input-group .form-select:valid:focus { + z-index: 3 + } + +.invalid-feedback { + display: none; + width: 100%; + margin-top: .25rem; + font-size: .875em; + color: #dc3545 +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .25rem .5rem; + margin-top: .1rem; + font-size: .875rem; + color: #fff; + background-color: rgba(220,53,69,.9); + border-radius: .25rem +} + +.is-invalid ~ .invalid-feedback, .is-invalid ~ .invalid-tooltip, .was-validated :invalid ~ .invalid-feedback, .was-validated :invalid ~ .invalid-tooltip { + display: block +} + +.form-control.is-invalid, .was-validated .form-control:invalid { + border-color: #dc3545; + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem) +} + + .form-control.is-invalid:focus, .was-validated .form-control:invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 .25rem rgba(220,53,69,.25) + } + +.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { + padding-right: calc(1.5em + .75rem); + background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem) +} + +.form-select.is-invalid, .was-validated .form-select:invalid { + border-color: #dc3545 +} + + .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"], .was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-position: right .75rem center,center right 2.25rem; + background-size: 16px 12px,calc(.75em + .375rem) calc(.75em + .375rem) + } + + .form-select.is-invalid:focus, .was-validated .form-select:invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 .25rem rgba(220,53,69,.25) + } + +.form-check-input.is-invalid, .was-validated .form-check-input:invalid { + border-color: #dc3545 +} + + .form-check-input.is-invalid:checked, .was-validated .form-check-input:invalid:checked { + background-color: #dc3545 + } + + .form-check-input.is-invalid:focus, .was-validated .form-check-input:invalid:focus { + box-shadow: 0 0 0 .25rem rgba(220,53,69,.25) + } + + .form-check-input.is-invalid ~ .form-check-label, .was-validated .form-check-input:invalid ~ .form-check-label { + color: #dc3545 + } + +.form-check-inline .form-check-input ~ .invalid-feedback { + margin-left: .5em +} + +.input-group .form-control.is-invalid, .input-group .form-select.is-invalid, .was-validated .input-group .form-control:invalid, .was-validated .input-group .form-select:invalid { + z-index: 2 +} + + .input-group .form-control.is-invalid:focus, .input-group .form-select.is-invalid:focus, .was-validated .input-group .form-control:invalid:focus, .was-validated .input-group .form-select:invalid:focus { + z-index: 3 + } + +.btn { + display: inline-block; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + background-color: transparent; + border: 1px solid transparent; + padding: .375rem .75rem; + font-size: 1rem; + border-radius: .25rem; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .btn { + transition: none + } +} + +.btn:hover { + color: #212529 +} + +.btn-check:focus + .btn, .btn:focus { + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13,110,253,.25) +} + +.btn.disabled, .btn:disabled, fieldset:disabled .btn { + pointer-events: none; + opacity: .65 +} + +.btn-primary { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd +} + + .btn-primary:hover { + color: #fff; + background-color: #0b5ed7; + border-color: #0a58ca + } + + .btn-check:focus + .btn-primary, .btn-primary:focus { + color: #fff; + background-color: #0b5ed7; + border-color: #0a58ca; + box-shadow: 0 0 0 .25rem rgba(49,132,253,.5) + } + + .btn-check:active + .btn-primary, .btn-check:checked + .btn-primary, .btn-primary.active, .btn-primary:active, .show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0a58ca; + border-color: #0a53be + } + + .btn-check:active + .btn-primary:focus, .btn-check:checked + .btn-primary:focus, .btn-primary.active:focus, .btn-primary:active:focus, .show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(49,132,253,.5) + } + + .btn-primary.disabled, .btn-primary:disabled { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd + } + +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d +} + + .btn-secondary:hover { + color: #fff; + background-color: #5c636a; + border-color: #565e64 + } + + .btn-check:focus + .btn-secondary, .btn-secondary:focus { + color: #fff; + background-color: #5c636a; + border-color: #565e64; + box-shadow: 0 0 0 .25rem rgba(130,138,145,.5) + } + + .btn-check:active + .btn-secondary, .btn-check:checked + .btn-secondary, .btn-secondary.active, .btn-secondary:active, .show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #565e64; + border-color: #51585e + } + + .btn-check:active + .btn-secondary:focus, .btn-check:checked + .btn-secondary:focus, .btn-secondary.active:focus, .btn-secondary:active:focus, .show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(130,138,145,.5) + } + + .btn-secondary.disabled, .btn-secondary:disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d + } + +.btn-success { + color: #fff; + background-color: #198754; + border-color: #198754 +} + + .btn-success:hover { + color: #fff; + background-color: #157347; + border-color: #146c43 + } + + .btn-check:focus + .btn-success, .btn-success:focus { + color: #fff; + background-color: #157347; + border-color: #146c43; + box-shadow: 0 0 0 .25rem rgba(60,153,110,.5) + } + + .btn-check:active + .btn-success, .btn-check:checked + .btn-success, .btn-success.active, .btn-success:active, .show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #146c43; + border-color: #13653f + } + + .btn-check:active + .btn-success:focus, .btn-check:checked + .btn-success:focus, .btn-success.active:focus, .btn-success:active:focus, .show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(60,153,110,.5) + } + + .btn-success.disabled, .btn-success:disabled { + color: #fff; + background-color: #198754; + border-color: #198754 + } + +.btn-info { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0 +} + + .btn-info:hover { + color: #000; + background-color: #31d2f2; + border-color: #25cff2 + } + + .btn-check:focus + .btn-info, .btn-info:focus { + color: #000; + background-color: #31d2f2; + border-color: #25cff2; + box-shadow: 0 0 0 .25rem rgba(11,172,204,.5) + } + + .btn-check:active + .btn-info, .btn-check:checked + .btn-info, .btn-info.active, .btn-info:active, .show > .btn-info.dropdown-toggle { + color: #000; + background-color: #3dd5f3; + border-color: #25cff2 + } + + .btn-check:active + .btn-info:focus, .btn-check:checked + .btn-info:focus, .btn-info.active:focus, .btn-info:active:focus, .show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(11,172,204,.5) + } + + .btn-info.disabled, .btn-info:disabled { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0 + } + +.btn-warning { + color: #000; + background-color: #ffc107; + border-color: #ffc107 +} + + .btn-warning:hover { + color: #000; + background-color: #ffca2c; + border-color: #ffc720 + } + + .btn-check:focus + .btn-warning, .btn-warning:focus { + color: #000; + background-color: #ffca2c; + border-color: #ffc720; + box-shadow: 0 0 0 .25rem rgba(217,164,6,.5) + } + + .btn-check:active + .btn-warning, .btn-check:checked + .btn-warning, .btn-warning.active, .btn-warning:active, .show > .btn-warning.dropdown-toggle { + color: #000; + background-color: #ffcd39; + border-color: #ffc720 + } + + .btn-check:active + .btn-warning:focus, .btn-check:checked + .btn-warning:focus, .btn-warning.active:focus, .btn-warning:active:focus, .show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(217,164,6,.5) + } + + .btn-warning.disabled, .btn-warning:disabled { + color: #000; + background-color: #ffc107; + border-color: #ffc107 + } + +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545 +} + + .btn-danger:hover { + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37 + } + + .btn-check:focus + .btn-danger, .btn-danger:focus { + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37; + box-shadow: 0 0 0 .25rem rgba(225,83,97,.5) + } + + .btn-check:active + .btn-danger, .btn-check:checked + .btn-danger, .btn-danger.active, .btn-danger:active, .show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #b02a37; + border-color: #a52834 + } + + .btn-check:active + .btn-danger:focus, .btn-check:checked + .btn-danger:focus, .btn-danger.active:focus, .btn-danger:active:focus, .show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(225,83,97,.5) + } + + .btn-danger.disabled, .btn-danger:disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545 + } + +.btn-light { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa +} + + .btn-light:hover { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb + } + + .btn-check:focus + .btn-light, .btn-light:focus { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; + box-shadow: 0 0 0 .25rem rgba(211,212,213,.5) + } + + .btn-check:active + .btn-light, .btn-check:checked + .btn-light, .btn-light.active, .btn-light:active, .show > .btn-light.dropdown-toggle { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb + } + + .btn-check:active + .btn-light:focus, .btn-check:checked + .btn-light:focus, .btn-light.active:focus, .btn-light:active:focus, .show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(211,212,213,.5) + } + + .btn-light.disabled, .btn-light:disabled { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa + } + +.btn-dark { + color: #fff; + background-color: #212529; + border-color: #212529 +} + + .btn-dark:hover { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21 + } + + .btn-check:focus + .btn-dark, .btn-dark:focus { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; + box-shadow: 0 0 0 .25rem rgba(66,70,73,.5) + } + + .btn-check:active + .btn-dark, .btn-check:checked + .btn-dark, .btn-dark.active, .btn-dark:active, .show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1a1e21; + border-color: #191c1f + } + + .btn-check:active + .btn-dark:focus, .btn-check:checked + .btn-dark:focus, .btn-dark.active:focus, .btn-dark:active:focus, .show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 .25rem rgba(66,70,73,.5) + } + + .btn-dark.disabled, .btn-dark:disabled { + color: #fff; + background-color: #212529; + border-color: #212529 + } + +.btn-outline-primary { + color: #0d6efd; + border-color: #0d6efd +} + + .btn-outline-primary:hover { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd + } + + .btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { + box-shadow: 0 0 0 .25rem rgba(13,110,253,.5) + } + + .btn-check:active + .btn-outline-primary, .btn-check:checked + .btn-outline-primary, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show, .btn-outline-primary:active { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd + } + + .btn-check:active + .btn-outline-primary:focus, .btn-check:checked + .btn-outline-primary:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus, .btn-outline-primary:active:focus { + box-shadow: 0 0 0 .25rem rgba(13,110,253,.5) + } + + .btn-outline-primary.disabled, .btn-outline-primary:disabled { + color: #0d6efd; + background-color: transparent + } + +.btn-outline-secondary { + color: #6c757d; + border-color: #6c757d +} + + .btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d + } + + .btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { + box-shadow: 0 0 0 .25rem rgba(108,117,125,.5) + } + + .btn-check:active + .btn-outline-secondary, .btn-check:checked + .btn-outline-secondary, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show, .btn-outline-secondary:active { + color: #fff; + background-color: #6c757d; + border-color: #6c757d + } + + .btn-check:active + .btn-outline-secondary:focus, .btn-check:checked + .btn-outline-secondary:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus, .btn-outline-secondary:active:focus { + box-shadow: 0 0 0 .25rem rgba(108,117,125,.5) + } + + .btn-outline-secondary.disabled, .btn-outline-secondary:disabled { + color: #6c757d; + background-color: transparent + } + +.btn-outline-success { + color: #198754; + border-color: #198754 +} + + .btn-outline-success:hover { + color: #fff; + background-color: #198754; + border-color: #198754 + } + + .btn-check:focus + .btn-outline-success, .btn-outline-success:focus { + box-shadow: 0 0 0 .25rem rgba(25,135,84,.5) + } + + .btn-check:active + .btn-outline-success, .btn-check:checked + .btn-outline-success, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show, .btn-outline-success:active { + color: #fff; + background-color: #198754; + border-color: #198754 + } + + .btn-check:active + .btn-outline-success:focus, .btn-check:checked + .btn-outline-success:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus, .btn-outline-success:active:focus { + box-shadow: 0 0 0 .25rem rgba(25,135,84,.5) + } + + .btn-outline-success.disabled, .btn-outline-success:disabled { + color: #198754; + background-color: transparent + } + +.btn-outline-info { + color: #0dcaf0; + border-color: #0dcaf0 +} + + .btn-outline-info:hover { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0 + } + + .btn-check:focus + .btn-outline-info, .btn-outline-info:focus { + box-shadow: 0 0 0 .25rem rgba(13,202,240,.5) + } + + .btn-check:active + .btn-outline-info, .btn-check:checked + .btn-outline-info, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show, .btn-outline-info:active { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0 + } + + .btn-check:active + .btn-outline-info:focus, .btn-check:checked + .btn-outline-info:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus, .btn-outline-info:active:focus { + box-shadow: 0 0 0 .25rem rgba(13,202,240,.5) + } + + .btn-outline-info.disabled, .btn-outline-info:disabled { + color: #0dcaf0; + background-color: transparent + } + +.btn-outline-warning { + color: #ffc107; + border-color: #ffc107 +} + + .btn-outline-warning:hover { + color: #000; + background-color: #ffc107; + border-color: #ffc107 + } + + .btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { + box-shadow: 0 0 0 .25rem rgba(255,193,7,.5) + } + + .btn-check:active + .btn-outline-warning, .btn-check:checked + .btn-outline-warning, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show, .btn-outline-warning:active { + color: #000; + background-color: #ffc107; + border-color: #ffc107 + } + + .btn-check:active + .btn-outline-warning:focus, .btn-check:checked + .btn-outline-warning:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus, .btn-outline-warning:active:focus { + box-shadow: 0 0 0 .25rem rgba(255,193,7,.5) + } + + .btn-outline-warning.disabled, .btn-outline-warning:disabled { + color: #ffc107; + background-color: transparent + } + +.btn-outline-danger { + color: #dc3545; + border-color: #dc3545 +} + + .btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545 + } + + .btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { + box-shadow: 0 0 0 .25rem rgba(220,53,69,.5) + } + + .btn-check:active + .btn-outline-danger, .btn-check:checked + .btn-outline-danger, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show, .btn-outline-danger:active { + color: #fff; + background-color: #dc3545; + border-color: #dc3545 + } + + .btn-check:active + .btn-outline-danger:focus, .btn-check:checked + .btn-outline-danger:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus, .btn-outline-danger:active:focus { + box-shadow: 0 0 0 .25rem rgba(220,53,69,.5) + } + + .btn-outline-danger.disabled, .btn-outline-danger:disabled { + color: #dc3545; + background-color: transparent + } + +.btn-outline-light { + color: #f8f9fa; + border-color: #f8f9fa +} + + .btn-outline-light:hover { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa + } + + .btn-check:focus + .btn-outline-light, .btn-outline-light:focus { + box-shadow: 0 0 0 .25rem rgba(248,249,250,.5) + } + + .btn-check:active + .btn-outline-light, .btn-check:checked + .btn-outline-light, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show, .btn-outline-light:active { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa + } + + .btn-check:active + .btn-outline-light:focus, .btn-check:checked + .btn-outline-light:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus, .btn-outline-light:active:focus { + box-shadow: 0 0 0 .25rem rgba(248,249,250,.5) + } + + .btn-outline-light.disabled, .btn-outline-light:disabled { + color: #f8f9fa; + background-color: transparent + } + +.btn-outline-dark { + color: #212529; + border-color: #212529 +} + + .btn-outline-dark:hover { + color: #fff; + background-color: #212529; + border-color: #212529 + } + + .btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { + box-shadow: 0 0 0 .25rem rgba(33,37,41,.5) + } + + .btn-check:active + .btn-outline-dark, .btn-check:checked + .btn-outline-dark, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show, .btn-outline-dark:active { + color: #fff; + background-color: #212529; + border-color: #212529 + } + + .btn-check:active + .btn-outline-dark:focus, .btn-check:checked + .btn-outline-dark:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus, .btn-outline-dark:active:focus { + box-shadow: 0 0 0 .25rem rgba(33,37,41,.5) + } + + .btn-outline-dark.disabled, .btn-outline-dark:disabled { + color: #212529; + background-color: transparent + } + +.btn-link { + font-weight: 400; + color: #0d6efd; + text-decoration: underline +} + + .btn-link:hover { + color: #0a58ca + } + + .btn-link.disabled, .btn-link:disabled { + color: #6c757d + } + +.btn-group-lg > .btn, .btn-lg { + padding: .5rem 1rem; + font-size: 1.25rem; + border-radius: .3rem +} + +.btn-group-sm > .btn, .btn-sm { + padding: .25rem .5rem; + font-size: .875rem; + border-radius: .2rem +} + +.fade { + transition: opacity .15s linear +} + +@media (prefers-reduced-motion:reduce) { + .fade { + transition: none + } +} + +.fade:not(.show) { + opacity: 0 +} + +.collapse:not(.show) { + display: none +} + +.collapsing { + height: 0; + overflow: hidden; + transition: height .35s ease +} + +@media (prefers-reduced-motion:reduce) { + .collapsing { + transition: none + } +} + +.collapsing.collapse-horizontal { + width: 0; + height: auto; + transition: width .35s ease +} + +@media (prefers-reduced-motion:reduce) { + .collapsing.collapse-horizontal { + transition: none + } +} + +.dropdown, .dropend, .dropstart, .dropup { + position: relative +} + +.dropdown-toggle { + white-space: nowrap +} + + .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid; + border-right: .3em solid transparent; + border-bottom: 0; + border-left: .3em solid transparent + } + + .dropdown-toggle:empty::after { + margin-left: 0 + } + +.dropdown-menu { + position: absolute; + z-index: 1000; + display: none; + min-width: 10rem; + padding: .5rem 0; + margin: 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0,0,0,.15); + border-radius: .25rem +} + + .dropdown-menu[data-bs-popper] { + top: 100%; + left: 0; + margin-top: .125rem + } + +.dropdown-menu-start { + --bs-position: start +} + + .dropdown-menu-start[data-bs-popper] { + right: auto; + left: 0 + } + +.dropdown-menu-end { + --bs-position: end +} + + .dropdown-menu-end[data-bs-popper] { + right: 0; + left: auto + } + +@media (min-width:576px) { + .dropdown-menu-sm-start { + --bs-position: start + } + + .dropdown-menu-sm-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-sm-end { + --bs-position: end + } + + .dropdown-menu-sm-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width:768px) { + .dropdown-menu-md-start { + --bs-position: start + } + + .dropdown-menu-md-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-md-end { + --bs-position: end + } + + .dropdown-menu-md-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width:992px) { + .dropdown-menu-lg-start { + --bs-position: start + } + + .dropdown-menu-lg-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-lg-end { + --bs-position: end + } + + .dropdown-menu-lg-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width:1200px) { + .dropdown-menu-xl-start { + --bs-position: start + } + + .dropdown-menu-xl-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-xl-end { + --bs-position: end + } + + .dropdown-menu-xl-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width:1400px) { + .dropdown-menu-xxl-start { + --bs-position: start + } + + .dropdown-menu-xxl-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-xxl-end { + --bs-position: end + } + + .dropdown-menu-xxl-end[data-bs-popper] { + right: 0; + left: auto + } +} + +.dropup .dropdown-menu[data-bs-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: .125rem +} + +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: 0; + border-right: .3em solid transparent; + border-bottom: .3em solid; + border-left: .3em solid transparent +} + +.dropup .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropend .dropdown-menu[data-bs-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: .125rem +} + +.dropend .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: 0; + border-bottom: .3em solid transparent; + border-left: .3em solid +} + +.dropend .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropend .dropdown-toggle::after { + vertical-align: 0 +} + +.dropstart .dropdown-menu[data-bs-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: .125rem +} + +.dropstart .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: "" +} + +.dropstart .dropdown-toggle::after { + display: none +} + +.dropstart .dropdown-toggle::before { + display: inline-block; + margin-right: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: .3em solid; + border-bottom: .3em solid transparent +} + +.dropstart .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropstart .dropdown-toggle::before { + vertical-align: 0 +} + +.dropdown-divider { + height: 0; + margin: .5rem 0; + overflow: hidden; + border-top: 1px solid rgba(0,0,0,.15) +} + +.dropdown-item { + display: block; + width: 100%; + padding: .25rem 1rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border: 0 +} + + .dropdown-item:focus, .dropdown-item:hover { + color: #1e2125; + background-color: #e9ecef + } + + .dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #0d6efd + } + + .dropdown-item.disabled, .dropdown-item:disabled { + color: #adb5bd; + pointer-events: none; + background-color: transparent + } + +.dropdown-menu.show { + display: block +} + +.dropdown-header { + display: block; + padding: .5rem 1rem; + margin-bottom: 0; + font-size: .875rem; + color: #6c757d; + white-space: nowrap +} + +.dropdown-item-text { + display: block; + padding: .25rem 1rem; + color: #212529 +} + +.dropdown-menu-dark { + color: #dee2e6; + background-color: #343a40; + border-color: rgba(0,0,0,.15) +} + + .dropdown-menu-dark .dropdown-item { + color: #dee2e6 + } + + .dropdown-menu-dark .dropdown-item:focus, .dropdown-menu-dark .dropdown-item:hover { + color: #fff; + background-color: rgba(255,255,255,.15) + } + + .dropdown-menu-dark .dropdown-item.active, .dropdown-menu-dark .dropdown-item:active { + color: #fff; + background-color: #0d6efd + } + + .dropdown-menu-dark .dropdown-item.disabled, .dropdown-menu-dark .dropdown-item:disabled { + color: #adb5bd + } + + .dropdown-menu-dark .dropdown-divider { + border-color: rgba(0,0,0,.15) + } + + .dropdown-menu-dark .dropdown-item-text { + color: #dee2e6 + } + + .dropdown-menu-dark .dropdown-header { + color: #adb5bd + } + +.btn-group, .btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle +} + + .btn-group-vertical > .btn, .btn-group > .btn { + position: relative; + flex: 1 1 auto + } + + .btn-group-vertical > .btn-check:checked + .btn, .btn-group-vertical > .btn-check:focus + .btn, .btn-group-vertical > .btn.active, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn:focus, .btn-group-vertical > .btn:hover, .btn-group > .btn-check:checked + .btn, .btn-group > .btn-check:focus + .btn, .btn-group > .btn.active, .btn-group > .btn:active, .btn-group > .btn:focus, .btn-group > .btn:hover { + z-index: 1 + } + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start +} + + .btn-toolbar .input-group { + width: auto + } + +.btn-group > .btn-group:not(:first-child), .btn-group > .btn:not(:first-child) { + margin-left: -1px +} + +.btn-group > .btn-group:not(:last-child) > .btn, .btn-group > .btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.btn-group > .btn-group:not(:first-child) > .btn, .btn-group > .btn:nth-child(n+3), .btn-group > :not(.btn-check) + .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.dropdown-toggle-split { + padding-right: .5625rem; + padding-left: .5625rem +} + + .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after { + margin-left: 0 + } + +.dropstart .dropdown-toggle-split::before { + margin-right: 0 +} + +.btn-group-sm > .btn + .dropdown-toggle-split, .btn-sm + .dropdown-toggle-split { + padding-right: .375rem; + padding-left: .375rem +} + +.btn-group-lg > .btn + .dropdown-toggle-split, .btn-lg + .dropdown-toggle-split { + padding-right: .75rem; + padding-left: .75rem +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center +} + + .btn-group-vertical > .btn, .btn-group-vertical > .btn-group { + width: 100% + } + + .btn-group-vertical > .btn-group:not(:first-child), .btn-group-vertical > .btn:not(:first-child) { + margin-top: -1px + } + + .btn-group-vertical > .btn-group:not(:last-child) > .btn, .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 + } + + .btn-group-vertical > .btn-group:not(:first-child) > .btn, .btn-group-vertical > .btn ~ .btn { + border-top-left-radius: 0; + border-top-right-radius: 0 + } + +.nav { + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.nav-link { + display: block; + padding: .5rem 1rem; + color: #0d6efd; + text-decoration: none; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .nav-link { + transition: none + } +} + +.nav-link:focus, .nav-link:hover { + color: #0a58ca +} + +.nav-link.disabled { + color: #6c757d; + pointer-events: none; + cursor: default +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6 +} + + .nav-tabs .nav-link { + margin-bottom: -1px; + background: 0 0; + border: 1px solid transparent; + border-top-left-radius: .25rem; + border-top-right-radius: .25rem + } + + .nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { + border-color: #e9ecef #e9ecef #dee2e6; + isolation: isolate + } + + .nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent + } + + .nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff + } + + .nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0 + } + +.nav-pills .nav-link { + background: 0 0; + border: 0; + border-radius: .25rem +} + + .nav-pills .nav-link.active, .nav-pills .show > .nav-link { + color: #fff; + background-color: #0d6efd + } + +.nav-fill .nav-item, .nav-fill > .nav-link { + flex: 1 1 auto; + text-align: center +} + +.nav-justified .nav-item, .nav-justified > .nav-link { + flex-basis: 0; + flex-grow: 1; + text-align: center +} + + .nav-fill .nav-item .nav-link, .nav-justified .nav-item .nav-link { + width: 100% + } + +.tab-content > .tab-pane { + display: none +} + +.tab-content > .active { + display: block +} + +.navbar { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding-top: .5rem; + padding-bottom: .5rem +} + + .navbar > .container, .navbar > .container-fluid, .navbar > .container-lg, .navbar > .container-md, .navbar > .container-sm, .navbar > .container-xl, .navbar > .container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between + } + +.navbar-brand { + padding-top: .3125rem; + padding-bottom: .3125rem; + margin-right: 1rem; + font-size: 1.25rem; + text-decoration: none; + white-space: nowrap +} + +.navbar-nav { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + + .navbar-nav .nav-link { + padding-right: 0; + padding-left: 0 + } + + .navbar-nav .dropdown-menu { + position: static + } + +.navbar-text { + padding-top: .5rem; + padding-bottom: .5rem +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center +} + +.navbar-toggler { + padding: .25rem .75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: .25rem; + transition: box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .navbar-toggler { + transition: none + } +} + +.navbar-toggler:hover { + text-decoration: none +} + +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 .25rem +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + background-repeat: no-repeat; + background-position: center; + background-size: 100% +} + +.navbar-nav-scroll { + max-height: var(--bs-scroll-height,75vh); + overflow-y: auto +} + +@media (min-width:576px) { + .navbar-expand-sm { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-sm .navbar-nav { + flex-direction: row + } + + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-sm .navbar-toggler { + display: none + } + + .navbar-expand-sm .offcanvas-header { + display: none + } + + .navbar-expand-sm .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none + } + + .navbar-expand-sm .offcanvas-bottom, .navbar-expand-sm .offcanvas-top { + height: auto; + border-top: 0; + border-bottom: 0 + } + + .navbar-expand-sm .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media (min-width:768px) { + .navbar-expand-md { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-md .navbar-nav { + flex-direction: row + } + + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-md .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-md .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-md .navbar-toggler { + display: none + } + + .navbar-expand-md .offcanvas-header { + display: none + } + + .navbar-expand-md .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none + } + + .navbar-expand-md .offcanvas-bottom, .navbar-expand-md .offcanvas-top { + height: auto; + border-top: 0; + border-bottom: 0 + } + + .navbar-expand-md .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media (min-width:992px) { + .navbar-expand-lg { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-lg .navbar-nav { + flex-direction: row + } + + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-lg .navbar-toggler { + display: none + } + + .navbar-expand-lg .offcanvas-header { + display: none + } + + .navbar-expand-lg .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none + } + + .navbar-expand-lg .offcanvas-bottom, .navbar-expand-lg .offcanvas-top { + height: auto; + border-top: 0; + border-bottom: 0 + } + + .navbar-expand-lg .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media (min-width:1200px) { + .navbar-expand-xl { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-xl .navbar-nav { + flex-direction: row + } + + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-xl .navbar-toggler { + display: none + } + + .navbar-expand-xl .offcanvas-header { + display: none + } + + .navbar-expand-xl .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none + } + + .navbar-expand-xl .offcanvas-bottom, .navbar-expand-xl .offcanvas-top { + height: auto; + border-top: 0; + border-bottom: 0 + } + + .navbar-expand-xl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media (min-width:1400px) { + .navbar-expand-xxl { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-xxl .navbar-nav { + flex-direction: row + } + + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-xxl .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-xxl .navbar-toggler { + display: none + } + + .navbar-expand-xxl .offcanvas-header { + display: none + } + + .navbar-expand-xxl .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none + } + + .navbar-expand-xxl .offcanvas-bottom, .navbar-expand-xxl .offcanvas-top { + height: auto; + border-top: 0; + border-bottom: 0 + } + + .navbar-expand-xxl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start +} + + .navbar-expand .navbar-nav { + flex-direction: row + } + + .navbar-expand .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + + .navbar-expand .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand .navbar-toggler { + display: none + } + + .navbar-expand .offcanvas-header { + display: none + } + + .navbar-expand .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none + } + + .navbar-expand .offcanvas-bottom, .navbar-expand .offcanvas-top { + height: auto; + border-top: 0; + border-bottom: 0 + } + + .navbar-expand .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } + +.navbar-light .navbar-brand { + color: rgba(0,0,0,.9) +} + + .navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover { + color: rgba(0,0,0,.9) + } + +.navbar-light .navbar-nav .nav-link { + color: rgba(0,0,0,.55) +} + + .navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { + color: rgba(0,0,0,.7) + } + + .navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0,0,0,.3) + } + + .navbar-light .navbar-nav .nav-link.active, .navbar-light .navbar-nav .show > .nav-link { + color: rgba(0,0,0,.9) + } + +.navbar-light .navbar-toggler { + color: rgba(0,0,0,.55); + border-color: rgba(0,0,0,.1) +} + +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") +} + +.navbar-light .navbar-text { + color: rgba(0,0,0,.55) +} + + .navbar-light .navbar-text a, .navbar-light .navbar-text a:focus, .navbar-light .navbar-text a:hover { + color: rgba(0,0,0,.9) + } + +.navbar-dark .navbar-brand { + color: #fff +} + + .navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover { + color: #fff + } + +.navbar-dark .navbar-nav .nav-link { + color: rgba(255,255,255,.55) +} + + .navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover { + color: rgba(255,255,255,.75) + } + + .navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255,255,255,.25) + } + + .navbar-dark .navbar-nav .nav-link.active, .navbar-dark .navbar-nav .show > .nav-link { + color: #fff + } + +.navbar-dark .navbar-toggler { + color: rgba(255,255,255,.55); + border-color: rgba(255,255,255,.1) +} + +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") +} + +.navbar-dark .navbar-text { + color: rgba(255,255,255,.55) +} + + .navbar-dark .navbar-text a, .navbar-dark .navbar-text a:focus, .navbar-dark .navbar-text a:hover { + color: #fff + } + +.card { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0,0,0,.125); + border-radius: .25rem +} + + .card > hr { + margin-right: 0; + margin-left: 0 + } + + .card > .list-group { + border-top: inherit; + border-bottom: inherit + } + + .card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) + } + + .card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: calc(.25rem - 1px); + border-bottom-left-radius: calc(.25rem - 1px) + } + + .card > .card-header + .list-group, .card > .list-group + .card-footer { + border-top: 0 + } + +.card-body { + flex: 1 1 auto; + padding: 1rem 1rem +} + +.card-title { + margin-bottom: .5rem +} + +.card-subtitle { + margin-top: -.25rem; + margin-bottom: 0 +} + +.card-text:last-child { + margin-bottom: 0 +} + +.card-link + .card-link { + margin-left: 1rem +} + +.card-header { + padding: .5rem 1rem; + margin-bottom: 0; + background-color: rgba(0,0,0,.03); + border-bottom: 1px solid rgba(0,0,0,.125) +} + + .card-header:first-child { + border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0 + } + +.card-footer { + padding: .5rem 1rem; + background-color: rgba(0,0,0,.03); + border-top: 1px solid rgba(0,0,0,.125) +} + + .card-footer:last-child { + border-radius: 0 0 calc(.25rem - 1px) calc(.25rem - 1px) + } + +.card-header-tabs { + margin-right: -.5rem; + margin-bottom: -.5rem; + margin-left: -.5rem; + border-bottom: 0 +} + +.card-header-pills { + margin-right: -.5rem; + margin-left: -.5rem +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1rem; + border-radius: calc(.25rem - 1px) +} + +.card-img, .card-img-bottom, .card-img-top { + width: 100% +} + +.card-img, .card-img-top { + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) +} + +.card-img, .card-img-bottom { + border-bottom-right-radius: calc(.25rem - 1px); + border-bottom-left-radius: calc(.25rem - 1px) +} + +.card-group > .card { + margin-bottom: .75rem +} + +@media (min-width:576px) { + .card-group { + display: flex; + flex-flow: row wrap + } + + .card-group > .card { + flex: 1 0 0%; + margin-bottom: 0 + } + + .card-group > .card + .card { + margin-left: 0; + border-left: 0 + } + + .card-group > .card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 + } + + .card-group > .card:not(:last-child) .card-header, .card-group > .card:not(:last-child) .card-img-top { + border-top-right-radius: 0 + } + + .card-group > .card:not(:last-child) .card-footer, .card-group > .card:not(:last-child) .card-img-bottom { + border-bottom-right-radius: 0 + } + + .card-group > .card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0 + } + + .card-group > .card:not(:first-child) .card-header, .card-group > .card:not(:first-child) .card-img-top { + border-top-left-radius: 0 + } + + .card-group > .card:not(:first-child) .card-footer, .card-group > .card:not(:first-child) .card-img-bottom { + border-bottom-left-radius: 0 + } +} + +.accordion-button { + position: relative; + display: flex; + align-items: center; + width: 100%; + padding: 1rem 1.25rem; + font-size: 1rem; + color: #212529; + text-align: left; + background-color: #fff; + border: 0; + border-radius: 0; + overflow-anchor: none; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease +} + +@media (prefers-reduced-motion:reduce) { + .accordion-button { + transition: none + } +} + +.accordion-button:not(.collapsed) { + color: #0c63e4; + background-color: #e7f1ff; + box-shadow: inset 0 -1px 0 rgba(0,0,0,.125) +} + + .accordion-button:not(.collapsed)::after { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + transform: rotate(-180deg) + } + +.accordion-button::after { + flex-shrink: 0; + width: 1.25rem; + height: 1.25rem; + margin-left: auto; + content: ""; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-size: 1.25rem; + transition: transform .2s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .accordion-button::after { + transition: none + } +} + +.accordion-button:hover { + z-index: 2 +} + +.accordion-button:focus { + z-index: 3; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13,110,253,.25) +} + +.accordion-header { + margin-bottom: 0 +} + +.accordion-item { + background-color: #fff; + border: 1px solid rgba(0,0,0,.125) +} + + .accordion-item:first-of-type { + border-top-left-radius: .25rem; + border-top-right-radius: .25rem + } + + .accordion-item:first-of-type .accordion-button { + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) + } + + .accordion-item:not(:first-of-type) { + border-top: 0 + } + + .accordion-item:last-of-type { + border-bottom-right-radius: .25rem; + border-bottom-left-radius: .25rem + } + + .accordion-item:last-of-type .accordion-button.collapsed { + border-bottom-right-radius: calc(.25rem - 1px); + border-bottom-left-radius: calc(.25rem - 1px) + } + + .accordion-item:last-of-type .accordion-collapse { + border-bottom-right-radius: .25rem; + border-bottom-left-radius: .25rem + } + +.accordion-body { + padding: 1rem 1.25rem +} + +.accordion-flush .accordion-collapse { + border-width: 0 +} + +.accordion-flush .accordion-item { + border-right: 0; + border-left: 0; + border-radius: 0 +} + + .accordion-flush .accordion-item:first-child { + border-top: 0 + } + + .accordion-flush .accordion-item:last-child { + border-bottom: 0 + } + + .accordion-flush .accordion-item .accordion-button { + border-radius: 0 + } + +.breadcrumb { + display: flex; + flex-wrap: wrap; + padding: 0 0; + margin-bottom: 1rem; + list-style: none +} + +.breadcrumb-item + .breadcrumb-item { + padding-left: .5rem +} + + .breadcrumb-item + .breadcrumb-item::before { + float: left; + padding-right: .5rem; + color: #6c757d; + content: var(--bs-breadcrumb-divider, "/") + } + +.breadcrumb-item.active { + color: #6c757d +} + +.pagination { + display: flex; + padding-left: 0; + list-style: none +} + +.page-link { + position: relative; + display: block; + color: #0d6efd; + text-decoration: none; + background-color: #fff; + border: 1px solid #dee2e6; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .page-link { + transition: none + } +} + +.page-link:hover { + z-index: 2; + color: #0a58ca; + background-color: #e9ecef; + border-color: #dee2e6 +} + +.page-link:focus { + z-index: 3; + color: #0a58ca; + background-color: #e9ecef; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13,110,253,.25) +} + +.page-item:not(:first-child) .page-link { + margin-left: -1px +} + +.page-item.active .page-link { + z-index: 3; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd +} + +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + background-color: #fff; + border-color: #dee2e6 +} + +.page-link { + padding: .375rem .75rem +} + +.page-item:first-child .page-link { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem +} + +.page-item:last-child .page-link { + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem +} + +.pagination-lg .page-link { + padding: .75rem 1.5rem; + font-size: 1.25rem +} + +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: .3rem; + border-bottom-left-radius: .3rem +} + +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: .3rem; + border-bottom-right-radius: .3rem +} + +.pagination-sm .page-link { + padding: .25rem .5rem; + font-size: .875rem +} + +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: .2rem; + border-bottom-left-radius: .2rem +} + +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: .2rem; + border-bottom-right-radius: .2rem +} + +.badge { + display: inline-block; + padding: .35em .65em; + font-size: .75em; + font-weight: 700; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25rem +} + + .badge:empty { + display: none + } + +.btn .badge { + position: relative; + top: -1px +} + +.alert { + position: relative; + padding: 1rem 1rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: .25rem +} + +.alert-heading { + color: inherit +} + +.alert-link { + font-weight: 700 +} + +.alert-dismissible { + padding-right: 3rem +} + + .alert-dismissible .btn-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 1.25rem 1rem + } + +.alert-primary { + color: #084298; + background-color: #cfe2ff; + border-color: #b6d4fe +} + + .alert-primary .alert-link { + color: #06357a + } + +.alert-secondary { + color: #41464b; + background-color: #e2e3e5; + border-color: #d3d6d8 +} + + .alert-secondary .alert-link { + color: #34383c + } + +.alert-success { + color: #0f5132; + background-color: #d1e7dd; + border-color: #badbcc +} + + .alert-success .alert-link { + color: #0c4128 + } + +.alert-info { + color: #055160; + background-color: #cff4fc; + border-color: #b6effb +} + + .alert-info .alert-link { + color: #04414d + } + +.alert-warning { + color: #664d03; + background-color: #fff3cd; + border-color: #ffecb5 +} + + .alert-warning .alert-link { + color: #523e02 + } + +.alert-danger { + color: #842029; + background-color: #f8d7da; + border-color: #f5c2c7 +} + + .alert-danger .alert-link { + color: #6a1a21 + } + +.alert-light { + color: #636464; + background-color: #fefefe; + border-color: #fdfdfe +} + + .alert-light .alert-link { + color: #4f5050 + } + +.alert-dark { + color: #141619; + background-color: #d3d3d4; + border-color: #bcbebf +} + + .alert-dark .alert-link { + color: #101214 + } + +@-webkit-keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem + } +} + +@keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem + } +} + +.progress { + display: flex; + height: 1rem; + overflow: hidden; + font-size: .75rem; + background-color: #e9ecef; + border-radius: .25rem +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; + background-color: #0d6efd; + transition: width .6s ease +} + +@media (prefers-reduced-motion:reduce) { + .progress-bar { + transition: none + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent); + background-size: 1rem 1rem +} + +.progress-bar-animated { + -webkit-animation: 1s linear infinite progress-bar-stripes; + animation: 1s linear infinite progress-bar-stripes +} + +@media (prefers-reduced-motion:reduce) { + .progress-bar-animated { + -webkit-animation: none; + animation: none + } +} + +.list-group { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: .25rem +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section +} + + .list-group-numbered > li::before { + content: counters(section, ".") ". "; + counter-increment: section + } + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit +} + + .list-group-item-action:focus, .list-group-item-action:hover { + z-index: 1; + color: #495057; + text-decoration: none; + background-color: #f8f9fa + } + + .list-group-item-action:active { + color: #212529; + background-color: #e9ecef + } + +.list-group-item { + position: relative; + display: block; + padding: .5rem 1rem; + color: #212529; + text-decoration: none; + background-color: #fff; + border: 1px solid rgba(0,0,0,.125) +} + + .list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit + } + + .list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit + } + + .list-group-item.disabled, .list-group-item:disabled { + color: #6c757d; + pointer-events: none; + background-color: #fff + } + + .list-group-item.active { + z-index: 2; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd + } + + .list-group-item + .list-group-item { + border-top-width: 0 + } + + .list-group-item + .list-group-item.active { + margin-top: -1px; + border-top-width: 1px + } + +.list-group-horizontal { + flex-direction: row +} + + .list-group-horizontal > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } + +@media (min-width:576px) { + .list-group-horizontal-sm { + flex-direction: row + } + + .list-group-horizontal-sm > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-sm > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +@media (min-width:768px) { + .list-group-horizontal-md { + flex-direction: row + } + + .list-group-horizontal-md > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-md > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +@media (min-width:992px) { + .list-group-horizontal-lg { + flex-direction: row + } + + .list-group-horizontal-lg > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-lg > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +@media (min-width:1200px) { + .list-group-horizontal-xl { + flex-direction: row + } + + .list-group-horizontal-xl > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-xl > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +@media (min-width:1400px) { + .list-group-horizontal-xxl { + flex-direction: row + } + + .list-group-horizontal-xxl > .list-group-item:first-child { + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + + .list-group-horizontal-xxl > .list-group-item:last-child { + border-top-right-radius: .25rem; + border-bottom-left-radius: 0 + } + + .list-group-horizontal-xxl > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-xxl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0 + } + + .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px + } +} + +.list-group-flush { + border-radius: 0 +} + + .list-group-flush > .list-group-item { + border-width: 0 0 1px + } + + .list-group-flush > .list-group-item:last-child { + border-bottom-width: 0 + } + +.list-group-item-primary { + color: #084298; + background-color: #cfe2ff +} + + .list-group-item-primary.list-group-item-action:focus, .list-group-item-primary.list-group-item-action:hover { + color: #084298; + background-color: #bacbe6 + } + + .list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #084298; + border-color: #084298 + } + +.list-group-item-secondary { + color: #41464b; + background-color: #e2e3e5 +} + + .list-group-item-secondary.list-group-item-action:focus, .list-group-item-secondary.list-group-item-action:hover { + color: #41464b; + background-color: #cbccce + } + + .list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #41464b; + border-color: #41464b + } + +.list-group-item-success { + color: #0f5132; + background-color: #d1e7dd +} + + .list-group-item-success.list-group-item-action:focus, .list-group-item-success.list-group-item-action:hover { + color: #0f5132; + background-color: #bcd0c7 + } + + .list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #0f5132; + border-color: #0f5132 + } + +.list-group-item-info { + color: #055160; + background-color: #cff4fc +} + + .list-group-item-info.list-group-item-action:focus, .list-group-item-info.list-group-item-action:hover { + color: #055160; + background-color: #badce3 + } + + .list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #055160; + border-color: #055160 + } + +.list-group-item-warning { + color: #664d03; + background-color: #fff3cd +} + + .list-group-item-warning.list-group-item-action:focus, .list-group-item-warning.list-group-item-action:hover { + color: #664d03; + background-color: #e6dbb9 + } + + .list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #664d03; + border-color: #664d03 + } + +.list-group-item-danger { + color: #842029; + background-color: #f8d7da +} + + .list-group-item-danger.list-group-item-action:focus, .list-group-item-danger.list-group-item-action:hover { + color: #842029; + background-color: #dfc2c4 + } + + .list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #842029; + border-color: #842029 + } + +.list-group-item-light { + color: #636464; + background-color: #fefefe +} + + .list-group-item-light.list-group-item-action:focus, .list-group-item-light.list-group-item-action:hover { + color: #636464; + background-color: #e5e5e5 + } + + .list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #636464; + border-color: #636464 + } + +.list-group-item-dark { + color: #141619; + background-color: #d3d3d4 +} + + .list-group-item-dark.list-group-item-action:focus, .list-group-item-dark.list-group-item-action:hover { + color: #141619; + background-color: #bebebf + } + + .list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #141619; + border-color: #141619 + } + +.btn-close { + box-sizing: content-box; + width: 1em; + height: 1em; + padding: .25em .25em; + color: #000; + background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; + border: 0; + border-radius: .25rem; + opacity: .5 +} + + .btn-close:hover { + color: #000; + text-decoration: none; + opacity: .75 + } + + .btn-close:focus { + outline: 0; + box-shadow: 0 0 0 .25rem rgba(13,110,253,.25); + opacity: 1 + } + + .btn-close.disabled, .btn-close:disabled { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + opacity: .25 + } + +.btn-close-white { + filter: invert(1) grayscale(100%) brightness(200%) +} + +.toast { + width: 350px; + max-width: 100%; + font-size: .875rem; + pointer-events: auto; + background-color: rgba(255,255,255,.85); + background-clip: padding-box; + border: 1px solid rgba(0,0,0,.1); + box-shadow: 0 .5rem 1rem rgba(0,0,0,.15); + border-radius: .25rem +} + + .toast.showing { + opacity: 0 + } + + .toast:not(.show) { + display: none + } + +.toast-container { + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + max-width: 100%; + pointer-events: none +} + + .toast-container > :not(:last-child) { + margin-bottom: .75rem + } + +.toast-header { + display: flex; + align-items: center; + padding: .5rem .75rem; + color: #6c757d; + background-color: rgba(255,255,255,.85); + background-clip: padding-box; + border-bottom: 1px solid rgba(0,0,0,.05); + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) +} + + .toast-header .btn-close { + margin-right: -.375rem; + margin-left: .75rem + } + +.toast-body { + padding: .75rem; + word-wrap: break-word +} + +.modal { + position: fixed; + top: 0; + left: 0; + z-index: 1055; + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0 +} + +.modal-dialog { + position: relative; + width: auto; + margin: .5rem; + pointer-events: none +} + +.modal.fade .modal-dialog { + transition: transform .3s ease-out; + transform: translate(0,-50px) +} + +@media (prefers-reduced-motion:reduce) { + .modal.fade .modal-dialog { + transition: none + } +} + +.modal.show .modal-dialog { + transform: none +} + +.modal.modal-static .modal-dialog { + transform: scale(1.02) +} + +.modal-dialog-scrollable { + height: calc(100% - 1rem) +} + + .modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden + } + + .modal-dialog-scrollable .modal-body { + overflow-y: auto + } + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - 1rem) +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0,0,0,.2); + border-radius: .3rem; + outline: 0 +} + +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1050; + width: 100vw; + height: 100vh; + background-color: #000 +} + + .modal-backdrop.fade { + opacity: 0 + } + + .modal-backdrop.show { + opacity: .5 + } + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem; + border-bottom: 1px solid #dee2e6; + border-top-left-radius: calc(.3rem - 1px); + border-top-right-radius: calc(.3rem - 1px) +} + + .modal-header .btn-close { + padding: .5rem .5rem; + margin: -.5rem -.5rem -.5rem auto + } + +.modal-title { + margin-bottom: 0; + line-height: 1.5 +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: 1rem +} + +.modal-footer { + display: flex; + flex-wrap: wrap; + flex-shrink: 0; + align-items: center; + justify-content: flex-end; + padding: .75rem; + border-top: 1px solid #dee2e6; + border-bottom-right-radius: calc(.3rem - 1px); + border-bottom-left-radius: calc(.3rem - 1px) +} + + .modal-footer > * { + margin: .25rem + } + +@media (min-width:576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto + } + + .modal-dialog-scrollable { + height: calc(100% - 3.5rem) + } + + .modal-dialog-centered { + min-height: calc(100% - 3.5rem) + } + + .modal-sm { + max-width: 300px + } +} + +@media (min-width:992px) { + .modal-lg, .modal-xl { + max-width: 800px + } +} + +@media (min-width:1200px) { + .modal-xl { + max-width: 1140px + } +} + +.modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 +} + + .modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen .modal-header { + border-radius: 0 + } + + .modal-fullscreen .modal-body { + overflow-y: auto + } + + .modal-fullscreen .modal-footer { + border-radius: 0 + } + +@media (max-width:575.98px) { + .modal-fullscreen-sm-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-sm-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-sm-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-sm-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-sm-down .modal-footer { + border-radius: 0 + } +} + +@media (max-width:767.98px) { + .modal-fullscreen-md-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-md-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-md-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-md-down .modal-footer { + border-radius: 0 + } +} + +@media (max-width:991.98px) { + .modal-fullscreen-lg-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-lg-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-lg-down .modal-footer { + border-radius: 0 + } +} + +@media (max-width:1199.98px) { + .modal-fullscreen-xl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-xl-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-xl-down .modal-footer { + border-radius: 0 + } +} + +@media (max-width:1399.98px) { + .modal-fullscreen-xxl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-xxl-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto + } + + .modal-fullscreen-xxl-down .modal-footer { + border-radius: 0 + } +} + +.tooltip { + position: absolute; + z-index: 1080; + display: block; + margin: 0; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: .875rem; + word-wrap: break-word; + opacity: 0 +} + + .tooltip.show { + opacity: .9 + } + + .tooltip .tooltip-arrow { + position: absolute; + display: block; + width: .8rem; + height: .4rem + } + + .tooltip .tooltip-arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid + } + +.bs-tooltip-auto[data-popper-placement^=top], .bs-tooltip-top { + padding: .4rem 0 +} + + .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow, .bs-tooltip-top .tooltip-arrow { + bottom: 0 + } + + .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before, .bs-tooltip-top .tooltip-arrow::before { + top: -1px; + border-width: .4rem .4rem 0; + border-top-color: #000 + } + +.bs-tooltip-auto[data-popper-placement^=right], .bs-tooltip-end { + padding: 0 .4rem +} + + .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow, .bs-tooltip-end .tooltip-arrow { + left: 0; + width: .4rem; + height: .8rem + } + + .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before, .bs-tooltip-end .tooltip-arrow::before { + right: -1px; + border-width: .4rem .4rem .4rem 0; + border-right-color: #000 + } + +.bs-tooltip-auto[data-popper-placement^=bottom], .bs-tooltip-bottom { + padding: .4rem 0 +} + + .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow, .bs-tooltip-bottom .tooltip-arrow { + top: 0 + } + + .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before, .bs-tooltip-bottom .tooltip-arrow::before { + bottom: -1px; + border-width: 0 .4rem .4rem; + border-bottom-color: #000 + } + +.bs-tooltip-auto[data-popper-placement^=left], .bs-tooltip-start { + padding: 0 .4rem +} + + .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow, .bs-tooltip-start .tooltip-arrow { + right: 0; + width: .4rem; + height: .8rem + } + + .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before, .bs-tooltip-start .tooltip-arrow::before { + left: -1px; + border-width: .4rem 0 .4rem .4rem; + border-left-color: #000 + } + +.tooltip-inner { + max-width: 200px; + padding: .25rem .5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: .25rem +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1070; + display: block; + max-width: 276px; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: .875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0,0,0,.2); + border-radius: .3rem +} + + .popover .popover-arrow { + position: absolute; + display: block; + width: 1rem; + height: .5rem + } + + .popover .popover-arrow::after, .popover .popover-arrow::before { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid + } + +.bs-popover-auto[data-popper-placement^=top] > .popover-arrow, .bs-popover-top > .popover-arrow { + bottom: calc(-.5rem - 1px) +} + + .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::before { + bottom: 0; + border-width: .5rem .5rem 0; + border-top-color: rgba(0,0,0,.25) + } + + .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after, .bs-popover-top > .popover-arrow::after { + bottom: 1px; + border-width: .5rem .5rem 0; + border-top-color: #fff + } + +.bs-popover-auto[data-popper-placement^=right] > .popover-arrow, .bs-popover-end > .popover-arrow { + left: calc(-.5rem - 1px); + width: .5rem; + height: 1rem +} + + .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::before { + left: 0; + border-width: .5rem .5rem .5rem 0; + border-right-color: rgba(0,0,0,.25) + } + + .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after, .bs-popover-end > .popover-arrow::after { + left: 1px; + border-width: .5rem .5rem .5rem 0; + border-right-color: #fff + } + +.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow, .bs-popover-bottom > .popover-arrow { + top: calc(-.5rem - 1px) +} + + .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::before { + top: 0; + border-width: 0 .5rem .5rem .5rem; + border-bottom-color: rgba(0,0,0,.25) + } + + .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after, .bs-popover-bottom > .popover-arrow::after { + top: 1px; + border-width: 0 .5rem .5rem .5rem; + border-bottom-color: #fff + } + +.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before, .bs-popover-bottom .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -.5rem; + content: ""; + border-bottom: 1px solid #f0f0f0 +} + +.bs-popover-auto[data-popper-placement^=left] > .popover-arrow, .bs-popover-start > .popover-arrow { + right: calc(-.5rem - 1px); + width: .5rem; + height: 1rem +} + + .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::before { + right: 0; + border-width: .5rem 0 .5rem .5rem; + border-left-color: rgba(0,0,0,.25) + } + + .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after, .bs-popover-start > .popover-arrow::after { + right: 1px; + border-width: .5rem 0 .5rem .5rem; + border-left-color: #fff + } + +.popover-header { + padding: .5rem 1rem; + margin-bottom: 0; + font-size: 1rem; + background-color: #f0f0f0; + border-bottom: 1px solid rgba(0,0,0,.2); + border-top-left-radius: calc(.3rem - 1px); + border-top-right-radius: calc(.3rem - 1px) +} + + .popover-header:empty { + display: none + } + +.popover-body { + padding: 1rem 1rem; + color: #212529 +} + +.carousel { + position: relative +} + + .carousel.pointer-event { + touch-action: pan-y + } + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden +} + + .carousel-inner::after { + display: block; + clear: both; + content: "" + } + +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transition: transform .6s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .carousel-item { + transition: none + } +} + +.carousel-item-next, .carousel-item-prev, .carousel-item.active { + display: block +} + + .active.carousel-item-end, .carousel-item-next:not(.carousel-item-start) { + transform: translateX(100%) + } + + .active.carousel-item-start, .carousel-item-prev:not(.carousel-item-end) { + transform: translateX(-100%) + } + +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + transform: none +} + + .carousel-fade .carousel-item-next.carousel-item-start, .carousel-fade .carousel-item-prev.carousel-item-end, .carousel-fade .carousel-item.active { + z-index: 1; + opacity: 1 + } + +.carousel-fade .active.carousel-item-end, .carousel-fade .active.carousel-item-start { + z-index: 0; + opacity: 0; + transition: opacity 0s .6s +} + +@media (prefers-reduced-motion:reduce) { + .carousel-fade .active.carousel-item-end, .carousel-fade .active.carousel-item-start { + transition: none + } +} + +.carousel-control-next, .carousel-control-prev { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + padding: 0; + color: #fff; + text-align: center; + background: 0 0; + border: 0; + opacity: .5; + transition: opacity .15s ease +} + +@media (prefers-reduced-motion:reduce) { + .carousel-control-next, .carousel-control-prev { + transition: none + } +} + +.carousel-control-next:focus, .carousel-control-next:hover, .carousel-control-prev:focus, .carousel-control-prev:hover { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9 +} + +.carousel-control-prev { + left: 0 +} + +.carousel-control-next { + right: 0 +} + +.carousel-control-next-icon, .carousel-control-prev-icon { + display: inline-block; + width: 2rem; + height: 2rem; + background-repeat: no-repeat; + background-position: 50%; + background-size: 100% 100% +} + +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e") +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e") +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + display: flex; + justify-content: center; + padding: 0; + margin-right: 15%; + margin-bottom: 1rem; + margin-left: 15%; + list-style: none +} + + .carousel-indicators [data-bs-target] { + box-sizing: content-box; + flex: 0 1 auto; + width: 30px; + height: 3px; + padding: 0; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: .5; + transition: opacity .6s ease + } + +@media (prefers-reduced-motion:reduce) { + .carousel-indicators [data-bs-target] { + transition: none + } +} + +.carousel-indicators .active { + opacity: 1 +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 1.25rem; + left: 15%; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + color: #fff; + text-align: center +} + +.carousel-dark .carousel-control-next-icon, .carousel-dark .carousel-control-prev-icon { + filter: invert(1) grayscale(100) +} + +.carousel-dark .carousel-indicators [data-bs-target] { + background-color: #000 +} + +.carousel-dark .carousel-caption { + color: #000 +} + +@-webkit-keyframes spinner-border { + to { + transform: rotate(360deg) + } +} + +@keyframes spinner-border { + to { + transform: rotate(360deg) + } +} + +.spinner-border { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: -.125em; + border: .25em solid currentColor; + border-right-color: transparent; + border-radius: 50%; + -webkit-animation: .75s linear infinite spinner-border; + animation: .75s linear infinite spinner-border +} + +.spinner-border-sm { + width: 1rem; + height: 1rem; + border-width: .2em +} + +@-webkit-keyframes spinner-grow { + 0% { + transform: scale(0) + } + + 50% { + opacity: 1; + transform: none + } +} + +@keyframes spinner-grow { + 0% { + transform: scale(0) + } + + 50% { + opacity: 1; + transform: none + } +} + +.spinner-grow { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: -.125em; + background-color: currentColor; + border-radius: 50%; + opacity: 0; + -webkit-animation: .75s linear infinite spinner-grow; + animation: .75s linear infinite spinner-grow +} + +.spinner-grow-sm { + width: 1rem; + height: 1rem +} + +@media (prefers-reduced-motion:reduce) { + .spinner-border, .spinner-grow { + -webkit-animation-duration: 1.5s; + animation-duration: 1.5s + } +} + +.offcanvas { + position: fixed; + bottom: 0; + z-index: 1045; + display: flex; + flex-direction: column; + max-width: 100%; + visibility: hidden; + background-color: #fff; + background-clip: padding-box; + outline: 0; + transition: transform .3s ease-in-out +} + +@media (prefers-reduced-motion:reduce) { + .offcanvas { + transition: none + } +} + +.offcanvas-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000 +} + + .offcanvas-backdrop.fade { + opacity: 0 + } + + .offcanvas-backdrop.show { + opacity: .5 + } + +.offcanvas-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem +} + + .offcanvas-header .btn-close { + padding: .5rem .5rem; + margin-top: -.5rem; + margin-right: -.5rem; + margin-bottom: -.5rem + } + +.offcanvas-title { + margin-bottom: 0; + line-height: 1.5 +} + +.offcanvas-body { + flex-grow: 1; + padding: 1rem 1rem; + overflow-y: auto +} + +.offcanvas-start { + top: 0; + left: 0; + width: 400px; + border-right: 1px solid rgba(0,0,0,.2); + transform: translateX(-100%) +} + +.offcanvas-end { + top: 0; + right: 0; + width: 400px; + border-left: 1px solid rgba(0,0,0,.2); + transform: translateX(100%) +} + +.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: 30vh; + max-height: 100%; + border-bottom: 1px solid rgba(0,0,0,.2); + transform: translateY(-100%) +} + +.offcanvas-bottom { + right: 0; + left: 0; + height: 30vh; + max-height: 100%; + border-top: 1px solid rgba(0,0,0,.2); + transform: translateY(100%) +} + +.offcanvas.show { + transform: none +} + +.placeholder { + display: inline-block; + min-height: 1em; + vertical-align: middle; + cursor: wait; + background-color: currentColor; + opacity: .5 +} + + .placeholder.btn::before { + display: inline-block; + content: "" + } + +.placeholder-xs { + min-height: .6em +} + +.placeholder-sm { + min-height: .8em +} + +.placeholder-lg { + min-height: 1.2em +} + +.placeholder-glow .placeholder { + -webkit-animation: placeholder-glow 2s ease-in-out infinite; + animation: placeholder-glow 2s ease-in-out infinite +} + +@-webkit-keyframes placeholder-glow { + 50% { + opacity: .2 + } +} + +@keyframes placeholder-glow { + 50% { + opacity: .2 + } +} + +.placeholder-wave { + -webkit-mask-image: linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%); + mask-image: linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%); + -webkit-mask-size: 200% 100%; + mask-size: 200% 100%; + -webkit-animation: placeholder-wave 2s linear infinite; + animation: placeholder-wave 2s linear infinite +} + +@-webkit-keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0% + } +} + +@keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0% + } +} + +.clearfix::after { + display: block; + clear: both; + content: "" +} + +.link-primary { + color: #0d6efd +} + + .link-primary:focus, .link-primary:hover { + color: #0a58ca + } + +.link-secondary { + color: #6c757d +} + + .link-secondary:focus, .link-secondary:hover { + color: #565e64 + } + +.link-success { + color: #198754 +} + + .link-success:focus, .link-success:hover { + color: #146c43 + } + +.link-info { + color: #0dcaf0 +} + + .link-info:focus, .link-info:hover { + color: #3dd5f3 + } + +.link-warning { + color: #ffc107 +} + + .link-warning:focus, .link-warning:hover { + color: #ffcd39 + } + +.link-danger { + color: #dc3545 +} + + .link-danger:focus, .link-danger:hover { + color: #b02a37 + } + +.link-light { + color: #f8f9fa +} + + .link-light:focus, .link-light:hover { + color: #f9fafb + } + +.link-dark { + color: #212529 +} + + .link-dark:focus, .link-dark:hover { + color: #1a1e21 + } + +.ratio { + position: relative; + width: 100% +} + + .ratio::before { + display: block; + padding-top: var(--bs-aspect-ratio); + content: "" + } + + .ratio > * { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100% + } + +.ratio-1x1 { + --bs-aspect-ratio: 100% +} + +.ratio-4x3 { + --bs-aspect-ratio: calc(3 / 4 * 100%) +} + +.ratio-16x9 { + --bs-aspect-ratio: calc(9 / 16 * 100%) +} + +.ratio-21x9 { + --bs-aspect-ratio: calc(9 / 21 * 100%) +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030 +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030 +} + +.sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 +} + +@media (min-width:576px) { + .sticky-sm-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +@media (min-width:768px) { + .sticky-md-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +@media (min-width:992px) { + .sticky-lg-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +@media (min-width:1200px) { + .sticky-xl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +@media (min-width:1400px) { + .sticky-xxl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } +} + +.hstack { + display: flex; + flex-direction: row; + align-items: center; + align-self: stretch +} + +.vstack { + display: flex; + flex: 1 1 auto; + flex-direction: column; + align-self: stretch +} + +.visually-hidden, .visually-hidden-focusable:not(:focus):not(:focus-within) { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0,0,0,0) !important; + white-space: nowrap !important; + border: 0 !important +} + +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + content: "" +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.vr { + display: inline-block; + align-self: stretch; + width: 1px; + min-height: 1em; + background-color: currentColor; + opacity: .25 +} + +.align-baseline { + vertical-align: baseline !important +} + +.align-top { + vertical-align: top !important +} + +.align-middle { + vertical-align: middle !important +} + +.align-bottom { + vertical-align: bottom !important +} + +.align-text-bottom { + vertical-align: text-bottom !important +} + +.align-text-top { + vertical-align: text-top !important +} + +.float-start { + float: left !important +} + +.float-end { + float: right !important +} + +.float-none { + float: none !important +} + +.opacity-0 { + opacity: 0 !important +} + +.opacity-25 { + opacity: .25 !important +} + +.opacity-50 { + opacity: .5 !important +} + +.opacity-75 { + opacity: .75 !important +} + +.opacity-100 { + opacity: 1 !important +} + +.overflow-auto { + overflow: auto !important +} + +.overflow-hidden { + overflow: hidden !important +} + +.overflow-visible { + overflow: visible !important +} + +.overflow-scroll { + overflow: scroll !important +} + +.d-inline { + display: inline !important +} + +.d-inline-block { + display: inline-block !important +} + +.d-block { + display: block !important +} + +.d-grid { + display: grid !important +} + +.d-table { + display: table !important +} + +.d-table-row { + display: table-row !important +} + +.d-table-cell { + display: table-cell !important +} + +.d-flex { + display: flex !important +} + +.d-inline-flex { + display: inline-flex !important +} + +.d-none { + display: none !important +} + +.shadow { + box-shadow: 0 .5rem 1rem rgba(0,0,0,.15) !important +} + +.shadow-sm { + box-shadow: 0 .125rem .25rem rgba(0,0,0,.075) !important +} + +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0,0,0,.175) !important +} + +.shadow-none { + box-shadow: none !important +} + +.position-static { + position: static !important +} + +.position-relative { + position: relative !important +} + +.position-absolute { + position: absolute !important +} + +.position-fixed { + position: fixed !important +} + +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important +} + +.top-0 { + top: 0 !important +} + +.top-50 { + top: 50% !important +} + +.top-100 { + top: 100% !important +} + +.bottom-0 { + bottom: 0 !important +} + +.bottom-50 { + bottom: 50% !important +} + +.bottom-100 { + bottom: 100% !important +} + +.start-0 { + left: 0 !important +} + +.start-50 { + left: 50% !important +} + +.start-100 { + left: 100% !important +} + +.end-0 { + right: 0 !important +} + +.end-50 { + right: 50% !important +} + +.end-100 { + right: 100% !important +} + +.translate-middle { + transform: translate(-50%,-50%) !important +} + +.translate-middle-x { + transform: translateX(-50%) !important +} + +.translate-middle-y { + transform: translateY(-50%) !important +} + +.border { + border: 1px solid #dee2e6 !important +} + +.border-0 { + border: 0 !important +} + +.border-top { + border-top: 1px solid #dee2e6 !important +} + +.border-top-0 { + border-top: 0 !important +} + +.border-end { + border-right: 1px solid #dee2e6 !important +} + +.border-end-0 { + border-right: 0 !important +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important +} + +.border-bottom-0 { + border-bottom: 0 !important +} + +.border-start { + border-left: 1px solid #dee2e6 !important +} + +.border-start-0 { + border-left: 0 !important +} + +.border-primary { + border-color: #0d6efd !important +} + +.border-secondary { + border-color: #6c757d !important +} + +.border-success { + border-color: #198754 !important +} + +.border-info { + border-color: #0dcaf0 !important +} + +.border-warning { + border-color: #ffc107 !important +} + +.border-danger { + border-color: #dc3545 !important +} + +.border-light { + border-color: #f8f9fa !important +} + +.border-dark { + border-color: #212529 !important +} + +.border-white { + border-color: #fff !important +} + +.border-1 { + border-width: 1px !important +} + +.border-2 { + border-width: 2px !important +} + +.border-3 { + border-width: 3px !important +} + +.border-4 { + border-width: 4px !important +} + +.border-5 { + border-width: 5px !important +} + +.w-25 { + width: 25% !important +} + +.w-50 { + width: 50% !important +} + +.w-75 { + width: 75% !important +} + +.w-100 { + width: 100% !important +} + +.w-auto { + width: auto !important +} + +.mw-100 { + max-width: 100% !important +} + +.vw-100 { + width: 100vw !important +} + +.min-vw-100 { + min-width: 100vw !important +} + +.h-25 { + height: 25% !important +} + +.h-50 { + height: 50% !important +} + +.h-75 { + height: 75% !important +} + +.h-100 { + height: 100% !important +} + +.h-auto { + height: auto !important +} + +.mh-100 { + max-height: 100% !important +} + +.vh-100 { + height: 100vh !important +} + +.min-vh-100 { + min-height: 100vh !important +} + +.flex-fill { + flex: 1 1 auto !important +} + +.flex-row { + flex-direction: row !important +} + +.flex-column { + flex-direction: column !important +} + +.flex-row-reverse { + flex-direction: row-reverse !important +} + +.flex-column-reverse { + flex-direction: column-reverse !important +} + +.flex-grow-0 { + flex-grow: 0 !important +} + +.flex-grow-1 { + flex-grow: 1 !important +} + +.flex-shrink-0 { + flex-shrink: 0 !important +} + +.flex-shrink-1 { + flex-shrink: 1 !important +} + +.flex-wrap { + flex-wrap: wrap !important +} + +.flex-nowrap { + flex-wrap: nowrap !important +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important +} + +.gap-0 { + gap: 0 !important +} + +.gap-1 { + gap: .25rem !important +} + +.gap-2 { + gap: .5rem !important +} + +.gap-3 { + gap: 1rem !important +} + +.gap-4 { + gap: 1.5rem !important +} + +.gap-5 { + gap: 3rem !important +} + +.justify-content-start { + justify-content: flex-start !important +} + +.justify-content-end { + justify-content: flex-end !important +} + +.justify-content-center { + justify-content: center !important +} + +.justify-content-between { + justify-content: space-between !important +} + +.justify-content-around { + justify-content: space-around !important +} + +.justify-content-evenly { + justify-content: space-evenly !important +} + +.align-items-start { + align-items: flex-start !important +} + +.align-items-end { + align-items: flex-end !important +} + +.align-items-center { + align-items: center !important +} + +.align-items-baseline { + align-items: baseline !important +} + +.align-items-stretch { + align-items: stretch !important +} + +.align-content-start { + align-content: flex-start !important +} + +.align-content-end { + align-content: flex-end !important +} + +.align-content-center { + align-content: center !important +} + +.align-content-between { + align-content: space-between !important +} + +.align-content-around { + align-content: space-around !important +} + +.align-content-stretch { + align-content: stretch !important +} + +.align-self-auto { + align-self: auto !important +} + +.align-self-start { + align-self: flex-start !important +} + +.align-self-end { + align-self: flex-end !important +} + +.align-self-center { + align-self: center !important +} + +.align-self-baseline { + align-self: baseline !important +} + +.align-self-stretch { + align-self: stretch !important +} + +.order-first { + order: -1 !important +} + +.order-0 { + order: 0 !important +} + +.order-1 { + order: 1 !important +} + +.order-2 { + order: 2 !important +} + +.order-3 { + order: 3 !important +} + +.order-4 { + order: 4 !important +} + +.order-5 { + order: 5 !important +} + +.order-last { + order: 6 !important +} + +.m-0 { + margin: 0 !important +} + +.m-1 { + margin: .25rem !important +} + +.m-2 { + margin: .5rem !important +} + +.m-3 { + margin: 1rem !important +} + +.m-4 { + margin: 1.5rem !important +} + +.m-5 { + margin: 3rem !important +} + +.m-auto { + margin: auto !important +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important +} + +.mx-1 { + margin-right: .25rem !important; + margin-left: .25rem !important +} + +.mx-2 { + margin-right: .5rem !important; + margin-left: .5rem !important +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important +} + +.my-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important +} + +.my-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important +} + +.mt-0 { + margin-top: 0 !important +} + +.mt-1 { + margin-top: .25rem !important +} + +.mt-2 { + margin-top: .5rem !important +} + +.mt-3 { + margin-top: 1rem !important +} + +.mt-4 { + margin-top: 1.5rem !important +} + +.mt-5 { + margin-top: 3rem !important +} + +.mt-auto { + margin-top: auto !important +} + +.me-0 { + margin-right: 0 !important +} + +.me-1 { + margin-right: .25rem !important +} + +.me-2 { + margin-right: .5rem !important +} + +.me-3 { + margin-right: 1rem !important +} + +.me-4 { + margin-right: 1.5rem !important +} + +.me-5 { + margin-right: 3rem !important +} + +.me-auto { + margin-right: auto !important +} + +.mb-0 { + margin-bottom: 0 !important +} + +.mb-1 { + margin-bottom: .25rem !important +} + +.mb-2 { + margin-bottom: .5rem !important +} + +.mb-3 { + margin-bottom: 1rem !important +} + +.mb-4 { + margin-bottom: 1.5rem !important +} + +.mb-5 { + margin-bottom: 3rem !important +} + +.mb-auto { + margin-bottom: auto !important +} + +.ms-0 { + margin-left: 0 !important +} + +.ms-1 { + margin-left: .25rem !important +} + +.ms-2 { + margin-left: .5rem !important +} + +.ms-3 { + margin-left: 1rem !important +} + +.ms-4 { + margin-left: 1.5rem !important +} + +.ms-5 { + margin-left: 3rem !important +} + +.ms-auto { + margin-left: auto !important +} + +.p-0 { + padding: 0 !important +} + +.p-1 { + padding: .25rem !important +} + +.p-2 { + padding: .5rem !important +} + +.p-3 { + padding: 1rem !important +} + +.p-4 { + padding: 1.5rem !important +} + +.p-5 { + padding: 3rem !important +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important +} + +.px-1 { + padding-right: .25rem !important; + padding-left: .25rem !important +} + +.px-2 { + padding-right: .5rem !important; + padding-left: .5rem !important +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important +} + +.py-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important +} + +.py-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important +} + +.pt-0 { + padding-top: 0 !important +} + +.pt-1 { + padding-top: .25rem !important +} + +.pt-2 { + padding-top: .5rem !important +} + +.pt-3 { + padding-top: 1rem !important +} + +.pt-4 { + padding-top: 1.5rem !important +} + +.pt-5 { + padding-top: 3rem !important +} + +.pe-0 { + padding-right: 0 !important +} + +.pe-1 { + padding-right: .25rem !important +} + +.pe-2 { + padding-right: .5rem !important +} + +.pe-3 { + padding-right: 1rem !important +} + +.pe-4 { + padding-right: 1.5rem !important +} + +.pe-5 { + padding-right: 3rem !important +} + +.pb-0 { + padding-bottom: 0 !important +} + +.pb-1 { + padding-bottom: .25rem !important +} + +.pb-2 { + padding-bottom: .5rem !important +} + +.pb-3 { + padding-bottom: 1rem !important +} + +.pb-4 { + padding-bottom: 1.5rem !important +} + +.pb-5 { + padding-bottom: 3rem !important +} + +.ps-0 { + padding-left: 0 !important +} + +.ps-1 { + padding-left: .25rem !important +} + +.ps-2 { + padding-left: .5rem !important +} + +.ps-3 { + padding-left: 1rem !important +} + +.ps-4 { + padding-left: 1.5rem !important +} + +.ps-5 { + padding-left: 3rem !important +} + +.font-monospace { + font-family: var(--bs-font-monospace) !important +} + +.fs-1 { + font-size: calc(1.375rem + 1.5vw) !important +} + +.fs-2 { + font-size: calc(1.325rem + .9vw) !important +} + +.fs-3 { + font-size: calc(1.3rem + .6vw) !important +} + +.fs-4 { + font-size: calc(1.275rem + .3vw) !important +} + +.fs-5 { + font-size: 1.25rem !important +} + +.fs-6 { + font-size: 1rem !important +} + +.fst-italic { + font-style: italic !important +} + +.fst-normal { + font-style: normal !important +} + +.fw-light { + font-weight: 300 !important +} + +.fw-lighter { + font-weight: lighter !important +} + +.fw-normal { + font-weight: 400 !important +} + +.fw-bold { + font-weight: 700 !important +} + +.fw-bolder { + font-weight: bolder !important +} + +.lh-1 { + line-height: 1 !important +} + +.lh-sm { + line-height: 1.25 !important +} + +.lh-base { + line-height: 1.5 !important +} + +.lh-lg { + line-height: 2 !important +} + +.text-start { + text-align: left !important +} + +.text-end { + text-align: right !important +} + +.text-center { + text-align: center !important +} + +.text-decoration-none { + text-decoration: none !important +} + +.text-decoration-underline { + text-decoration: underline !important +} + +.text-decoration-line-through { + text-decoration: line-through !important +} + +.text-lowercase { + text-transform: lowercase !important +} + +.text-uppercase { + text-transform: uppercase !important +} + +.text-capitalize { + text-transform: capitalize !important +} + +.text-wrap { + white-space: normal !important +} + +.text-nowrap { + white-space: nowrap !important +} + +.text-break { + word-wrap: break-word !important; + word-break: break-word !important +} + +.text-primary { + --bs-text-opacity: 1; + color: rgba(var(--bs-primary-rgb),var(--bs-text-opacity)) !important +} + +.text-secondary { + --bs-text-opacity: 1; + color: rgba(var(--bs-secondary-rgb),var(--bs-text-opacity)) !important +} + +.text-success { + --bs-text-opacity: 1; + color: rgba(var(--bs-success-rgb),var(--bs-text-opacity)) !important +} + +.text-info { + --bs-text-opacity: 1; + color: rgba(var(--bs-info-rgb),var(--bs-text-opacity)) !important +} + +.text-warning { + --bs-text-opacity: 1; + color: rgba(var(--bs-warning-rgb),var(--bs-text-opacity)) !important +} + +.text-danger { + --bs-text-opacity: 1; + color: rgba(var(--bs-danger-rgb),var(--bs-text-opacity)) !important +} + +.text-light { + --bs-text-opacity: 1; + color: rgba(var(--bs-light-rgb),var(--bs-text-opacity)) !important +} + +.text-dark { + --bs-text-opacity: 1; + color: rgba(var(--bs-dark-rgb),var(--bs-text-opacity)) !important +} + +.text-black { + --bs-text-opacity: 1; + color: rgba(var(--bs-black-rgb),var(--bs-text-opacity)) !important +} + +.text-white { + --bs-text-opacity: 1; + color: rgba(var(--bs-white-rgb),var(--bs-text-opacity)) !important +} + +.text-body { + --bs-text-opacity: 1; + color: rgba(var(--bs-body-rgb),var(--bs-text-opacity)) !important +} + +.text-muted { + --bs-text-opacity: 1; + color: #6c757d !important +} + +.text-black-50 { + --bs-text-opacity: 1; + color: rgba(0,0,0,.5) !important +} + +.text-white-50 { + --bs-text-opacity: 1; + color: rgba(255,255,255,.5) !important +} + +.text-reset { + --bs-text-opacity: 1; + color: inherit !important +} + +.text-opacity-25 { + --bs-text-opacity: 0.25 +} + +.text-opacity-50 { + --bs-text-opacity: 0.5 +} + +.text-opacity-75 { + --bs-text-opacity: 0.75 +} + +.text-opacity-100 { + --bs-text-opacity: 1 +} + +.bg-primary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-primary-rgb),var(--bs-bg-opacity)) !important +} + +.bg-secondary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity)) !important +} + +.bg-success { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-success-rgb),var(--bs-bg-opacity)) !important +} + +.bg-info { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-info-rgb),var(--bs-bg-opacity)) !important +} + +.bg-warning { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-warning-rgb),var(--bs-bg-opacity)) !important +} + +.bg-danger { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-danger-rgb),var(--bs-bg-opacity)) !important +} + +.bg-light { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-light-rgb),var(--bs-bg-opacity)) !important +} + +.bg-dark { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-dark-rgb),var(--bs-bg-opacity)) !important +} + +.bg-black { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-black-rgb),var(--bs-bg-opacity)) !important +} + +.bg-white { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-white-rgb),var(--bs-bg-opacity)) !important +} + +.bg-body { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-body-rgb),var(--bs-bg-opacity)) !important +} + +.bg-transparent { + --bs-bg-opacity: 1; + background-color: transparent !important +} + +.bg-opacity-10 { + --bs-bg-opacity: 0.1 +} + +.bg-opacity-25 { + --bs-bg-opacity: 0.25 +} + +.bg-opacity-50 { + --bs-bg-opacity: 0.5 +} + +.bg-opacity-75 { + --bs-bg-opacity: 0.75 +} + +.bg-opacity-100 { + --bs-bg-opacity: 1 +} + +.bg-gradient { + background-image: var(--bs-gradient) !important +} + +.user-select-all { + -webkit-user-select: all !important; + -moz-user-select: all !important; + user-select: all !important +} + +.user-select-auto { + -webkit-user-select: auto !important; + -moz-user-select: auto !important; + user-select: auto !important +} + +.user-select-none { + -webkit-user-select: none !important; + -moz-user-select: none !important; + user-select: none !important +} + +.pe-none { + pointer-events: none !important +} + +.pe-auto { + pointer-events: auto !important +} + +.rounded { + border-radius: .25rem !important +} + +.rounded-0 { + border-radius: 0 !important +} + +.rounded-1 { + border-radius: .2rem !important +} + +.rounded-2 { + border-radius: .25rem !important +} + +.rounded-3 { + border-radius: .3rem !important +} + +.rounded-circle { + border-radius: 50% !important +} + +.rounded-pill { + border-radius: 50rem !important +} + +.rounded-top { + border-top-left-radius: .25rem !important; + border-top-right-radius: .25rem !important +} + +.rounded-end { + border-top-right-radius: .25rem !important; + border-bottom-right-radius: .25rem !important +} + +.rounded-bottom { + border-bottom-right-radius: .25rem !important; + border-bottom-left-radius: .25rem !important +} + +.rounded-start { + border-bottom-left-radius: .25rem !important; + border-top-left-radius: .25rem !important +} + +.visible { + visibility: visible !important +} + +.invisible { + visibility: hidden !important +} + +@media (min-width:576px) { + .float-sm-start { + float: left !important + } + + .float-sm-end { + float: right !important + } + + .float-sm-none { + float: none !important + } + + .d-sm-inline { + display: inline !important + } + + .d-sm-inline-block { + display: inline-block !important + } + + .d-sm-block { + display: block !important + } + + .d-sm-grid { + display: grid !important + } + + .d-sm-table { + display: table !important + } + + .d-sm-table-row { + display: table-row !important + } + + .d-sm-table-cell { + display: table-cell !important + } + + .d-sm-flex { + display: flex !important + } + + .d-sm-inline-flex { + display: inline-flex !important + } + + .d-sm-none { + display: none !important + } + + .flex-sm-fill { + flex: 1 1 auto !important + } + + .flex-sm-row { + flex-direction: row !important + } + + .flex-sm-column { + flex-direction: column !important + } + + .flex-sm-row-reverse { + flex-direction: row-reverse !important + } + + .flex-sm-column-reverse { + flex-direction: column-reverse !important + } + + .flex-sm-grow-0 { + flex-grow: 0 !important + } + + .flex-sm-grow-1 { + flex-grow: 1 !important + } + + .flex-sm-shrink-0 { + flex-shrink: 0 !important + } + + .flex-sm-shrink-1 { + flex-shrink: 1 !important + } + + .flex-sm-wrap { + flex-wrap: wrap !important + } + + .flex-sm-nowrap { + flex-wrap: nowrap !important + } + + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-sm-0 { + gap: 0 !important + } + + .gap-sm-1 { + gap: .25rem !important + } + + .gap-sm-2 { + gap: .5rem !important + } + + .gap-sm-3 { + gap: 1rem !important + } + + .gap-sm-4 { + gap: 1.5rem !important + } + + .gap-sm-5 { + gap: 3rem !important + } + + .justify-content-sm-start { + justify-content: flex-start !important + } + + .justify-content-sm-end { + justify-content: flex-end !important + } + + .justify-content-sm-center { + justify-content: center !important + } + + .justify-content-sm-between { + justify-content: space-between !important + } + + .justify-content-sm-around { + justify-content: space-around !important + } + + .justify-content-sm-evenly { + justify-content: space-evenly !important + } + + .align-items-sm-start { + align-items: flex-start !important + } + + .align-items-sm-end { + align-items: flex-end !important + } + + .align-items-sm-center { + align-items: center !important + } + + .align-items-sm-baseline { + align-items: baseline !important + } + + .align-items-sm-stretch { + align-items: stretch !important + } + + .align-content-sm-start { + align-content: flex-start !important + } + + .align-content-sm-end { + align-content: flex-end !important + } + + .align-content-sm-center { + align-content: center !important + } + + .align-content-sm-between { + align-content: space-between !important + } + + .align-content-sm-around { + align-content: space-around !important + } + + .align-content-sm-stretch { + align-content: stretch !important + } + + .align-self-sm-auto { + align-self: auto !important + } + + .align-self-sm-start { + align-self: flex-start !important + } + + .align-self-sm-end { + align-self: flex-end !important + } + + .align-self-sm-center { + align-self: center !important + } + + .align-self-sm-baseline { + align-self: baseline !important + } + + .align-self-sm-stretch { + align-self: stretch !important + } + + .order-sm-first { + order: -1 !important + } + + .order-sm-0 { + order: 0 !important + } + + .order-sm-1 { + order: 1 !important + } + + .order-sm-2 { + order: 2 !important + } + + .order-sm-3 { + order: 3 !important + } + + .order-sm-4 { + order: 4 !important + } + + .order-sm-5 { + order: 5 !important + } + + .order-sm-last { + order: 6 !important + } + + .m-sm-0 { + margin: 0 !important + } + + .m-sm-1 { + margin: .25rem !important + } + + .m-sm-2 { + margin: .5rem !important + } + + .m-sm-3 { + margin: 1rem !important + } + + .m-sm-4 { + margin: 1.5rem !important + } + + .m-sm-5 { + margin: 3rem !important + } + + .m-sm-auto { + margin: auto !important + } + + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-sm-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-sm-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-sm-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-sm-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-sm-0 { + margin-top: 0 !important + } + + .mt-sm-1 { + margin-top: .25rem !important + } + + .mt-sm-2 { + margin-top: .5rem !important + } + + .mt-sm-3 { + margin-top: 1rem !important + } + + .mt-sm-4 { + margin-top: 1.5rem !important + } + + .mt-sm-5 { + margin-top: 3rem !important + } + + .mt-sm-auto { + margin-top: auto !important + } + + .me-sm-0 { + margin-right: 0 !important + } + + .me-sm-1 { + margin-right: .25rem !important + } + + .me-sm-2 { + margin-right: .5rem !important + } + + .me-sm-3 { + margin-right: 1rem !important + } + + .me-sm-4 { + margin-right: 1.5rem !important + } + + .me-sm-5 { + margin-right: 3rem !important + } + + .me-sm-auto { + margin-right: auto !important + } + + .mb-sm-0 { + margin-bottom: 0 !important + } + + .mb-sm-1 { + margin-bottom: .25rem !important + } + + .mb-sm-2 { + margin-bottom: .5rem !important + } + + .mb-sm-3 { + margin-bottom: 1rem !important + } + + .mb-sm-4 { + margin-bottom: 1.5rem !important + } + + .mb-sm-5 { + margin-bottom: 3rem !important + } + + .mb-sm-auto { + margin-bottom: auto !important + } + + .ms-sm-0 { + margin-left: 0 !important + } + + .ms-sm-1 { + margin-left: .25rem !important + } + + .ms-sm-2 { + margin-left: .5rem !important + } + + .ms-sm-3 { + margin-left: 1rem !important + } + + .ms-sm-4 { + margin-left: 1.5rem !important + } + + .ms-sm-5 { + margin-left: 3rem !important + } + + .ms-sm-auto { + margin-left: auto !important + } + + .p-sm-0 { + padding: 0 !important + } + + .p-sm-1 { + padding: .25rem !important + } + + .p-sm-2 { + padding: .5rem !important + } + + .p-sm-3 { + padding: 1rem !important + } + + .p-sm-4 { + padding: 1.5rem !important + } + + .p-sm-5 { + padding: 3rem !important + } + + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-sm-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-sm-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-sm-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-sm-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-sm-0 { + padding-top: 0 !important + } + + .pt-sm-1 { + padding-top: .25rem !important + } + + .pt-sm-2 { + padding-top: .5rem !important + } + + .pt-sm-3 { + padding-top: 1rem !important + } + + .pt-sm-4 { + padding-top: 1.5rem !important + } + + .pt-sm-5 { + padding-top: 3rem !important + } + + .pe-sm-0 { + padding-right: 0 !important + } + + .pe-sm-1 { + padding-right: .25rem !important + } + + .pe-sm-2 { + padding-right: .5rem !important + } + + .pe-sm-3 { + padding-right: 1rem !important + } + + .pe-sm-4 { + padding-right: 1.5rem !important + } + + .pe-sm-5 { + padding-right: 3rem !important + } + + .pb-sm-0 { + padding-bottom: 0 !important + } + + .pb-sm-1 { + padding-bottom: .25rem !important + } + + .pb-sm-2 { + padding-bottom: .5rem !important + } + + .pb-sm-3 { + padding-bottom: 1rem !important + } + + .pb-sm-4 { + padding-bottom: 1.5rem !important + } + + .pb-sm-5 { + padding-bottom: 3rem !important + } + + .ps-sm-0 { + padding-left: 0 !important + } + + .ps-sm-1 { + padding-left: .25rem !important + } + + .ps-sm-2 { + padding-left: .5rem !important + } + + .ps-sm-3 { + padding-left: 1rem !important + } + + .ps-sm-4 { + padding-left: 1.5rem !important + } + + .ps-sm-5 { + padding-left: 3rem !important + } + + .text-sm-start { + text-align: left !important + } + + .text-sm-end { + text-align: right !important + } + + .text-sm-center { + text-align: center !important + } +} + +@media (min-width:768px) { + .float-md-start { + float: left !important + } + + .float-md-end { + float: right !important + } + + .float-md-none { + float: none !important + } + + .d-md-inline { + display: inline !important + } + + .d-md-inline-block { + display: inline-block !important + } + + .d-md-block { + display: block !important + } + + .d-md-grid { + display: grid !important + } + + .d-md-table { + display: table !important + } + + .d-md-table-row { + display: table-row !important + } + + .d-md-table-cell { + display: table-cell !important + } + + .d-md-flex { + display: flex !important + } + + .d-md-inline-flex { + display: inline-flex !important + } + + .d-md-none { + display: none !important + } + + .flex-md-fill { + flex: 1 1 auto !important + } + + .flex-md-row { + flex-direction: row !important + } + + .flex-md-column { + flex-direction: column !important + } + + .flex-md-row-reverse { + flex-direction: row-reverse !important + } + + .flex-md-column-reverse { + flex-direction: column-reverse !important + } + + .flex-md-grow-0 { + flex-grow: 0 !important + } + + .flex-md-grow-1 { + flex-grow: 1 !important + } + + .flex-md-shrink-0 { + flex-shrink: 0 !important + } + + .flex-md-shrink-1 { + flex-shrink: 1 !important + } + + .flex-md-wrap { + flex-wrap: wrap !important + } + + .flex-md-nowrap { + flex-wrap: nowrap !important + } + + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-md-0 { + gap: 0 !important + } + + .gap-md-1 { + gap: .25rem !important + } + + .gap-md-2 { + gap: .5rem !important + } + + .gap-md-3 { + gap: 1rem !important + } + + .gap-md-4 { + gap: 1.5rem !important + } + + .gap-md-5 { + gap: 3rem !important + } + + .justify-content-md-start { + justify-content: flex-start !important + } + + .justify-content-md-end { + justify-content: flex-end !important + } + + .justify-content-md-center { + justify-content: center !important + } + + .justify-content-md-between { + justify-content: space-between !important + } + + .justify-content-md-around { + justify-content: space-around !important + } + + .justify-content-md-evenly { + justify-content: space-evenly !important + } + + .align-items-md-start { + align-items: flex-start !important + } + + .align-items-md-end { + align-items: flex-end !important + } + + .align-items-md-center { + align-items: center !important + } + + .align-items-md-baseline { + align-items: baseline !important + } + + .align-items-md-stretch { + align-items: stretch !important + } + + .align-content-md-start { + align-content: flex-start !important + } + + .align-content-md-end { + align-content: flex-end !important + } + + .align-content-md-center { + align-content: center !important + } + + .align-content-md-between { + align-content: space-between !important + } + + .align-content-md-around { + align-content: space-around !important + } + + .align-content-md-stretch { + align-content: stretch !important + } + + .align-self-md-auto { + align-self: auto !important + } + + .align-self-md-start { + align-self: flex-start !important + } + + .align-self-md-end { + align-self: flex-end !important + } + + .align-self-md-center { + align-self: center !important + } + + .align-self-md-baseline { + align-self: baseline !important + } + + .align-self-md-stretch { + align-self: stretch !important + } + + .order-md-first { + order: -1 !important + } + + .order-md-0 { + order: 0 !important + } + + .order-md-1 { + order: 1 !important + } + + .order-md-2 { + order: 2 !important + } + + .order-md-3 { + order: 3 !important + } + + .order-md-4 { + order: 4 !important + } + + .order-md-5 { + order: 5 !important + } + + .order-md-last { + order: 6 !important + } + + .m-md-0 { + margin: 0 !important + } + + .m-md-1 { + margin: .25rem !important + } + + .m-md-2 { + margin: .5rem !important + } + + .m-md-3 { + margin: 1rem !important + } + + .m-md-4 { + margin: 1.5rem !important + } + + .m-md-5 { + margin: 3rem !important + } + + .m-md-auto { + margin: auto !important + } + + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-md-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-md-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-md-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-md-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-md-0 { + margin-top: 0 !important + } + + .mt-md-1 { + margin-top: .25rem !important + } + + .mt-md-2 { + margin-top: .5rem !important + } + + .mt-md-3 { + margin-top: 1rem !important + } + + .mt-md-4 { + margin-top: 1.5rem !important + } + + .mt-md-5 { + margin-top: 3rem !important + } + + .mt-md-auto { + margin-top: auto !important + } + + .me-md-0 { + margin-right: 0 !important + } + + .me-md-1 { + margin-right: .25rem !important + } + + .me-md-2 { + margin-right: .5rem !important + } + + .me-md-3 { + margin-right: 1rem !important + } + + .me-md-4 { + margin-right: 1.5rem !important + } + + .me-md-5 { + margin-right: 3rem !important + } + + .me-md-auto { + margin-right: auto !important + } + + .mb-md-0 { + margin-bottom: 0 !important + } + + .mb-md-1 { + margin-bottom: .25rem !important + } + + .mb-md-2 { + margin-bottom: .5rem !important + } + + .mb-md-3 { + margin-bottom: 1rem !important + } + + .mb-md-4 { + margin-bottom: 1.5rem !important + } + + .mb-md-5 { + margin-bottom: 3rem !important + } + + .mb-md-auto { + margin-bottom: auto !important + } + + .ms-md-0 { + margin-left: 0 !important + } + + .ms-md-1 { + margin-left: .25rem !important + } + + .ms-md-2 { + margin-left: .5rem !important + } + + .ms-md-3 { + margin-left: 1rem !important + } + + .ms-md-4 { + margin-left: 1.5rem !important + } + + .ms-md-5 { + margin-left: 3rem !important + } + + .ms-md-auto { + margin-left: auto !important + } + + .p-md-0 { + padding: 0 !important + } + + .p-md-1 { + padding: .25rem !important + } + + .p-md-2 { + padding: .5rem !important + } + + .p-md-3 { + padding: 1rem !important + } + + .p-md-4 { + padding: 1.5rem !important + } + + .p-md-5 { + padding: 3rem !important + } + + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-md-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-md-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-md-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-md-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-md-0 { + padding-top: 0 !important + } + + .pt-md-1 { + padding-top: .25rem !important + } + + .pt-md-2 { + padding-top: .5rem !important + } + + .pt-md-3 { + padding-top: 1rem !important + } + + .pt-md-4 { + padding-top: 1.5rem !important + } + + .pt-md-5 { + padding-top: 3rem !important + } + + .pe-md-0 { + padding-right: 0 !important + } + + .pe-md-1 { + padding-right: .25rem !important + } + + .pe-md-2 { + padding-right: .5rem !important + } + + .pe-md-3 { + padding-right: 1rem !important + } + + .pe-md-4 { + padding-right: 1.5rem !important + } + + .pe-md-5 { + padding-right: 3rem !important + } + + .pb-md-0 { + padding-bottom: 0 !important + } + + .pb-md-1 { + padding-bottom: .25rem !important + } + + .pb-md-2 { + padding-bottom: .5rem !important + } + + .pb-md-3 { + padding-bottom: 1rem !important + } + + .pb-md-4 { + padding-bottom: 1.5rem !important + } + + .pb-md-5 { + padding-bottom: 3rem !important + } + + .ps-md-0 { + padding-left: 0 !important + } + + .ps-md-1 { + padding-left: .25rem !important + } + + .ps-md-2 { + padding-left: .5rem !important + } + + .ps-md-3 { + padding-left: 1rem !important + } + + .ps-md-4 { + padding-left: 1.5rem !important + } + + .ps-md-5 { + padding-left: 3rem !important + } + + .text-md-start { + text-align: left !important + } + + .text-md-end { + text-align: right !important + } + + .text-md-center { + text-align: center !important + } +} + +@media (min-width:992px) { + .float-lg-start { + float: left !important + } + + .float-lg-end { + float: right !important + } + + .float-lg-none { + float: none !important + } + + .d-lg-inline { + display: inline !important + } + + .d-lg-inline-block { + display: inline-block !important + } + + .d-lg-block { + display: block !important + } + + .d-lg-grid { + display: grid !important + } + + .d-lg-table { + display: table !important + } + + .d-lg-table-row { + display: table-row !important + } + + .d-lg-table-cell { + display: table-cell !important + } + + .d-lg-flex { + display: flex !important + } + + .d-lg-inline-flex { + display: inline-flex !important + } + + .d-lg-none { + display: none !important + } + + .flex-lg-fill { + flex: 1 1 auto !important + } + + .flex-lg-row { + flex-direction: row !important + } + + .flex-lg-column { + flex-direction: column !important + } + + .flex-lg-row-reverse { + flex-direction: row-reverse !important + } + + .flex-lg-column-reverse { + flex-direction: column-reverse !important + } + + .flex-lg-grow-0 { + flex-grow: 0 !important + } + + .flex-lg-grow-1 { + flex-grow: 1 !important + } + + .flex-lg-shrink-0 { + flex-shrink: 0 !important + } + + .flex-lg-shrink-1 { + flex-shrink: 1 !important + } + + .flex-lg-wrap { + flex-wrap: wrap !important + } + + .flex-lg-nowrap { + flex-wrap: nowrap !important + } + + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-lg-0 { + gap: 0 !important + } + + .gap-lg-1 { + gap: .25rem !important + } + + .gap-lg-2 { + gap: .5rem !important + } + + .gap-lg-3 { + gap: 1rem !important + } + + .gap-lg-4 { + gap: 1.5rem !important + } + + .gap-lg-5 { + gap: 3rem !important + } + + .justify-content-lg-start { + justify-content: flex-start !important + } + + .justify-content-lg-end { + justify-content: flex-end !important + } + + .justify-content-lg-center { + justify-content: center !important + } + + .justify-content-lg-between { + justify-content: space-between !important + } + + .justify-content-lg-around { + justify-content: space-around !important + } + + .justify-content-lg-evenly { + justify-content: space-evenly !important + } + + .align-items-lg-start { + align-items: flex-start !important + } + + .align-items-lg-end { + align-items: flex-end !important + } + + .align-items-lg-center { + align-items: center !important + } + + .align-items-lg-baseline { + align-items: baseline !important + } + + .align-items-lg-stretch { + align-items: stretch !important + } + + .align-content-lg-start { + align-content: flex-start !important + } + + .align-content-lg-end { + align-content: flex-end !important + } + + .align-content-lg-center { + align-content: center !important + } + + .align-content-lg-between { + align-content: space-between !important + } + + .align-content-lg-around { + align-content: space-around !important + } + + .align-content-lg-stretch { + align-content: stretch !important + } + + .align-self-lg-auto { + align-self: auto !important + } + + .align-self-lg-start { + align-self: flex-start !important + } + + .align-self-lg-end { + align-self: flex-end !important + } + + .align-self-lg-center { + align-self: center !important + } + + .align-self-lg-baseline { + align-self: baseline !important + } + + .align-self-lg-stretch { + align-self: stretch !important + } + + .order-lg-first { + order: -1 !important + } + + .order-lg-0 { + order: 0 !important + } + + .order-lg-1 { + order: 1 !important + } + + .order-lg-2 { + order: 2 !important + } + + .order-lg-3 { + order: 3 !important + } + + .order-lg-4 { + order: 4 !important + } + + .order-lg-5 { + order: 5 !important + } + + .order-lg-last { + order: 6 !important + } + + .m-lg-0 { + margin: 0 !important + } + + .m-lg-1 { + margin: .25rem !important + } + + .m-lg-2 { + margin: .5rem !important + } + + .m-lg-3 { + margin: 1rem !important + } + + .m-lg-4 { + margin: 1.5rem !important + } + + .m-lg-5 { + margin: 3rem !important + } + + .m-lg-auto { + margin: auto !important + } + + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-lg-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-lg-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-lg-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-lg-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-lg-0 { + margin-top: 0 !important + } + + .mt-lg-1 { + margin-top: .25rem !important + } + + .mt-lg-2 { + margin-top: .5rem !important + } + + .mt-lg-3 { + margin-top: 1rem !important + } + + .mt-lg-4 { + margin-top: 1.5rem !important + } + + .mt-lg-5 { + margin-top: 3rem !important + } + + .mt-lg-auto { + margin-top: auto !important + } + + .me-lg-0 { + margin-right: 0 !important + } + + .me-lg-1 { + margin-right: .25rem !important + } + + .me-lg-2 { + margin-right: .5rem !important + } + + .me-lg-3 { + margin-right: 1rem !important + } + + .me-lg-4 { + margin-right: 1.5rem !important + } + + .me-lg-5 { + margin-right: 3rem !important + } + + .me-lg-auto { + margin-right: auto !important + } + + .mb-lg-0 { + margin-bottom: 0 !important + } + + .mb-lg-1 { + margin-bottom: .25rem !important + } + + .mb-lg-2 { + margin-bottom: .5rem !important + } + + .mb-lg-3 { + margin-bottom: 1rem !important + } + + .mb-lg-4 { + margin-bottom: 1.5rem !important + } + + .mb-lg-5 { + margin-bottom: 3rem !important + } + + .mb-lg-auto { + margin-bottom: auto !important + } + + .ms-lg-0 { + margin-left: 0 !important + } + + .ms-lg-1 { + margin-left: .25rem !important + } + + .ms-lg-2 { + margin-left: .5rem !important + } + + .ms-lg-3 { + margin-left: 1rem !important + } + + .ms-lg-4 { + margin-left: 1.5rem !important + } + + .ms-lg-5 { + margin-left: 3rem !important + } + + .ms-lg-auto { + margin-left: auto !important + } + + .p-lg-0 { + padding: 0 !important + } + + .p-lg-1 { + padding: .25rem !important + } + + .p-lg-2 { + padding: .5rem !important + } + + .p-lg-3 { + padding: 1rem !important + } + + .p-lg-4 { + padding: 1.5rem !important + } + + .p-lg-5 { + padding: 3rem !important + } + + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-lg-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-lg-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-lg-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-lg-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-lg-0 { + padding-top: 0 !important + } + + .pt-lg-1 { + padding-top: .25rem !important + } + + .pt-lg-2 { + padding-top: .5rem !important + } + + .pt-lg-3 { + padding-top: 1rem !important + } + + .pt-lg-4 { + padding-top: 1.5rem !important + } + + .pt-lg-5 { + padding-top: 3rem !important + } + + .pe-lg-0 { + padding-right: 0 !important + } + + .pe-lg-1 { + padding-right: .25rem !important + } + + .pe-lg-2 { + padding-right: .5rem !important + } + + .pe-lg-3 { + padding-right: 1rem !important + } + + .pe-lg-4 { + padding-right: 1.5rem !important + } + + .pe-lg-5 { + padding-right: 3rem !important + } + + .pb-lg-0 { + padding-bottom: 0 !important + } + + .pb-lg-1 { + padding-bottom: .25rem !important + } + + .pb-lg-2 { + padding-bottom: .5rem !important + } + + .pb-lg-3 { + padding-bottom: 1rem !important + } + + .pb-lg-4 { + padding-bottom: 1.5rem !important + } + + .pb-lg-5 { + padding-bottom: 3rem !important + } + + .ps-lg-0 { + padding-left: 0 !important + } + + .ps-lg-1 { + padding-left: .25rem !important + } + + .ps-lg-2 { + padding-left: .5rem !important + } + + .ps-lg-3 { + padding-left: 1rem !important + } + + .ps-lg-4 { + padding-left: 1.5rem !important + } + + .ps-lg-5 { + padding-left: 3rem !important + } + + .text-lg-start { + text-align: left !important + } + + .text-lg-end { + text-align: right !important + } + + .text-lg-center { + text-align: center !important + } +} + +@media (min-width:1200px) { + .float-xl-start { + float: left !important + } + + .float-xl-end { + float: right !important + } + + .float-xl-none { + float: none !important + } + + .d-xl-inline { + display: inline !important + } + + .d-xl-inline-block { + display: inline-block !important + } + + .d-xl-block { + display: block !important + } + + .d-xl-grid { + display: grid !important + } + + .d-xl-table { + display: table !important + } + + .d-xl-table-row { + display: table-row !important + } + + .d-xl-table-cell { + display: table-cell !important + } + + .d-xl-flex { + display: flex !important + } + + .d-xl-inline-flex { + display: inline-flex !important + } + + .d-xl-none { + display: none !important + } + + .flex-xl-fill { + flex: 1 1 auto !important + } + + .flex-xl-row { + flex-direction: row !important + } + + .flex-xl-column { + flex-direction: column !important + } + + .flex-xl-row-reverse { + flex-direction: row-reverse !important + } + + .flex-xl-column-reverse { + flex-direction: column-reverse !important + } + + .flex-xl-grow-0 { + flex-grow: 0 !important + } + + .flex-xl-grow-1 { + flex-grow: 1 !important + } + + .flex-xl-shrink-0 { + flex-shrink: 0 !important + } + + .flex-xl-shrink-1 { + flex-shrink: 1 !important + } + + .flex-xl-wrap { + flex-wrap: wrap !important + } + + .flex-xl-nowrap { + flex-wrap: nowrap !important + } + + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-xl-0 { + gap: 0 !important + } + + .gap-xl-1 { + gap: .25rem !important + } + + .gap-xl-2 { + gap: .5rem !important + } + + .gap-xl-3 { + gap: 1rem !important + } + + .gap-xl-4 { + gap: 1.5rem !important + } + + .gap-xl-5 { + gap: 3rem !important + } + + .justify-content-xl-start { + justify-content: flex-start !important + } + + .justify-content-xl-end { + justify-content: flex-end !important + } + + .justify-content-xl-center { + justify-content: center !important + } + + .justify-content-xl-between { + justify-content: space-between !important + } + + .justify-content-xl-around { + justify-content: space-around !important + } + + .justify-content-xl-evenly { + justify-content: space-evenly !important + } + + .align-items-xl-start { + align-items: flex-start !important + } + + .align-items-xl-end { + align-items: flex-end !important + } + + .align-items-xl-center { + align-items: center !important + } + + .align-items-xl-baseline { + align-items: baseline !important + } + + .align-items-xl-stretch { + align-items: stretch !important + } + + .align-content-xl-start { + align-content: flex-start !important + } + + .align-content-xl-end { + align-content: flex-end !important + } + + .align-content-xl-center { + align-content: center !important + } + + .align-content-xl-between { + align-content: space-between !important + } + + .align-content-xl-around { + align-content: space-around !important + } + + .align-content-xl-stretch { + align-content: stretch !important + } + + .align-self-xl-auto { + align-self: auto !important + } + + .align-self-xl-start { + align-self: flex-start !important + } + + .align-self-xl-end { + align-self: flex-end !important + } + + .align-self-xl-center { + align-self: center !important + } + + .align-self-xl-baseline { + align-self: baseline !important + } + + .align-self-xl-stretch { + align-self: stretch !important + } + + .order-xl-first { + order: -1 !important + } + + .order-xl-0 { + order: 0 !important + } + + .order-xl-1 { + order: 1 !important + } + + .order-xl-2 { + order: 2 !important + } + + .order-xl-3 { + order: 3 !important + } + + .order-xl-4 { + order: 4 !important + } + + .order-xl-5 { + order: 5 !important + } + + .order-xl-last { + order: 6 !important + } + + .m-xl-0 { + margin: 0 !important + } + + .m-xl-1 { + margin: .25rem !important + } + + .m-xl-2 { + margin: .5rem !important + } + + .m-xl-3 { + margin: 1rem !important + } + + .m-xl-4 { + margin: 1.5rem !important + } + + .m-xl-5 { + margin: 3rem !important + } + + .m-xl-auto { + margin: auto !important + } + + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-xl-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-xl-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-xl-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-xl-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-xl-0 { + margin-top: 0 !important + } + + .mt-xl-1 { + margin-top: .25rem !important + } + + .mt-xl-2 { + margin-top: .5rem !important + } + + .mt-xl-3 { + margin-top: 1rem !important + } + + .mt-xl-4 { + margin-top: 1.5rem !important + } + + .mt-xl-5 { + margin-top: 3rem !important + } + + .mt-xl-auto { + margin-top: auto !important + } + + .me-xl-0 { + margin-right: 0 !important + } + + .me-xl-1 { + margin-right: .25rem !important + } + + .me-xl-2 { + margin-right: .5rem !important + } + + .me-xl-3 { + margin-right: 1rem !important + } + + .me-xl-4 { + margin-right: 1.5rem !important + } + + .me-xl-5 { + margin-right: 3rem !important + } + + .me-xl-auto { + margin-right: auto !important + } + + .mb-xl-0 { + margin-bottom: 0 !important + } + + .mb-xl-1 { + margin-bottom: .25rem !important + } + + .mb-xl-2 { + margin-bottom: .5rem !important + } + + .mb-xl-3 { + margin-bottom: 1rem !important + } + + .mb-xl-4 { + margin-bottom: 1.5rem !important + } + + .mb-xl-5 { + margin-bottom: 3rem !important + } + + .mb-xl-auto { + margin-bottom: auto !important + } + + .ms-xl-0 { + margin-left: 0 !important + } + + .ms-xl-1 { + margin-left: .25rem !important + } + + .ms-xl-2 { + margin-left: .5rem !important + } + + .ms-xl-3 { + margin-left: 1rem !important + } + + .ms-xl-4 { + margin-left: 1.5rem !important + } + + .ms-xl-5 { + margin-left: 3rem !important + } + + .ms-xl-auto { + margin-left: auto !important + } + + .p-xl-0 { + padding: 0 !important + } + + .p-xl-1 { + padding: .25rem !important + } + + .p-xl-2 { + padding: .5rem !important + } + + .p-xl-3 { + padding: 1rem !important + } + + .p-xl-4 { + padding: 1.5rem !important + } + + .p-xl-5 { + padding: 3rem !important + } + + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-xl-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-xl-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-xl-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-xl-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-xl-0 { + padding-top: 0 !important + } + + .pt-xl-1 { + padding-top: .25rem !important + } + + .pt-xl-2 { + padding-top: .5rem !important + } + + .pt-xl-3 { + padding-top: 1rem !important + } + + .pt-xl-4 { + padding-top: 1.5rem !important + } + + .pt-xl-5 { + padding-top: 3rem !important + } + + .pe-xl-0 { + padding-right: 0 !important + } + + .pe-xl-1 { + padding-right: .25rem !important + } + + .pe-xl-2 { + padding-right: .5rem !important + } + + .pe-xl-3 { + padding-right: 1rem !important + } + + .pe-xl-4 { + padding-right: 1.5rem !important + } + + .pe-xl-5 { + padding-right: 3rem !important + } + + .pb-xl-0 { + padding-bottom: 0 !important + } + + .pb-xl-1 { + padding-bottom: .25rem !important + } + + .pb-xl-2 { + padding-bottom: .5rem !important + } + + .pb-xl-3 { + padding-bottom: 1rem !important + } + + .pb-xl-4 { + padding-bottom: 1.5rem !important + } + + .pb-xl-5 { + padding-bottom: 3rem !important + } + + .ps-xl-0 { + padding-left: 0 !important + } + + .ps-xl-1 { + padding-left: .25rem !important + } + + .ps-xl-2 { + padding-left: .5rem !important + } + + .ps-xl-3 { + padding-left: 1rem !important + } + + .ps-xl-4 { + padding-left: 1.5rem !important + } + + .ps-xl-5 { + padding-left: 3rem !important + } + + .text-xl-start { + text-align: left !important + } + + .text-xl-end { + text-align: right !important + } + + .text-xl-center { + text-align: center !important + } +} + +@media (min-width:1400px) { + .float-xxl-start { + float: left !important + } + + .float-xxl-end { + float: right !important + } + + .float-xxl-none { + float: none !important + } + + .d-xxl-inline { + display: inline !important + } + + .d-xxl-inline-block { + display: inline-block !important + } + + .d-xxl-block { + display: block !important + } + + .d-xxl-grid { + display: grid !important + } + + .d-xxl-table { + display: table !important + } + + .d-xxl-table-row { + display: table-row !important + } + + .d-xxl-table-cell { + display: table-cell !important + } + + .d-xxl-flex { + display: flex !important + } + + .d-xxl-inline-flex { + display: inline-flex !important + } + + .d-xxl-none { + display: none !important + } + + .flex-xxl-fill { + flex: 1 1 auto !important + } + + .flex-xxl-row { + flex-direction: row !important + } + + .flex-xxl-column { + flex-direction: column !important + } + + .flex-xxl-row-reverse { + flex-direction: row-reverse !important + } + + .flex-xxl-column-reverse { + flex-direction: column-reverse !important + } + + .flex-xxl-grow-0 { + flex-grow: 0 !important + } + + .flex-xxl-grow-1 { + flex-grow: 1 !important + } + + .flex-xxl-shrink-0 { + flex-shrink: 0 !important + } + + .flex-xxl-shrink-1 { + flex-shrink: 1 !important + } + + .flex-xxl-wrap { + flex-wrap: wrap !important + } + + .flex-xxl-nowrap { + flex-wrap: nowrap !important + } + + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .gap-xxl-0 { + gap: 0 !important + } + + .gap-xxl-1 { + gap: .25rem !important + } + + .gap-xxl-2 { + gap: .5rem !important + } + + .gap-xxl-3 { + gap: 1rem !important + } + + .gap-xxl-4 { + gap: 1.5rem !important + } + + .gap-xxl-5 { + gap: 3rem !important + } + + .justify-content-xxl-start { + justify-content: flex-start !important + } + + .justify-content-xxl-end { + justify-content: flex-end !important + } + + .justify-content-xxl-center { + justify-content: center !important + } + + .justify-content-xxl-between { + justify-content: space-between !important + } + + .justify-content-xxl-around { + justify-content: space-around !important + } + + .justify-content-xxl-evenly { + justify-content: space-evenly !important + } + + .align-items-xxl-start { + align-items: flex-start !important + } + + .align-items-xxl-end { + align-items: flex-end !important + } + + .align-items-xxl-center { + align-items: center !important + } + + .align-items-xxl-baseline { + align-items: baseline !important + } + + .align-items-xxl-stretch { + align-items: stretch !important + } + + .align-content-xxl-start { + align-content: flex-start !important + } + + .align-content-xxl-end { + align-content: flex-end !important + } + + .align-content-xxl-center { + align-content: center !important + } + + .align-content-xxl-between { + align-content: space-between !important + } + + .align-content-xxl-around { + align-content: space-around !important + } + + .align-content-xxl-stretch { + align-content: stretch !important + } + + .align-self-xxl-auto { + align-self: auto !important + } + + .align-self-xxl-start { + align-self: flex-start !important + } + + .align-self-xxl-end { + align-self: flex-end !important + } + + .align-self-xxl-center { + align-self: center !important + } + + .align-self-xxl-baseline { + align-self: baseline !important + } + + .align-self-xxl-stretch { + align-self: stretch !important + } + + .order-xxl-first { + order: -1 !important + } + + .order-xxl-0 { + order: 0 !important + } + + .order-xxl-1 { + order: 1 !important + } + + .order-xxl-2 { + order: 2 !important + } + + .order-xxl-3 { + order: 3 !important + } + + .order-xxl-4 { + order: 4 !important + } + + .order-xxl-5 { + order: 5 !important + } + + .order-xxl-last { + order: 6 !important + } + + .m-xxl-0 { + margin: 0 !important + } + + .m-xxl-1 { + margin: .25rem !important + } + + .m-xxl-2 { + margin: .5rem !important + } + + .m-xxl-3 { + margin: 1rem !important + } + + .m-xxl-4 { + margin: 1.5rem !important + } + + .m-xxl-5 { + margin: 3rem !important + } + + .m-xxl-auto { + margin: auto !important + } + + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-xxl-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-xxl-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-xxl-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-xxl-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-xxl-0 { + margin-top: 0 !important + } + + .mt-xxl-1 { + margin-top: .25rem !important + } + + .mt-xxl-2 { + margin-top: .5rem !important + } + + .mt-xxl-3 { + margin-top: 1rem !important + } + + .mt-xxl-4 { + margin-top: 1.5rem !important + } + + .mt-xxl-5 { + margin-top: 3rem !important + } + + .mt-xxl-auto { + margin-top: auto !important + } + + .me-xxl-0 { + margin-right: 0 !important + } + + .me-xxl-1 { + margin-right: .25rem !important + } + + .me-xxl-2 { + margin-right: .5rem !important + } + + .me-xxl-3 { + margin-right: 1rem !important + } + + .me-xxl-4 { + margin-right: 1.5rem !important + } + + .me-xxl-5 { + margin-right: 3rem !important + } + + .me-xxl-auto { + margin-right: auto !important + } + + .mb-xxl-0 { + margin-bottom: 0 !important + } + + .mb-xxl-1 { + margin-bottom: .25rem !important + } + + .mb-xxl-2 { + margin-bottom: .5rem !important + } + + .mb-xxl-3 { + margin-bottom: 1rem !important + } + + .mb-xxl-4 { + margin-bottom: 1.5rem !important + } + + .mb-xxl-5 { + margin-bottom: 3rem !important + } + + .mb-xxl-auto { + margin-bottom: auto !important + } + + .ms-xxl-0 { + margin-left: 0 !important + } + + .ms-xxl-1 { + margin-left: .25rem !important + } + + .ms-xxl-2 { + margin-left: .5rem !important + } + + .ms-xxl-3 { + margin-left: 1rem !important + } + + .ms-xxl-4 { + margin-left: 1.5rem !important + } + + .ms-xxl-5 { + margin-left: 3rem !important + } + + .ms-xxl-auto { + margin-left: auto !important + } + + .p-xxl-0 { + padding: 0 !important + } + + .p-xxl-1 { + padding: .25rem !important + } + + .p-xxl-2 { + padding: .5rem !important + } + + .p-xxl-3 { + padding: 1rem !important + } + + .p-xxl-4 { + padding: 1.5rem !important + } + + .p-xxl-5 { + padding: 3rem !important + } + + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-xxl-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-xxl-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-xxl-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-xxl-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-xxl-0 { + padding-top: 0 !important + } + + .pt-xxl-1 { + padding-top: .25rem !important + } + + .pt-xxl-2 { + padding-top: .5rem !important + } + + .pt-xxl-3 { + padding-top: 1rem !important + } + + .pt-xxl-4 { + padding-top: 1.5rem !important + } + + .pt-xxl-5 { + padding-top: 3rem !important + } + + .pe-xxl-0 { + padding-right: 0 !important + } + + .pe-xxl-1 { + padding-right: .25rem !important + } + + .pe-xxl-2 { + padding-right: .5rem !important + } + + .pe-xxl-3 { + padding-right: 1rem !important + } + + .pe-xxl-4 { + padding-right: 1.5rem !important + } + + .pe-xxl-5 { + padding-right: 3rem !important + } + + .pb-xxl-0 { + padding-bottom: 0 !important + } + + .pb-xxl-1 { + padding-bottom: .25rem !important + } + + .pb-xxl-2 { + padding-bottom: .5rem !important + } + + .pb-xxl-3 { + padding-bottom: 1rem !important + } + + .pb-xxl-4 { + padding-bottom: 1.5rem !important + } + + .pb-xxl-5 { + padding-bottom: 3rem !important + } + + .ps-xxl-0 { + padding-left: 0 !important + } + + .ps-xxl-1 { + padding-left: .25rem !important + } + + .ps-xxl-2 { + padding-left: .5rem !important + } + + .ps-xxl-3 { + padding-left: 1rem !important + } + + .ps-xxl-4 { + padding-left: 1.5rem !important + } + + .ps-xxl-5 { + padding-left: 3rem !important + } + + .text-xxl-start { + text-align: left !important + } + + .text-xxl-end { + text-align: right !important + } + + .text-xxl-center { + text-align: center !important + } +} + +@media (min-width:1200px) { + .fs-1 { + font-size: 2.5rem !important + } + + .fs-2 { + font-size: 2rem !important + } + + .fs-3 { + font-size: 1.75rem !important + } + + .fs-4 { + font-size: 1.5rem !important + } +} + +@media print { + .d-print-inline { + display: inline !important + } + + .d-print-inline-block { + display: inline-block !important + } + + .d-print-block { + display: block !important + } + + .d-print-grid { + display: grid !important + } + + .d-print-table { + display: table !important + } + + .d-print-table-row { + display: table-row !important + } + + .d-print-table-cell { + display: table-cell !important + } + + .d-print-flex { + display: flex !important + } + + .d-print-inline-flex { + display: inline-flex !important + } + + .d-print-none { + display: none !important + } +} +/*# sourceMappingURL=bootstrap.min.css.map */ diff --git a/MasaBlazorApp3/wwwroot/css/bootstrap/bootstrap.min.css.map b/MasaBlazorApp3/wwwroot/css/bootstrap/bootstrap.min.css.map new file mode 100644 index 0000000..8c41293 --- /dev/null +++ b/MasaBlazorApp3/wwwroot/css/bootstrap/bootstrap.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","../../scss/mixins/_border-radius.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/_containers.scss","../../scss/mixins/_container.scss","../../scss/mixins/_breakpoints.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/_tables.scss","../../scss/mixins/_table-variants.scss","../../scss/forms/_labels.scss","../../scss/forms/_form-text.scss","../../scss/forms/_form-control.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_gradients.scss","../../scss/forms/_form-select.scss","../../scss/forms/_form-check.scss","../../scss/forms/_form-range.scss","../../scss/forms/_floating-labels.scss","../../scss/forms/_input-group.scss","../../scss/mixins/_forms.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/_button-group.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_accordion.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/mixins/_backdrop.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/_offcanvas.scss","../../scss/_placeholders.scss","../../scss/helpers/_colored-links.scss","../../scss/helpers/_ratio.scss","../../scss/helpers/_position.scss","../../scss/helpers/_stacks.scss","../../scss/helpers/_visually-hidden.scss","../../scss/mixins/_visually-hidden.scss","../../scss/helpers/_stretched-link.scss","../../scss/helpers/_text-truncation.scss","../../scss/mixins/_text-truncate.scss","../../scss/helpers/_vr.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n// scss-docs-start import-stack\n// Configuration\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"utilities\";\n\n// Layout & components\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"containers\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"accordion\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"alert\";\n@import \"progress\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"offcanvas\";\n@import \"placeholders\";\n\n// Helpers\n@import \"helpers\";\n\n// Utilities\n@import \"utilities/api\";\n// scss-docs-end import-stack\n",":root {\n // Note: Custom variable values only support SassScript inside `#{}`.\n\n // Colors\n //\n // Generate palettes for full colors, grays, and theme colors.\n\n @each $color, $value in $colors {\n --#{$variable-prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $grays {\n --#{$variable-prefix}gray-#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$variable-prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors-rgb {\n --#{$variable-prefix}#{$color}-rgb: #{$value};\n }\n\n --#{$variable-prefix}white-rgb: #{to-rgb($white)};\n --#{$variable-prefix}black-rgb: #{to-rgb($black)};\n --#{$variable-prefix}body-rgb: #{to-rgb($body-color)};\n\n // Fonts\n\n // Note: Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n --#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)};\n --#{$variable-prefix}gradient: #{$gradient};\n\n // Root and body\n // stylelint-disable custom-property-empty-line-before\n // scss-docs-start root-body-variables\n @if $font-size-root != null {\n --#{$variable-prefix}root-font-size: #{$font-size-root};\n }\n --#{$variable-prefix}body-font-family: #{$font-family-base};\n --#{$variable-prefix}body-font-size: #{$font-size-base};\n --#{$variable-prefix}body-font-weight: #{$font-weight-base};\n --#{$variable-prefix}body-line-height: #{$line-height-base};\n --#{$variable-prefix}body-color: #{$body-color};\n @if $body-text-align != null {\n --#{$variable-prefix}body-text-align: #{$body-text-align};\n }\n --#{$variable-prefix}body-bg: #{$body-bg};\n // scss-docs-end root-body-variables\n // stylelint-enable custom-property-empty-line-before\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n\n// Root\n//\n// Ability to the value of the root font sizes, affecting the value of `rem`.\n// null by default, thus nothing is generated.\n\n:root {\n @if $font-size-root != null {\n font-size: var(--#{$variable-prefix}-root-font-size);\n }\n\n @if $enable-smooth-scroll {\n @media (prefers-reduced-motion: no-preference) {\n scroll-behavior: smooth;\n }\n }\n}\n\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Prevent adjustments of font size after orientation changes in iOS.\n// 4. Change the default tap highlight to be completely transparent in iOS.\n\n// scss-docs-start reboot-body-rules\nbody {\n margin: 0; // 1\n font-family: var(--#{$variable-prefix}body-font-family);\n @include font-size(var(--#{$variable-prefix}body-font-size));\n font-weight: var(--#{$variable-prefix}body-font-weight);\n line-height: var(--#{$variable-prefix}body-line-height);\n color: var(--#{$variable-prefix}body-color);\n text-align: var(--#{$variable-prefix}body-text-align);\n background-color: var(--#{$variable-prefix}body-bg); // 2\n -webkit-text-size-adjust: 100%; // 3\n -webkit-tap-highlight-color: rgba($black, 0); // 4\n}\n// scss-docs-end reboot-body-rules\n\n\n// Content grouping\n//\n// 1. Reset Firefox's gray color\n// 2. Set correct height and prevent the `size` attribute to make the `hr` look like an input field\n\nhr {\n margin: $hr-margin-y 0;\n color: $hr-color; // 1\n background-color: currentColor;\n border: 0;\n opacity: $hr-opacity;\n}\n\nhr:not([size]) {\n height: $hr-height; // 2\n}\n\n\n// Typography\n//\n// 1. Remove top margins from headings\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n margin-top: 0; // 1\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-style: $headings-font-style;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1 {\n @extend %heading;\n @include font-size($h1-font-size);\n}\n\nh2 {\n @extend %heading;\n @include font-size($h2-font-size);\n}\n\nh3 {\n @extend %heading;\n @include font-size($h3-font-size);\n}\n\nh4 {\n @extend %heading;\n @include font-size($h4-font-size);\n}\n\nh5 {\n @extend %heading;\n @include font-size($h5-font-size);\n}\n\nh6 {\n @extend %heading;\n @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-bs-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-bs-original-title] { // 1\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n text-decoration-skip-ink: none; // 4\n}\n\n\n// Address\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n position: relative;\n @include font-size($sub-sup-font-size);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n\n &:hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n &,\n &:hover {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-code;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n direction: ltr #{\"/* rtl:ignore */\"};\n unicode-bidi: bidi-override;\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n display: block;\n margin-top: 0; // 1\n margin-bottom: 1rem; // 2\n overflow: auto; // 3\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\ncode {\n @include font-size($code-font-size);\n color: $code-color;\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n\n kbd {\n padding: 0;\n @include font-size(1em);\n font-weight: $nested-kbd-font-weight;\n }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: $table-cell-padding-y;\n padding-bottom: $table-cell-padding-y;\n color: $table-caption-color;\n text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // 1\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\nbutton,\nselect {\n text-transform: none;\n}\n// Set the cursor for non-`