添加项目文件。
This commit is contained in:
		
							parent
							
								
									0682ae842d
								
							
						
					
					
						commit
						1a0aced391
					
				| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					@namespace MasaBlazorApp3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Router AppAssembly="@typeof(App).Assembly">
 | 
				
			||||||
 | 
					    <Found Context="routeData">
 | 
				
			||||||
 | 
					        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
 | 
				
			||||||
 | 
					        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
 | 
				
			||||||
 | 
					    </Found>
 | 
				
			||||||
 | 
					    <NotFound>
 | 
				
			||||||
 | 
					        <LayoutView Layout="@typeof(MainLayout)">
 | 
				
			||||||
 | 
					            <p role="alert">Sorry, there's nothing at this address.</p>
 | 
				
			||||||
 | 
					        </LayoutView>
 | 
				
			||||||
 | 
					    </NotFound>
 | 
				
			||||||
 | 
					</Router>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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<AppDataConnection> options)
 | 
				
			||||||
 | 
					       : base(options.Options)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public ITable<User> User => this.GetTable<User>();
 | 
				
			||||||
 | 
					        public ITable<Role> Role => this.GetTable<Role>();
 | 
				
			||||||
 | 
					        public ITable<ChannelList> ChannelList => this.GetTable<ChannelList>();
 | 
				
			||||||
 | 
					        public ITable<ChannelStock> ChannelStock => this.GetTable<ChannelStock>();
 | 
				
			||||||
 | 
					        public ITable<DrugInfo> DrugInfo => this.GetTable<DrugInfo>();
 | 
				
			||||||
 | 
					        public ITable<DrugManuNo> DrugManuNo => this.GetTable<DrugManuNo>();
 | 
				
			||||||
 | 
					        public ITable<OrderInfo> OrderInfo => this.GetTable<OrderInfo>();
 | 
				
			||||||
 | 
					        public ITable<OrderDetail> OrderDetail => this.GetTable<OrderDetail>();
 | 
				
			||||||
 | 
					        public ITable<MachineRecord> MachineRecord => this.GetTable<MachineRecord>();
 | 
				
			||||||
 | 
					        public ITable<InOutInvoice> InOutInvoice => this.GetTable<InOutInvoice>();
 | 
				
			||||||
 | 
					        public ITable<AccountBook> AccountBook => this.GetTable<AccountBook>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<ChannelStock>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public int[] DrawerArray { get; set; }
 | 
				
			||||||
 | 
					        public List<ChannelStock> ChannelStocks { get; set; } = new List<ChannelStock>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using MasaBlazorApp3.Pojo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MasaBlazorApp3.DataAccess.Dao
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public interface IChannelListDao
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public Task<PageData<ChannelStock>> GetAllChannelList(int DrawerType, string drugName, int? take, int? skip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<List<ChannelStock>> GetChannelStockByDrugId(string DrugId);
 | 
				
			||||||
 | 
					        public Task<List<ChannelList>> GetChannelListByDrawerNo(int DrawerNo);
 | 
				
			||||||
 | 
					        public Task<List<ChannelStock>> GetChannelStockByDrawerNo(int DrawerNo, int Quantity = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<List<ChannelStock>> GetAllDrugChannelStock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<List<ChannelList>> GetAllDrugChannelList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<bool> DrawerOperationFinish(List<ChannelStock> Stocks, int type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<bool> UnBind(string id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<bool> Bind(ChannelStock Stock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<PageMultiData<ChannelStock,DrugInfo>> GetAllChannelListWithDrug(int DrawerType, string drugName, int? take, int? skip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<ChannelStockWithDrawerCount<ChannelStock>> GetChannelStockByDrawerNoWithDrawers(int DrawerNo, int Quantity = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //盘点
 | 
				
			||||||
 | 
					        public Task<bool> DrawerCheckFinish(List<ChannelStock> Stocks);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<List<DrugInfo>> GetAllDrugAndStock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<List<DrugInfo>> GetAllDrug();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<PageData<DrugInfo>> GetAllDrug(string drugId, string drugName, int? take, int? skip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //Task<List<DrugInfo>> GetAllDrugAndStockList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<DrugManuNo> GetDrugManuNo(string drugId, string manuNo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //添加药品信息
 | 
				
			||||||
 | 
					        int AddDrugInfo(DrugInfo drugInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //删除药品信息
 | 
				
			||||||
 | 
					        Task<bool> DeleteDrugInfo(string drugId);
 | 
				
			||||||
 | 
					        //修改药品信息
 | 
				
			||||||
 | 
					        Task<bool> UpdateDrugInfo(DrugInfo drugInfo);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<PageData<InOutInvoice>> GetAllInvoiceByType(string invoiceNo, DateTime invoiceDate, int? take, int? skip, int type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<List<InvoiceVo>> getTakeInfoByInvoiceNo(string invoiceNo);
 | 
				
			||||||
 | 
					        Task<List<InvoiceVo>> getAddInfoByInvoiceNo(string invoiceNo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<bool> InvoiceOutFinish(List<InvoiceVo> data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<bool> InvoiceAddFinish(List<InvoiceVo> data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<PageData<MachineRecord>> GetMachineRecordAsync(DateTime start, DateTime end, int operatorId, string drugId, int type, int? take, int? skip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<PageData<MachineRecord>> GetCanReturnRecords(DateTime start, DateTime end, int operatorId, string drugId, int? take, int? skip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<List<OperationVo<List<MachineRecord>>>> getReturnDrugInfoByRecords(List<MachineRecord> records);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<bool> ReturnDrugFinish(List<OperationVo<List<MachineRecord>>> datas);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<List<ChannelStock>> GetReturnEmpty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<PageData<MachineRecord>> getReturnEmptyInfoByRecords(ChannelStock records);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<bool> ReturnEmptyFinish(List<MachineRecord> datas,ChannelStock channelStock);
 | 
				
			||||||
 | 
					        Task<List<ChannelStock>> GetReturnEmptyWithCanReturnQuantiy();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<PageData<OrderInfo>> GetAllOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<PageData<OrderInfo>> GetAllCanReturnOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<List<OrderDetail>> getDetailByOrderNo(string OrderrNo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<List<OrderTakeVo>> getTakeInfoByOrderNo(string OrderrNo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<bool> OrderTakeFinish(List<OrderTakeVo> datas);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<bool> OrderReturnFinish(List<OperationVo<MachineRecord>> datas, string OrderrNo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<List<OperationVo<MachineRecord>>> getReturnInfoByOrderNo(string OrderrNo);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					using MasaBlazorApp3.Pojo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MasaBlazorApp3.DataAccess.Dao
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public interface IRoleDao
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int InsertRole(Role role);
 | 
				
			||||||
 | 
					        Task<Role> GetRoleById(int id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool UpdateRole(Role role);
 | 
				
			||||||
 | 
					        bool DeleteRole(int id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<PageData<Role>> GetRolesByName(string name, int? take, int? skip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<List<Role>> GetAllRoles();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<List<ChannelStock>> GetChannelStocksByDrug(List<DrugInfo> drugInfos);
 | 
				
			||||||
 | 
					        Task<List<OrderTakeVo>> getTakeInfoByOrderNo(List<OrderDetail> orderDetails);
 | 
				
			||||||
 | 
					        Task<bool> OrderTakeFinish(List<OrderTakeVo> datas,OrderInfo order);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					using MasaBlazorApp3.Pojo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MasaBlazorApp3.DataAccess.Dao
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public interface IUserDao
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int InsertUser(User user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Task<PageData<User>> 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<bool> UpdateSign(int id, string sign);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<SettingConfig> setting, GlobalStateService globalStateService, PortUtil portUtil)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _globalStateService = globalStateService;
 | 
				
			||||||
 | 
					            _connection = connection;
 | 
				
			||||||
 | 
					            _setting = setting.Value;
 | 
				
			||||||
 | 
					            _portUtil = portUtil;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<PageData<ChannelStock>> 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<ChannelStock> 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<ChannelStock>()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                TotalDesserts = pagedData,
 | 
				
			||||||
 | 
					                Desserts = list
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<List<ChannelStock>> 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<List<ChannelStock>> 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<List<ChannelList>> 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<List<ChannelStock>> 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<List<ChannelList>> 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<bool> DrawerOperationFinish(List<ChannelStock> 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<ChannelStock> 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<bool> 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<bool> 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<PageMultiData<ChannelStock,DrugInfo>> 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<ChannelStock> 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<DrugInfo> drugInfos= await other
 | 
				
			||||||
 | 
					                .LoadWith(di => di.Manus)
 | 
				
			||||||
 | 
					                .OrderBy((di) => di.DrugId)
 | 
				
			||||||
 | 
					                .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return new PageMultiData<ChannelStock,DrugInfo>()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                TotalDesserts = pagedData,
 | 
				
			||||||
 | 
					                Desserts = list,
 | 
				
			||||||
 | 
					                Other= drugInfos
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        //抽屉加药、取药获取数据
 | 
				
			||||||
 | 
					        public async Task<ChannelStockWithDrawerCount<ChannelStock>> 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<ChannelStock> channelStocks= await query
 | 
				
			||||||
 | 
					               .OrderBy((cs) => cs.DrawerNo)
 | 
				
			||||||
 | 
					               .ThenBy((cs) => cs.ColNo)
 | 
				
			||||||
 | 
					               .ToListAsync();
 | 
				
			||||||
 | 
					            return new ChannelStockWithDrawerCount<ChannelStock>() { DrawerArray = ints, ChannelStocks = channelStocks };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        //盘点
 | 
				
			||||||
 | 
					        public async Task<bool> DrawerCheckFinish(List<ChannelStock> 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<ChannelStock> 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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<SettingConfig> setting)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _connection = connection;
 | 
				
			||||||
 | 
					            _setting = setting.Value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public async Task<List<DrugInfo>> 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<PageData<DrugInfo>> 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<DrugInfo> list = await query
 | 
				
			||||||
 | 
					                .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return new PageData<DrugInfo>()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                TotalDesserts = pagedData,
 | 
				
			||||||
 | 
					                Desserts = list
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<List<DrugInfo>> GetAllDrug()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var query = _connection.DrugInfo.AsQueryable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return await query
 | 
				
			||||||
 | 
					                .LoadWith(di => di.Manus)
 | 
				
			||||||
 | 
					                .OrderBy((di) => di.DrugId)
 | 
				
			||||||
 | 
					                .ToListAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<DrugManuNo> 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<bool> 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<bool> 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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<SettingConfig> setting, GlobalStateService globalStateService, PortUtil portUtil)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _connection = connection;
 | 
				
			||||||
 | 
					            _setting = setting.Value;
 | 
				
			||||||
 | 
					            _globalStateService = globalStateService;
 | 
				
			||||||
 | 
					            _portUtil = portUtil;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public async Task<PageData<InOutInvoice>> 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<InOutInvoice>($@"
 | 
				
			||||||
 | 
					            //    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 <InOutInvoice> list = await query3
 | 
				
			||||||
 | 
					                .OrderByDescending(ioi => ioi.CreateTime)
 | 
				
			||||||
 | 
					                .Skip((int)skip)
 | 
				
			||||||
 | 
					                .Take((int)take)
 | 
				
			||||||
 | 
					                .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int pagedData = await query3.CountAsync();
 | 
				
			||||||
 | 
					            return new PageData<InOutInvoice>()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                TotalDesserts = pagedData,
 | 
				
			||||||
 | 
					                Desserts = list
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public async Task<DrugManuNo> 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<List<ChannelStock>> 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<List<InOutInvoice>> 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<DrugInfo> getDrugInfoById(string DrugId)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return await _connection.DrugInfo.Where(di => di.DrugId == DrugId).FirstOrDefaultAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<List<InvoiceVo>> getTakeInfoByInvoiceNo(string invoiceNo)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<InvoiceVo> tempData = new();
 | 
				
			||||||
 | 
					            var flag = true;
 | 
				
			||||||
 | 
					            List<InOutInvoice> details = await this.getInvoiceByInvoiceNo(invoiceNo);
 | 
				
			||||||
 | 
					            for (var i = 0; i < details.Count; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //List<IDictionary<string, object>> tempData = new();
 | 
				
			||||||
 | 
					                InOutInvoice detail = details[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                DrugInfo Drug = await this.getDrugInfoById(detail.DrugId);
 | 
				
			||||||
 | 
					                // 当前detail取药数量
 | 
				
			||||||
 | 
					                var Quantity = detail.quantity;
 | 
				
			||||||
 | 
					                List<ChannelStock> 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<List<InvoiceVo>> getAddInfoByInvoiceNo(string invoiceNo)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<InvoiceVo> tempData = new();
 | 
				
			||||||
 | 
					            List<InOutInvoice> details = await this.getInvoiceByInvoiceNo(invoiceNo);
 | 
				
			||||||
 | 
					            for (var i = 0; i < details.Count; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //List<IDictionary<string, object>> tempData = new();
 | 
				
			||||||
 | 
					                InOutInvoice detail = details[i];
 | 
				
			||||||
 | 
					                List<ChannelStock> 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<bool> InvoiceOutFinish(List<InvoiceVo> 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<ChannelStock> 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<ChannelStock> 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<bool> InvoiceAddFinish(List<InvoiceVo> 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<ChannelStock> 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<ChannelStock> 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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<SettingConfig> setting, PortUtil portUtil)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _connection = connection;
 | 
				
			||||||
 | 
					            _setting = setting.Value;
 | 
				
			||||||
 | 
					            _portUtil = portUtil;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<List<ChannelStock>> 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<List<ChannelStock>> 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<PageData<MachineRecord>> 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<MachineRecord> 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<MachineRecord>() { Desserts = MachineRecords, TotalDesserts = pagedData };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<PageData<MachineRecord>> 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<MachineRecord> 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<MachineRecord>() { Desserts = MachineRecords, TotalDesserts = pagedData };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int InsertMachineRecord(MachineRecord record)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            record.MachineId = _setting.machineId;
 | 
				
			||||||
 | 
					            return _connection.InsertWithInt32Identity(record);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public async Task<List<OperationVo<List<MachineRecord>>>> getReturnDrugInfoByRecords(List<MachineRecord> records)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<OperationVo<List<MachineRecord>>> 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<ChannelStock> stockList = await this.GetChannelStockByDrugId(record.DrugId, record.ManuNo);
 | 
				
			||||||
 | 
					                    List<ChannelStock> 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<List<MachineRecord>>()
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Drug = record.Drug,
 | 
				
			||||||
 | 
					                        ChannelStocks = stockList,
 | 
				
			||||||
 | 
					                        data = new List<MachineRecord> { record },
 | 
				
			||||||
 | 
					                        Quantity = record.CurrentReturnQuantity,
 | 
				
			||||||
 | 
					                        StockQuantity = total,
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return list;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<bool> ReturnDrugFinish(List<OperationVo<List<MachineRecord>>> 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<List<ChannelStock>> GetReturnEmpty()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<ChannelStock> 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<MachineRecord> 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<MachineRecord>() { Desserts = MachineRecords, TotalDesserts = pagedData };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public async Task<PageData<MachineRecord>> getReturnEmptyInfoByRecords(ChannelStock records)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<MachineRecord> 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<MachineRecord>() { Desserts = machineRecords, TotalDesserts = pagedData };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public async Task<bool> ReturnEmptyFinish(List<MachineRecord> 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<List<ChannelStock>> GetReturnEmptyWithCanReturnQuantiy()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<ChannelStock> 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
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<SettingConfig> setting, GlobalStateService globalStateService,PortUtil portUtil)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _connection = connection;
 | 
				
			||||||
 | 
					            _setting = setting.Value;
 | 
				
			||||||
 | 
					            _globalStateService = globalStateService;
 | 
				
			||||||
 | 
					            _portUtil = portUtil;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<PageData<OrderInfo>> GetAllOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //var query = _connection.OrderInfo.AsQueryable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //query.InnerJoin<OrderDetail>((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<OrderInfo> list = await query
 | 
				
			||||||
 | 
					                .OrderBy((oi) => oi.RecvDate)
 | 
				
			||||||
 | 
					                .ThenBy((oi => oi.OrderNo))
 | 
				
			||||||
 | 
					                .Skip((int)skip)
 | 
				
			||||||
 | 
					                .Take((int)take)
 | 
				
			||||||
 | 
					                .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return new PageData<OrderInfo>()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                TotalDesserts = pagedData,
 | 
				
			||||||
 | 
					                Desserts = list
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<List<OrderDetail>> 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<List<ChannelStock>> 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<List<OrderTakeVo>> getTakeInfoByOrderNo(string OrderrNo)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<OrderTakeVo> tempData = new();
 | 
				
			||||||
 | 
					            List<OrderTakeVo> tempData2 = new();
 | 
				
			||||||
 | 
					            List<OrderDetail> details = await this.getDetailByOrderNo(OrderrNo);
 | 
				
			||||||
 | 
					            var flag = true;
 | 
				
			||||||
 | 
					            for (var i = 0; i < details.Count; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //List<IDictionary<string, object>> tempData = new();
 | 
				
			||||||
 | 
					                OrderDetail detail = details[i];
 | 
				
			||||||
 | 
					                // 当前detail取药数量
 | 
				
			||||||
 | 
					                var Quantity = detail.Quantity;
 | 
				
			||||||
 | 
					                List<ChannelStock> 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<bool> OrderTakeFinish(List<OrderTakeVo> 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<ChannelStock> 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<PageData<OrderInfo>> 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<OrderInfo> list = await query
 | 
				
			||||||
 | 
					                .OrderBy((oi) => oi.RecvDate)
 | 
				
			||||||
 | 
					                .ThenBy((oi => oi.OrderNo))
 | 
				
			||||||
 | 
					                .Skip((int)skip)
 | 
				
			||||||
 | 
					                .Take((int)take)
 | 
				
			||||||
 | 
					                .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return new PageData<OrderInfo>()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                TotalDesserts = pagedData,
 | 
				
			||||||
 | 
					                Desserts = list
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<List<MachineRecord>> 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<List<OperationVo<MachineRecord>>> getReturnInfoByOrderNo(string OrderrNo)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<OperationVo<MachineRecord>> tempData = new();
 | 
				
			||||||
 | 
					            List<MachineRecord> details = await this.GetMachineRecordByOrderNo(OrderrNo);
 | 
				
			||||||
 | 
					            for (var i = 0; i < details.Count; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //List<IDictionary<string, object>> tempData = new();
 | 
				
			||||||
 | 
					                MachineRecord detail = details[i];
 | 
				
			||||||
 | 
					                List<ChannelStock> 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<MachineRecord>()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Drug = detail.Drug,
 | 
				
			||||||
 | 
					                    data = detail,
 | 
				
			||||||
 | 
					                    StockQuantity = total,
 | 
				
			||||||
 | 
					                    Quantity = Quantity,
 | 
				
			||||||
 | 
					                    ChannelStocks = stockList,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return tempData;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<DrugManuNo> 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<bool> OrderReturnFinish(List<OperationVo<MachineRecord>> 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<ChannelStock> 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<ChannelStock> 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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<SettingConfig> setting) { _connection = connection; _setting = setting.Value; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<Role> 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<PageData<Role>> 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<Role> list = await query
 | 
				
			||||||
 | 
					                .OrderBy(r => r.Id)
 | 
				
			||||||
 | 
					                .Skip((int)skip)
 | 
				
			||||||
 | 
					                .Take((int)take)
 | 
				
			||||||
 | 
					                .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int pagedData = await query.CountAsync();
 | 
				
			||||||
 | 
					            return new PageData<Role>()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                TotalDesserts = pagedData,
 | 
				
			||||||
 | 
					                Desserts = list
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<List<Role>> GetAllRoles()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return await _connection.Role.Where(r => r.MachineId == _setting.machineId).ToListAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<SettingConfig> setting, GlobalStateService globalStateService, PortUtil portUtil)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _connection = connection;
 | 
				
			||||||
 | 
					            _setting = setting.Value;
 | 
				
			||||||
 | 
					            _globalStateService = globalStateService;
 | 
				
			||||||
 | 
					            _portUtil = portUtil;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 根据药品信息 获取药品库存信息
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="drugInfos"></param>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public async Task<List<ChannelStock>> GetChannelStocksByDrug(List<DrugInfo> drugInfos)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<ChannelStock> channelStocks = new List<ChannelStock>();
 | 
				
			||||||
 | 
					            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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 根据药品明细获取数据
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="orderDetails"></param>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public async Task<List<OrderTakeVo>> getTakeInfoByOrderNo(List<OrderDetail> orderDetails)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            List<OrderTakeVo> tempData = new();
 | 
				
			||||||
 | 
					            List<OrderTakeVo> tempData2 = new();
 | 
				
			||||||
 | 
					            var flag = true;
 | 
				
			||||||
 | 
					            for (var i = 0; i < orderDetails.Count; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //List<IDictionary<string, object>> tempData = new();
 | 
				
			||||||
 | 
					                OrderDetail detail = orderDetails[i];
 | 
				
			||||||
 | 
					                // 当前detail取药数量
 | 
				
			||||||
 | 
					                var Quantity = detail.Quantity;
 | 
				
			||||||
 | 
					                List<ChannelStock> 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<List<ChannelStock>> 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();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 保存自选取药完成数据
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="datas"></param>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public async Task<bool> OrderTakeFinish(List<OrderTakeVo> datas, OrderInfo order)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _connection.BeginTransaction();
 | 
				
			||||||
 | 
					                var flag = true;
 | 
				
			||||||
 | 
					                // 保存处方信息
 | 
				
			||||||
 | 
					                order.Status = 1;
 | 
				
			||||||
 | 
					                order.PatientId = order.PatientId == null ? "0" : order.PatientId;
 | 
				
			||||||
 | 
					                int r1 = _connection.InsertWithInt32Identity<OrderInfo>(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<OrderDetail>(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<ChannelStock> 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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<SettingConfig> setting)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _connection = connection;
 | 
				
			||||||
 | 
					            _setting = setting.Value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<PageData<User>> 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<User> 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<User>()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                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<bool> 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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<T>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public int TotalDesserts { get; set; }
 | 
				
			||||||
 | 
					        public List<T> Desserts { get; set; } = new List<T>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<T,S>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public int TotalDesserts { get; set; }
 | 
				
			||||||
 | 
					        public List<T> Desserts { get; set; } = new List<T>();
 | 
				
			||||||
 | 
					        public List<S> Other { get; set; } = new List<S>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<FingerPojo> 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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
 | 
					        //{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,96 @@
 | 
				
			||||||
 | 
					<Project Sdk="Microsoft.NET.Sdk.Razor">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <PropertyGroup>
 | 
				
			||||||
 | 
						<OutputType>WinExe</OutputType>
 | 
				
			||||||
 | 
					        <TargetFramework>net7.0</TargetFramework>
 | 
				
			||||||
 | 
					        <ImplicitUsings>enable</ImplicitUsings>
 | 
				
			||||||
 | 
					        <Nullable>enable</Nullable>
 | 
				
			||||||
 | 
					        <ApplicationIcon>favicon.ico</ApplicationIcon>
 | 
				
			||||||
 | 
					    </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <ItemGroup>
 | 
				
			||||||
 | 
					      <COMReference Include="zkemkeeper">
 | 
				
			||||||
 | 
					        <WrapperTool>tlbimp</WrapperTool>
 | 
				
			||||||
 | 
					        <VersionMinor>0</VersionMinor>
 | 
				
			||||||
 | 
					        <VersionMajor>1</VersionMajor>
 | 
				
			||||||
 | 
					        <Guid>fe9ded34-e159-408e-8490-b720a5e632c7</Guid>
 | 
				
			||||||
 | 
					        <Lcid>0</Lcid>
 | 
				
			||||||
 | 
					        <Isolated>false</Isolated>
 | 
				
			||||||
 | 
					        <EmbedInteropTypes>False</EmbedInteropTypes>
 | 
				
			||||||
 | 
					      </COMReference>
 | 
				
			||||||
 | 
					      <COMReference Include="gregn6Lib">
 | 
				
			||||||
 | 
					        <WrapperTool>tlbimp</WrapperTool>
 | 
				
			||||||
 | 
					        <VersionMinor>0</VersionMinor>
 | 
				
			||||||
 | 
					        <VersionMajor>6</VersionMajor>
 | 
				
			||||||
 | 
					        <Guid>4018f953-1bfe-441e-8a04-dc8ba1ff060e</Guid>
 | 
				
			||||||
 | 
					        <Lcid>0</Lcid>
 | 
				
			||||||
 | 
					        <Isolated>false</Isolated>
 | 
				
			||||||
 | 
					        <EmbedInteropTypes>False</EmbedInteropTypes>
 | 
				
			||||||
 | 
					      </COMReference>
 | 
				
			||||||
 | 
					    </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
							<PackageReference Include="FluentValidation" Version="11.9.1" />
 | 
				
			||||||
 | 
							<PackageReference Include="linq2db.AspNet" Version="5.4.1" />
 | 
				
			||||||
 | 
							<PackageReference Include="log4net" Version="2.0.17" />
 | 
				
			||||||
 | 
							<PackageReference Include="MySql.Data" Version="8.4.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
 | 
				
			||||||
 | 
							<PackageReference Include="Photino.Blazor" Version="2.7.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="Radzen.Blazor" Version="4.32.1" />
 | 
				
			||||||
 | 
							<PackageReference Include="SharpPromise" Version="1.7.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="SuperSimpleTcp" Version="3.0.14" />
 | 
				
			||||||
 | 
							<PackageReference Include="System.IO.Ports" Version="8.0.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="System.Management" Version="8.0.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="System.Speech" Version="8.0.0" />
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
							<Content Update="wwwroot\**">
 | 
				
			||||||
 | 
								<CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
							</Content>
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
						  <Content Update="log4net.config">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </Content>
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
						  <None Remove="i18ntext\MyText.zh.json" />
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
						  <None Remove="i18ntext\MyText.en.json" />
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
						  <Content Include="favicon.ico">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </Content>
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
						  <None Update="favicon.ico">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </None>
 | 
				
			||||||
 | 
						  <None Update="ReportTemp\account_book_temp.grf">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </None>
 | 
				
			||||||
 | 
						  <None Update="ReportTemp\machine_log_add.grf">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </None>
 | 
				
			||||||
 | 
						  <None Update="ReportTemp\machine_log_check.grf">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </None>
 | 
				
			||||||
 | 
						  <None Update="ReportTemp\machine_log_return.grf">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </None>
 | 
				
			||||||
 | 
						  <None Update="ReportTemp\machine_log_take.grf">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </None>
 | 
				
			||||||
 | 
						  <None Update="ReportTemp\stock_template.grf">
 | 
				
			||||||
 | 
						    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 | 
				
			||||||
 | 
						  </None>
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    .rz-custom-header {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Orientation="Orientation.Horizontal">
 | 
				
			||||||
 | 
					    <div class="row  justify-content-center">
 | 
				
			||||||
 | 
					        @if (DrawerNos.Count() > 8)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <div class="col-12 row justify-content-center align-items-center text-center" style="background: url('/images/box-16.jpg')  no-repeat; background-size: 100% 100%; width: 380px; height:650px">
 | 
				
			||||||
 | 
					                <div class="row justify-content-around align-items-center" style="margin-top: 220px; height: 430px;">
 | 
				
			||||||
 | 
					                    @foreach (int i in DrawerNos)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenButton class="col-5" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <div class="col-12 row justify-content-center align-items-center text-center" style="background: url('/images/box.png')  no-repeat; background-size: 100% 100%; width: 380px; height:650px">
 | 
				
			||||||
 | 
					                <div class="row justify-content-around align-items-center" style="margin-top: 220px; height: 430px;">
 | 
				
			||||||
 | 
					                    @foreach (int i in DrawerNos)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenButton class="col-12" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					    LoadData="@LoadData"
 | 
				
			||||||
 | 
					    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					    Count="@count"
 | 
				
			||||||
 | 
					    EmptyText="无数据"
 | 
				
			||||||
 | 
					    Data="@channels"
 | 
				
			||||||
 | 
					    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					    CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args))"
 | 
				
			||||||
 | 
					    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					        <HeaderTemplate>
 | 
				
			||||||
 | 
					            <RadzenRow JustifyContent="JustifyContent.End">
 | 
				
			||||||
 | 
					                <RadzenButton IsBusy="@(status>0)" BusyText="抽屉已打开。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Outlined" Shade="Shade.Light" Text="开抽屉" Click="@OpenDrawer" />
 | 
				
			||||||
 | 
					            </RadzenRow>
 | 
				
			||||||
 | 
					        </HeaderTemplate>
 | 
				
			||||||
 | 
					        <Columns>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Width="70px" Title="库位" Property="ColNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="药品名称" Property="Drug.DrugName">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.Drug?.DrugName</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Caption">@channel.Drug?.DrugSpec</RadzenText>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="批次" Property="ManuNo">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Caption">@channel.drugManuNo?.EffDate</RadzenText>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					                <EditTemplate Context="channel">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    @if (channel.Quantity == 0 && !String.IsNullOrEmpty(channel.DrugId))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenDropDown TValue="DrugManuNo" Name="ManuNo" @bind-Value="channel.drugManuNo" Data="@channel.Drug?.Manus" Style="width:100%; display: block;">
 | 
				
			||||||
 | 
					                            <Template>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                            <ValueTemplate>
 | 
				
			||||||
 | 
					                                <RadzenStack Orientation="Orientation.Horizontal">
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
 | 
				
			||||||
 | 
					                                </RadzenStack>
 | 
				
			||||||
 | 
					                            </ValueTemplate>
 | 
				
			||||||
 | 
					                        </RadzenDropDown>
 | 
				
			||||||
 | 
					                        <RadzenRequiredValidator Text="请选择批次" Component="ManuNo" Popup="true" />
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                        <RadzenText TextStyle="TextStyle.Caption">@channel.drugManuNo?.EffDate</RadzenText>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </EditTemplate>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="库存" Property="Quantity">
 | 
				
			||||||
 | 
					                <Template Context="cs">
 | 
				
			||||||
 | 
					                    <RadzenButton ButtonStyle="ButtonStyle.Info" Variant="Variant.Flat" Shade="Shade.Lighter" class="m-1" Text="@cs.Quantity.ToString()" />
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn MinWidth="100px" Title="加药数量" Property="AddQuantity">
 | 
				
			||||||
 | 
					                <EditTemplate Context="cs">
 | 
				
			||||||
 | 
					                    @if (cs.BoardType == 2)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        @cs.AddQuantity
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenNumeric Min="0" Style="display: block" Name="Quantity" @bind-Value=@cs.AddQuantity />
 | 
				
			||||||
 | 
					                        <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Text="请填写正确的添加数量" Component="Quantity" Popup="true" />
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </EditTemplate>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        </Columns>
 | 
				
			||||||
 | 
					    </RadzenDataGrid>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IChannelListDao channelListDao;
 | 
				
			||||||
 | 
					    @inject NavigationManager na;
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					    int drawerNo = 1;
 | 
				
			||||||
 | 
					    RadzenDataGrid<ChannelStock> grid;
 | 
				
			||||||
 | 
					    private List<ChannelStock>? 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<int> ColNos { get; set; } = new List<int>();
 | 
				
			||||||
 | 
					    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<object>();
 | 
				
			||||||
 | 
					        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<ChannelStock> args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (args.Data.BoardType.ToString().Contains("3"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //是药盒抽屉则点击行,打开对应行的药箱
 | 
				
			||||||
 | 
					            if (!ColNos.Contains(args.Data.ColNo))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ColNos.Add(args.Data.ColNo);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            grid.EditRow(args.Data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <RadzenText TextStyle="TextStyle.Body1" Style="color: var(--rz-text-tertiary-color); align-content:center; text-align:center; font-size:medium;">确认要@(confirmInfo) 吗?</RadzenText>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
 | 
				
			||||||
 | 
					        <RadzenButton Click="@ConfirmOK" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="确认" Style="width: 120px" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <RadzenButton Click="@((args) => dialogService.Close(false))" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,446 @@
 | 
				
			||||||
 | 
					@page "/add/drawer"
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Pojo.Config;
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Util;
 | 
				
			||||||
 | 
					@using Microsoft.Extensions.Options;
 | 
				
			||||||
 | 
					@using Newtonsoft.Json;
 | 
				
			||||||
 | 
					@using log4net;
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    .rz-custom-header {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<RadzenStack Orientation="Orientation.Horizontal">
 | 
				
			||||||
 | 
					    <div class="row  justify-content-center">
 | 
				
			||||||
 | 
					        <div class="col-12 row justify-content-center align-items-center text-center" style="background: url('/images/box.png')  no-repeat; background-size: 100% 100%; width: 380px; height:650px">
 | 
				
			||||||
 | 
					            @* <RadzenStack AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center" Orientation="Orientation.Vertical" Style="margin-top: 220px"> *@
 | 
				
			||||||
 | 
					            <div class="row justify-content-around align-items-center" style="margin-top: 220px; height: 430px;">
 | 
				
			||||||
 | 
					                @foreach (int i in DrawerNos)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton class="col-5" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            @* </RadzenStack> *@
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					    LoadData="@LoadData"
 | 
				
			||||||
 | 
					    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					    Count="@count"
 | 
				
			||||||
 | 
					    EmptyText="无数据"
 | 
				
			||||||
 | 
					    Data="@channels"
 | 
				
			||||||
 | 
					    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					    CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args))"
 | 
				
			||||||
 | 
					    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					        <HeaderTemplate>
 | 
				
			||||||
 | 
					            <RadzenRow JustifyContent="JustifyContent.End">
 | 
				
			||||||
 | 
					                @if (status < 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton IsBusy="@(status>0)" BusyText="加药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Outlined" Shade="Shade.Light" Text="加药" Click="@OpenDrawer" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @if (status == 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton Visible="@CompleteIsEnable" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Outlined" Shade="Shade.Light" Text="完成" Click="@AddFinish" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @if (status > 0 && status <= 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton Visible="@CancleIsEnable" Variant="Variant.Flat" Text="取消" Click="@Cancel" Style="width: 120px" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </RadzenRow>
 | 
				
			||||||
 | 
					        </HeaderTemplate>
 | 
				
			||||||
 | 
					        <Columns>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Width="70px" Title="库位" Property="ColNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="药品名称" Property="Drug.DrugName">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.Drug?.DrugName</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Caption">@channel.Drug?.DrugSpec</RadzenText>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="批次" Property="ManuNo">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Caption">@channel.drugManuNo?.EffDate</RadzenText>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					                <EditTemplate Context="channel">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    @if (channel.Quantity == 0 && !String.IsNullOrEmpty(channel.DrugId))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenDropDown TValue="DrugManuNo" Name="ManuNo" @bind-Value="channel.drugManuNo" Data="@channel.Drug?.Manus" Style="width:100%; display: block;">
 | 
				
			||||||
 | 
					                            <Template>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                            <ValueTemplate>
 | 
				
			||||||
 | 
					                                <RadzenStack Orientation="Orientation.Horizontal">
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
 | 
				
			||||||
 | 
					                                </RadzenStack>
 | 
				
			||||||
 | 
					                            </ValueTemplate>
 | 
				
			||||||
 | 
					                        </RadzenDropDown>
 | 
				
			||||||
 | 
					                        <RadzenRequiredValidator Text="请选择批次" Component="ManuNo" Popup="true" />
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                        <RadzenText TextStyle="TextStyle.Caption">@channel.drugManuNo?.EffDate</RadzenText>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </EditTemplate>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="库存" Property="Quantity">
 | 
				
			||||||
 | 
					                <Template Context="cs">
 | 
				
			||||||
 | 
					                    <RadzenButton ButtonStyle="ButtonStyle.Info" Variant="Variant.Flat" Shade="Shade.Lighter" class="m-1" Text="@cs.Quantity.ToString()" />
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn MinWidth="100px" Title="加药数量" Property="AddQuantity">
 | 
				
			||||||
 | 
					                <EditTemplate Context="cs">
 | 
				
			||||||
 | 
					                    @if (cs.BoardType == 2)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        @cs.AddQuantity
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenNumeric Min="0" Style="display: block" Name="Quantity" @bind-Value=@cs.AddQuantity />
 | 
				
			||||||
 | 
					                        <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Text="请填写正确的添加数量" Component="Quantity" Popup="true" />
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </EditTemplate>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        </Columns>
 | 
				
			||||||
 | 
					    </RadzenDataGrid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IChannelListDao channelListDao;
 | 
				
			||||||
 | 
					    @inject NavigationManager na;
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					    int drawerNo = 1;
 | 
				
			||||||
 | 
					    RadzenDataGrid<ChannelStock> grid;
 | 
				
			||||||
 | 
					    private List<ChannelStock>? 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<int> ColNos { get; set; } = new List<int>();
 | 
				
			||||||
 | 
					    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<object>();
 | 
				
			||||||
 | 
					        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<int[]> finallyQuantity = new List<int[]>();
 | 
				
			||||||
 | 
					        await new PromiseUtil<int>().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<int[]> 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<ChannelStock> 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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,445 @@
 | 
				
			||||||
 | 
					@page "/take/drawer"
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Pojo.Config;
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Util;
 | 
				
			||||||
 | 
					@using Microsoft.Extensions.Options;
 | 
				
			||||||
 | 
					@using Newtonsoft.Json;
 | 
				
			||||||
 | 
					@using log4net;
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    .rz-custom-header {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<RadzenStack Orientation="Orientation.Horizontal">
 | 
				
			||||||
 | 
					    @* <div class="row  justify-content-center align-items-center">
 | 
				
			||||||
 | 
					        <div class="col-12 row justify-content-center align-items-center text-center" style="background: url('/images/box.png')  no-repeat; background-size: 100% 100%; width: 240px; height:650px">
 | 
				
			||||||
 | 
					            <RadzenStack AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center" Orientation="Orientation.Vertical" Style="margin-top: 220px">
 | 
				
			||||||
 | 
					                @foreach (int i in DrawerNos)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton class="col-5" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </RadzenStack>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div> *@
 | 
				
			||||||
 | 
					    <div class="row  justify-content-center">
 | 
				
			||||||
 | 
					        <div class="col-12 row justify-content-center align-items-center text-center" style="background: url('/images/box.png')  no-repeat; background-size: 100% 100%; width: 380px; height:650px">
 | 
				
			||||||
 | 
					            @* <RadzenStack AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center" Orientation="Orientation.Vertical" Style="margin-top: 220px"> *@
 | 
				
			||||||
 | 
					            <div class="row justify-content-around align-items-center" style="margin-top: 220px; height: 430px;">
 | 
				
			||||||
 | 
					                @foreach (int i in DrawerNos)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton class="col-5" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            @* </RadzenStack> *@
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					    LoadData="@LoadData"
 | 
				
			||||||
 | 
					    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					    Count="@count"
 | 
				
			||||||
 | 
					    EmptyText="无数据"
 | 
				
			||||||
 | 
					    Data="@channels"
 | 
				
			||||||
 | 
					    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					    CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args))"
 | 
				
			||||||
 | 
					    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					        <HeaderTemplate>
 | 
				
			||||||
 | 
					            <RadzenRow JustifyContent="JustifyContent.End">
 | 
				
			||||||
 | 
					                @if (status < 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton IsBusy="@(status>0)" BusyText="取药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="取药" Click="@OpenDrawer" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @if (status == 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton Visible="@CompleteIsEnable"  ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="完成" Click="@TakeFinish" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @if (status > 0 && status <= 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton Visible="@CancleIsEnable" Variant="Variant.Flat" Text="取消" Click="@Cancel" Style="width: 120px" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </RadzenRow>
 | 
				
			||||||
 | 
					        </HeaderTemplate>
 | 
				
			||||||
 | 
					        <Columns>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Width="70px" Title="库位" Property="ColNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="药品名称" Property="Drug.DrugName">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.Drug.DrugName</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Caption">@channel.Drug.DrugSpec</RadzenText>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="批次" Property="ManuNo">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Caption">@channel.EffDate</RadzenText>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="库存" Property="Quantity">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenButton ButtonStyle="ButtonStyle.Info" Size="ButtonSize.Medium" Variant="Variant.Flat" Shade="Shade.Lighter" class="m-1" Text="@channel.Quantity.ToString()" />
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn MinWidth="120px" Title="取药数量" Property="TakeQuantity">
 | 
				
			||||||
 | 
					                <EditTemplate Context="channel">
 | 
				
			||||||
 | 
					                    @if (channel.BoardType == 2)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        @channel.TakeQuantity
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenNumeric Style="display: block" Min="0" Max="@channel.Quantity" Name="Quantity" @bind-Value=@channel.TakeQuantity />
 | 
				
			||||||
 | 
					                        @* <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Max="@cs.Quantity" Text="请填写正确的取出数量" Component="Quantity" Popup="true" /> *@
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </EditTemplate>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        </Columns>
 | 
				
			||||||
 | 
					    </RadzenDataGrid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IChannelListDao channelListDao;
 | 
				
			||||||
 | 
					    @inject NavigationManager na;
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					    int drawerNo = 1;
 | 
				
			||||||
 | 
					    RadzenDataGrid<ChannelStock> grid;
 | 
				
			||||||
 | 
					    private List<ChannelStock>? 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<int> ColNos { get; set; } = new List<int>();
 | 
				
			||||||
 | 
					    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<object>();
 | 
				
			||||||
 | 
					        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<int[]> finallyQuantity = new List<int[]>();
 | 
				
			||||||
 | 
					        await new PromiseUtil<int>().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<int[]> 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<ChannelStock> 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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,338 @@
 | 
				
			||||||
 | 
					@page "/stock/drug"
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    .rz-custom-header {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12  mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="药品编码" Component="DrugId" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenTextBox @bind-Value="DrugId" Style="width: 100%;" Name="DrugId"></RadzenTextBox>
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="药品名称" Component="DrugName" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenTextBox @bind-Value="DrugName" Style="width: 100%;" Name="DrugName"></RadzenTextBox>
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" ButtonStyle="ButtonStyle.Success" Icon="add_circle_outline" Click="@InsertDrugRow" Text="新增药品" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-6  mb-4">
 | 
				
			||||||
 | 
					            <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					            LoadData="@LoadData"
 | 
				
			||||||
 | 
					            @bind-Value="@SelectedDrugs"
 | 
				
			||||||
 | 
					            IsLoading="@isLoading"
 | 
				
			||||||
 | 
					            Count="@count"
 | 
				
			||||||
 | 
					            EmptyText="无数据"
 | 
				
			||||||
 | 
					            Data="@_forecasts"
 | 
				
			||||||
 | 
					            AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					            SelectionMode="DataGridSelectionMode.Single" RowUpdate="@((DrugInfo di)=>{OnDrugUpdateRow(di);})" RowCreate="@((DrugInfo di)=>{OnDrugCreateRow(di);})"
 | 
				
			||||||
 | 
					            AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ColumnWidth="100px" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Frozen="true" Title="编码" Property="DrugId">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="drugInfo">
 | 
				
			||||||
 | 
					                            <RadzenTextBox Name="DrugId" @bind-Value="drugInfo.DrugId" Style="width:100%; display: block;" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Text="请填写编码" Component="DrugId" Popup="true" />
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Width="200px" Title="药品名称" Property="DrugName">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="drugInfo">
 | 
				
			||||||
 | 
					                            <RadzenTextBox Name="DrugName" @bind-Value="drugInfo.DrugName" Style="width:100%;display:block;" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Text="请填写药品名称" Component="DrugName" Popup="true"/>
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="规格" Property="DrugSpec">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="drugInfo">
 | 
				
			||||||
 | 
					                            <RadzenTextBox Name="DrugSpec" @bind-Value="drugInfo.DrugSpec" Style="width:100%;display:block;" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Text="请填写规格" Component="DrugSpec" Popup="true"/>
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn  Width="200px"  Title="厂家" Property="Manufactory">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="drugInfo">
 | 
				
			||||||
 | 
					                            <RadzenTextBox Name="Manufactory" @bind-Value="drugInfo.Manufactory" Style="width:100%;display:block;" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Text="请填写厂家" Component="Manufactory" Popup="true"/>
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Context="drugInfo" Title="操作" Filterable="false" Sortable="false" TextAlign="TextAlign.Left" Frozen="true" FrozenPosition="FrozenColumnPosition.Right">
 | 
				
			||||||
 | 
					                        <Template Context="drugInfo">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@(args => EditDrugRow(drugInfo))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteDrugRow(drugInfo))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                        <EditTemplate Context="drugInfo">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => SaveDrugRow(drugInfo))" aria-label="Save">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@((args) => CancelDrugEdit(drugInfo))" aria-label="Cancel">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteDrugRow(drugInfo))" aria-label="Delete">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-6  mb-4">
 | 
				
			||||||
 | 
					            @*     <RadzenCard Style="margin-bottom:20px">
 | 
				
			||||||
 | 
					                批次列表
 | 
				
			||||||
 | 
					            </RadzenCard> *@
 | 
				
			||||||
 | 
					            @if (SelectedDrugs.Count > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                <RadzenDataGrid @ref="ManusGrid" EmptyText="无数据"
 | 
				
			||||||
 | 
					                Data="@(SelectedDrugs.FirstOrDefault()?.Manus)"
 | 
				
			||||||
 | 
					                RowUpdate="@((DrugManuNo dm) => { OnUpdateRow(dm); })" RowCreate="@((DrugManuNo dm) => { OnCreateRow(dm); })"
 | 
				
			||||||
 | 
					                AllowColumnResize="true" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					                    @* <HeaderTemplate>
 | 
				
			||||||
 | 
					                        <RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="download" Text="添加" Variant="Variant.Outlined" />
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </HeaderTemplate> *@
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="序号" Property="index">
 | 
				
			||||||
 | 
					                            <Template Context="data">
 | 
				
			||||||
 | 
					                                @(SelectedDrugs.FirstOrDefault()?.Manus.IndexOf(data) + 1)
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="批次" Property="ManuNo">
 | 
				
			||||||
 | 
					                            <EditTemplate Context="drugManuNo">
 | 
				
			||||||
 | 
					                                <RadzenTextBox Name="ManuNo" @bind-Value="drugManuNo.ManuNo" Style="width:100%; display: block;" />
 | 
				
			||||||
 | 
					                                <RadzenRequiredValidator Text="请填写批次" Component="ManuNo" Popup="true" />
 | 
				
			||||||
 | 
					                            </EditTemplate>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="效期" Property="EffDate">
 | 
				
			||||||
 | 
					                            <EditTemplate Context="drugManuNo">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd" @bind-Value="drugManuNo.EffDate" Style="width: 100%;" Name="EffDate" />
 | 
				
			||||||
 | 
					                                <RadzenRequiredValidator Text="请填写效期" Component="EffDate" Popup="true" />
 | 
				
			||||||
 | 
					                            </EditTemplate>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Context="drugManuNo" Title="操作" Filterable="false" Sortable="false" TextAlign="TextAlign.Left" Frozen="true" FrozenPosition="FrozenColumnPosition.Right">
 | 
				
			||||||
 | 
					                            <Template Context="drugManuNo">
 | 
				
			||||||
 | 
					                                <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@(args => EditRow(drugManuNo))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                                </RadzenButton>
 | 
				
			||||||
 | 
					                                <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(drugManuNo))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                                </RadzenButton>
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                            <EditTemplate Context="drugManuNo">
 | 
				
			||||||
 | 
					                                <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => SaveRow(drugManuNo))" aria-label="Save">
 | 
				
			||||||
 | 
					                                </RadzenButton>
 | 
				
			||||||
 | 
					                                <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@((args) => CancelEdit(drugManuNo))" aria-label="Cancel">
 | 
				
			||||||
 | 
					                                </RadzenButton>
 | 
				
			||||||
 | 
					                                <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(drugManuNo))" aria-label="Delete">
 | 
				
			||||||
 | 
					                                </RadzenButton>
 | 
				
			||||||
 | 
					                            </EditTemplate>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					                <div style="margin-top:5px">
 | 
				
			||||||
 | 
					                    <RadzenButton Size="ButtonSize.Medium" ButtonStyle="ButtonStyle.Success" Icon="add_circle_outline" Click="@InsertRow" Text="新增批次" />
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IDrugInfoDao drugInfoDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject IDrugManuNoDao drugManuNoDao;
 | 
				
			||||||
 | 
					    RadzenDataGrid<DrugInfo> grid;
 | 
				
			||||||
 | 
					    RadzenDataGrid<DrugManuNo> ManusGrid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<DrugManuNo> manuNoToInsert = new List<DrugManuNo>();
 | 
				
			||||||
 | 
					    List<DrugManuNo> manuNoToUpdate = new List<DrugManuNo>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<DrugInfo>? _forecasts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IList<DrugInfo> SelectedDrugs { get; set; } = new List<DrugInfo>();
 | 
				
			||||||
 | 
					    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<DrugInfo>() { _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<ConfirmDialo>(
 | 
				
			||||||
 | 
					               $"删除确认",
 | 
				
			||||||
 | 
					             new Dictionary<string, object>() { { "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<ConfirmDialo>(
 | 
				
			||||||
 | 
					                $"确认删除",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,70 @@
 | 
				
			||||||
 | 
					@page "/user/finger/{userId}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@using log4net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Gap="1.5rem">
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center">
 | 
				
			||||||
 | 
					        <RadzenLabel Text="选择手指" Component="DropDownBindValue" Style="margin-right: 8px; vertical-align: middle;" />
 | 
				
			||||||
 | 
					        <RadzenDropDown @bind-Value=@fingerName Data=@fingerNames Style="width: 100%; max-width: 400px;" Name="DropDownBindValue" />
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.SpaceBetween">
 | 
				
			||||||
 | 
					        <RadzenStack Orientation="Orientation.Horizontal">
 | 
				
			||||||
 | 
					            <RadzenButton IsBusy="@regLoading" Text="录入" Click="() => RegZWJSubmit()" Style="width: 80px;" />
 | 
				
			||||||
 | 
					            <RadzenButton Text="取消" Click="() => RegZWJCancel()" ButtonStyle="ButtonStyle.Light" />
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    [Parameter] public int userId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject FingerprintUtil FingerprintUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly ILog logger = LogManager.GetLogger(typeof(FingerRegDialog));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<string> fingerNames = new List<string>()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "左小拇指","左无名指","左中指", "左食指", "左大拇指", "右小拇指", "右无名指", "右中指" ,"右食指", "右大拇指"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,220 @@
 | 
				
			||||||
 | 
					@page "/home"
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Util
 | 
				
			||||||
 | 
					@using log4net
 | 
				
			||||||
 | 
					@layout EmptyLayout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    .home-menu{
 | 
				
			||||||
 | 
					        transition: box-shadow 0.3s ease; /* 平滑过渡阴影效果 */
 | 
				
			||||||
 | 
					        cursor: pointer;
 | 
				
			||||||
 | 
					        position: relative;
 | 
				
			||||||
 | 
					        z-index: 1;
 | 
				
			||||||
 | 
					        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.7);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .home-menu>h2{
 | 
				
			||||||
 | 
					        font-weight: bold;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .home-menu:hover {
 | 
				
			||||||
 | 
					        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.7); /* 阴影效果 */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .mask {
 | 
				
			||||||
 | 
					        position: absolute;
 | 
				
			||||||
 | 
					        top: 0;
 | 
				
			||||||
 | 
					        left: 0;
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        background-color: black;
 | 
				
			||||||
 | 
					        opacity: 0.6;
 | 
				
			||||||
 | 
					        z-index: 2;
 | 
				
			||||||
 | 
					        cursor: not-allowed;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .rz-gauge .rz-tick-text {
 | 
				
			||||||
 | 
					        fill: #ffffff !important;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<RadzenStack Orientation="Orientation.Vertical" class="rz-background-color-primary-light"  AlignItems="AlignItems.Center" Style="width:100vw;height:100vh" Gap="0">
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <RadzenRow Style="width:100vw;height:25vh;" Gap="0" RowGap="0">
 | 
				
			||||||
 | 
					        <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        </RadzenColumn>
 | 
				
			||||||
 | 
					        <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					            <RadzenRow Style="height: 100%;width:100%" Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                <RadzenColumn Size="3">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <RadzenText Style="" class="rz-color-white" TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">操作人:@Operator.NickName</RadzenText>
 | 
				
			||||||
 | 
					                    @if (Reviewer != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenText Style="" class="rz-color-white" TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">复核人:@Reviewer.NickName</RadzenText>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </RadzenColumn>
 | 
				
			||||||
 | 
					                <RadzenColumn Size="3">
 | 
				
			||||||
 | 
					                    <RadzenIcon Icon="exit_to_app" Style="font-size:3rem;cursor: pointer;" class="rz-ripple" IconColor="white" @onclick="@(() => { logout(); })" />
 | 
				
			||||||
 | 
					                </RadzenColumn>
 | 
				
			||||||
 | 
					            </RadzenRow>
 | 
				
			||||||
 | 
					        </RadzenColumn>
 | 
				
			||||||
 | 
					    </RadzenRow>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <RadzenStack class="rz-background-color-info-lighter" Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" AlignItems="AlignItems.Center" Style="width: 75vw;height: 57vh" Gap="20">
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <RadzenStack Style="height: 100%;width:41%" Gap="20">
 | 
				
			||||||
 | 
					            <RadzenStack class="home-menu rz-background-color-info-lighter rz-ripple" JustifyContent="JustifyContent.Center" Style="height: 50%" @onclick="@(() => jump2Page(1))">
 | 
				
			||||||
 | 
					                <RadzenText Style="" class="rz-color-white" TextStyle="TextStyle.H2" TextAlign="TextAlign.Center" >出库</RadzenText>
 | 
				
			||||||
 | 
					                @if (!Operator.role.permissionIds.Any(id => id - 10 < 10))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <div class="mask"> 
 | 
				
			||||||
 | 
					                        <RadzenImage Path="images/no_auth.png" />
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </RadzenStack>
 | 
				
			||||||
 | 
					            <RadzenStack class="home-menu rz-background-color-success-light rz-text-white rz-ripple" JustifyContent="JustifyContent.Center" @onclick="@(() => jump2Page(2))" Style="height: 50%">
 | 
				
			||||||
 | 
					                <RadzenText class="rz-color-white" TextStyle="TextStyle.H2" TextAlign="TextAlign.Center">入库</RadzenText>
 | 
				
			||||||
 | 
					                @if (!Operator.role.permissionIds.Any(id => id - 20 > 0 && id - 20 < 10))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <div class="mask"> 
 | 
				
			||||||
 | 
					                        <RadzenImage Path="images/no_auth.png" />
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </RadzenStack>
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					        <RadzenStack Style="height: 100%;width:59%" Gap="20">
 | 
				
			||||||
 | 
					            <RadzenStack class="home-menu rz-background-color-series-2 rz-text-white rz-ripple" JustifyContent="JustifyContent.Center" @onclick="@(() => jump2Page(3))" Style="height: 43%;width:100%">
 | 
				
			||||||
 | 
					                <RadzenText class="rz-color-white" TextStyle="TextStyle.H2" TextAlign="TextAlign.Center">归还</RadzenText>
 | 
				
			||||||
 | 
					                @if (!Operator.role.permissionIds.Any(id => id - 30 > 0 && id - 30 < 10))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <div class="mask"> 
 | 
				
			||||||
 | 
					                        <RadzenImage Path="images/no_auth.png" />
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </RadzenStack>
 | 
				
			||||||
 | 
					            <RadzenStack Orientation="Orientation.Horizontal"  Style="height: 57%;width:100%">
 | 
				
			||||||
 | 
					                <RadzenStack class="home-menu rz-background-color-primary rz-text-white rz-ripple" JustifyContent="JustifyContent.Center" @onclick="@(() => jump2Page(4))" Style="height: 100%;width:50%">
 | 
				
			||||||
 | 
					                    <RadzenText class="rz-color-white" TextStyle="TextStyle.H2" TextAlign="TextAlign.Center">库存管理</RadzenText>
 | 
				
			||||||
 | 
					                    @if (!Operator.role.permissionIds.Any(id => id - 40 > 0 && id - 40 < 10))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <div class="mask"> 
 | 
				
			||||||
 | 
					                            <RadzenImage Path="images/no_auth.png" />
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </RadzenStack>
 | 
				
			||||||
 | 
					                <RadzenStack class="home-menu rz-background-color-success-lighter rz-text-white rz-ripple" JustifyContent="JustifyContent.Center" @onclick="@(() => jump2Page(5))" Style="height: 100%;width:50%">
 | 
				
			||||||
 | 
					                    <RadzenText class="rz-color-white" TextStyle="TextStyle.H2" TextAlign="TextAlign.Center">系统设置</RadzenText>
 | 
				
			||||||
 | 
					                    @if (!Operator.role.permissionIds.Any(id => id - 50 > 0 && id - 50 < 10))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <div class="mask"> 
 | 
				
			||||||
 | 
					                            <RadzenImage Path="images/no_auth.png" />
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </RadzenStack>
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            </RadzenStack>
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject NavigationManager na;
 | 
				
			||||||
 | 
					    @inject TooltipService tooltipService
 | 
				
			||||||
 | 
					    private List<Premission> 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<Pojo.Config.SettingConfig> 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<object>();
 | 
				
			||||||
 | 
					            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<int> 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("");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,234 @@
 | 
				
			||||||
 | 
					@page "/"
 | 
				
			||||||
 | 
					@layout EmptyLayout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@using System.ComponentModel;
 | 
				
			||||||
 | 
					@using log4net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    body{
 | 
				
			||||||
 | 
					    background-image: url(/images/body-bg.png);
 | 
				
			||||||
 | 
					    /* background-repeat:repeat; */
 | 
				
			||||||
 | 
					    /* background: var(--rz-primary-light) no-repeat 100% 70% fixed url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwNCIgaGVpZ2h0PSIxNDU4IiB2aWV3Qm94PSIwIDAgMTIwNCAxNDU4IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8ZyBvcGFjaXR5PSIwLjUiIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2ZfNDkzXzEwMTM0KSI+CjxjaXJjbGUgY3g9IjcyMi4xMjgiIGN5PSI4MzkuMDIiIHI9IjQ4MS40MTkiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF80OTNfMTAxMzQpIi8+CjwvZz4KPGcgb3BhY2l0eT0iMC41IiBmaWx0ZXI9InVybCgjZmlsdGVyMV9mXzQ5M18xMDEzNCkiPgo8Y2lyY2xlIGN4PSI0NzAuMzMzIiBjeT0iNTcwLjMzMyIgcj0iNDcwLjMzMyIgZmlsbD0idXJsKCNwYWludDFfcmFkaWFsXzQ5M18xMDEzNCkiLz4KPC9nPgo8ZyBvcGFjaXR5PSIwLjUiIGZpbHRlcj0idXJsKCNmaWx0ZXIyX2ZfNDkzXzEwMTM0KSI+CjxjaXJjbGUgY3g9IjY5MS41MTEiIGN5PSI1MjIuMjk3IiByPSIzMzEuNTAzIiBmaWxsPSJ1cmwoI3BhaW50Ml9yYWRpYWxfNDkzXzEwMTM0KSIvPgo8L2c+CjxnIG9wYWNpdHk9IjAuNSIgZmlsdGVyPSJ1cmwoI2ZpbHRlcjNfZl80OTNfMTAxMzQpIj4KPGNpcmNsZSBjeD0iNjA4LjI0NCIgY3k9IjEwNzkuOTciIHI9IjMzMS41MDMiIHRyYW5zZm9ybT0icm90YXRlKC04MS4yMjQ0IDYwOC4yNDQgMTA3OS45NykiIGZpbGw9InVybCgjcGFpbnQzX3JhZGlhbF80OTNfMTAxMzQpIi8+CjwvZz4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImZpbHRlcjBfZl80OTNfMTAxMzQiIHg9IjE0MC43MDkiIHk9IjI1Ny42MDEiIHdpZHRoPSIxMTYyLjg0IiBoZWlnaHQ9IjExNjIuODQiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNTAiIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl80OTNfMTAxMzQiLz4KPC9maWx0ZXI+CjxmaWx0ZXIgaWQ9ImZpbHRlcjFfZl80OTNfMTAxMzQiIHg9Ii0xMDAiIHk9IjAiIHdpZHRoPSIxMTQwLjY3IiBoZWlnaHQ9IjExNDAuNjciIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNTAiIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl80OTNfMTAxMzQiLz4KPC9maWx0ZXI+CjxmaWx0ZXIgaWQ9ImZpbHRlcjJfZl80OTNfMTAxMzQiIHg9IjI2MC4wMDgiIHk9IjkwLjc5MzkiIHdpZHRoPSI4NjMuMDA2IiBoZWlnaHQ9Ijg2My4wMDYiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNTAiIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl80OTNfMTAxMzQiLz4KPC9maWx0ZXI+CjxmaWx0ZXIgaWQ9ImZpbHRlcjNfZl80OTNfMTAxMzQiIHg9IjE3Ni42OTQiIHk9IjY0OC40MjMiIHdpZHRoPSI4NjMuMSIgaGVpZ2h0PSI4NjMuMSIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI1MCIgcmVzdWx0PSJlZmZlY3QxX2ZvcmVncm91bmRCbHVyXzQ5M18xMDEzNCIvPgo8L2ZpbHRlcj4KPHJhZGlhbEdyYWRpZW50IGlkPSJwYWludDBfcmFkaWFsXzQ5M18xMDEzNCIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSg3MjIuMTI4IDgzOS4wMikgcm90YXRlKDkwKSBzY2FsZSg0ODEuNDE5KSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRjFBNkMiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkYxQTZDIiBzdG9wLW9wYWNpdHk9IjAiLz4KPC9yYWRpYWxHcmFkaWVudD4KPHJhZGlhbEdyYWRpZW50IGlkPSJwYWludDFfcmFkaWFsXzQ5M18xMDEzNCIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSg0NzAuMzMzIDU3MC4zMzMpIHJvdGF0ZSg5MCkgc2NhbGUoNDcwLjMzMykiPgo8c3RvcCBzdG9wLWNvbG9yPSIjM0FBQ0ZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzNBOTVGRiIgc3RvcC1vcGFjaXR5PSIwIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQyX3JhZGlhbF80OTNfMTAxMzQiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjkxLjUxMSA1MjIuMjk3KSByb3RhdGUoOTApIHNjYWxlKDMzMS41MDMpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzQ4M0FGRiIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0ODNBRkYiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50M19yYWRpYWxfNDkzXzEwMTM0IiBjeD0iMCIgY3k9IjAiIHI9IjEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKDYwOC4yNDQgMTA3OS45Nykgcm90YXRlKDkwKSBzY2FsZSgzMzEuNTAzKSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkM4M0EiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkZDODNBIiBzdG9wLW9wYWNpdHk9IjAiLz4KPC9yYWRpYWxHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K'); */
 | 
				
			||||||
 | 
					    width: 100vw;
 | 
				
			||||||
 | 
					    height: 100vh;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .finner-bg {
 | 
				
			||||||
 | 
					    background: url('/images/finger-bg-r.png') repeat;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" AlignItems="AlignItems.Center" Style="width:100vw;height:100vh">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <RadzenRow>
 | 
				
			||||||
 | 
					        <RadzenColumn></RadzenColumn>
 | 
				
			||||||
 | 
					    </RadzenRow>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <RadzenRow Gap="0" Class="rz-my-12 rz-mx-auto rz-border-radius-3 rz-shadow-10" Style="overflow: hidden;width:55vw;height:45vh">
 | 
				
			||||||
 | 
					        <RadzenColumn Size="12" SizeMD="5">
 | 
				
			||||||
 | 
					            <RadzenCard class="rz-shadow-0 rz-border-radius-0 rz-text-align-center rz-p-12" Style="height: 100%; background: var(--rz-primary-light) no-repeat 100% 70% fixed url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwNCIgaGVpZ2h0PSIxNDU4IiB2aWV3Qm94PSIwIDAgMTIwNCAxNDU4IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8ZyBvcGFjaXR5PSIwLjUiIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2ZfNDkzXzEwMTM0KSI+CjxjaXJjbGUgY3g9IjcyMi4xMjgiIGN5PSI4MzkuMDIiIHI9IjQ4MS40MTkiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF80OTNfMTAxMzQpIi8+CjwvZz4KPGcgb3BhY2l0eT0iMC41IiBmaWx0ZXI9InVybCgjZmlsdGVyMV9mXzQ5M18xMDEzNCkiPgo8Y2lyY2xlIGN4PSI0NzAuMzMzIiBjeT0iNTcwLjMzMyIgcj0iNDcwLjMzMyIgZmlsbD0idXJsKCNwYWludDFfcmFkaWFsXzQ5M18xMDEzNCkiLz4KPC9nPgo8ZyBvcGFjaXR5PSIwLjUiIGZpbHRlcj0idXJsKCNmaWx0ZXIyX2ZfNDkzXzEwMTM0KSI+CjxjaXJjbGUgY3g9IjY5MS41MTEiIGN5PSI1MjIuMjk3IiByPSIzMzEuNTAzIiBmaWxsPSJ1cmwoI3BhaW50Ml9yYWRpYWxfNDkzXzEwMTM0KSIvPgo8L2c+CjxnIG9wYWNpdHk9IjAuNSIgZmlsdGVyPSJ1cmwoI2ZpbHRlcjNfZl80OTNfMTAxMzQpIj4KPGNpcmNsZSBjeD0iNjA4LjI0NCIgY3k9IjEwNzkuOTciIHI9IjMzMS41MDMiIHRyYW5zZm9ybT0icm90YXRlKC04MS4yMjQ0IDYwOC4yNDQgMTA3OS45NykiIGZpbGw9InVybCgjcGFpbnQzX3JhZGlhbF80OTNfMTAxMzQpIi8+CjwvZz4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImZpbHRlcjBfZl80OTNfMTAxMzQiIHg9IjE0MC43MDkiIHk9IjI1Ny42MDEiIHdpZHRoPSIxMTYyLjg0IiBoZWlnaHQ9IjExNjIuODQiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNTAiIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl80OTNfMTAxMzQiLz4KPC9maWx0ZXI+CjxmaWx0ZXIgaWQ9ImZpbHRlcjFfZl80OTNfMTAxMzQiIHg9Ii0xMDAiIHk9IjAiIHdpZHRoPSIxMTQwLjY3IiBoZWlnaHQ9IjExNDAuNjciIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNTAiIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl80OTNfMTAxMzQiLz4KPC9maWx0ZXI+CjxmaWx0ZXIgaWQ9ImZpbHRlcjJfZl80OTNfMTAxMzQiIHg9IjI2MC4wMDgiIHk9IjkwLjc5MzkiIHdpZHRoPSI4NjMuMDA2IiBoZWlnaHQ9Ijg2My4wMDYiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNTAiIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl80OTNfMTAxMzQiLz4KPC9maWx0ZXI+CjxmaWx0ZXIgaWQ9ImZpbHRlcjNfZl80OTNfMTAxMzQiIHg9IjE3Ni42OTQiIHk9IjY0OC40MjMiIHdpZHRoPSI4NjMuMSIgaGVpZ2h0PSI4NjMuMSIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI1MCIgcmVzdWx0PSJlZmZlY3QxX2ZvcmVncm91bmRCbHVyXzQ5M18xMDEzNCIvPgo8L2ZpbHRlcj4KPHJhZGlhbEdyYWRpZW50IGlkPSJwYWludDBfcmFkaWFsXzQ5M18xMDEzNCIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSg3MjIuMTI4IDgzOS4wMikgcm90YXRlKDkwKSBzY2FsZSg0ODEuNDE5KSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRjFBNkMiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkYxQTZDIiBzdG9wLW9wYWNpdHk9IjAiLz4KPC9yYWRpYWxHcmFkaWVudD4KPHJhZGlhbEdyYWRpZW50IGlkPSJwYWludDFfcmFkaWFsXzQ5M18xMDEzNCIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSg0NzAuMzMzIDU3MC4zMzMpIHJvdGF0ZSg5MCkgc2NhbGUoNDcwLjMzMykiPgo8c3RvcCBzdG9wLWNvbG9yPSIjM0FBQ0ZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzNBOTVGRiIgc3RvcC1vcGFjaXR5PSIwIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQyX3JhZGlhbF80OTNfMTAxMzQiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjkxLjUxMSA1MjIuMjk3KSByb3RhdGUoOTApIHNjYWxlKDMzMS41MDMpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzQ4M0FGRiIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0ODNBRkYiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50M19yYWRpYWxfNDkzXzEwMTM0IiBjeD0iMCIgY3k9IjAiIHI9IjEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKDYwOC4yNDQgMTA3OS45Nykgcm90YXRlKDkwKSBzY2FsZSgzMzEuNTAzKSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkM4M0EiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkZDODNBIiBzdG9wLW9wYWNpdHk9IjAiLz4KPC9yYWRpYWxHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K')">
 | 
				
			||||||
 | 
					                @if(loginMode == 2)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.H6" class="rz-color-white">操作人:@globalStateService.Operator?.NickName</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.H6" class="rz-color-white">复核人:@globalStateService.Reviewer?.NickName</RadzenText>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </RadzenCard>
 | 
				
			||||||
 | 
					        </RadzenColumn>
 | 
				
			||||||
 | 
					        <RadzenColumn Size="12" SizeMD="7">
 | 
				
			||||||
 | 
					            <RadzenCard Class="rz-shadow-0 rz-border-radius-0 rz-p-12" Style="width:100%;height:100%">
 | 
				
			||||||
 | 
					                <RadzenText TextStyle="TextStyle.H5" TagName="TagName.H2" class="rz-mb-6">
 | 
				
			||||||
 | 
					                    登录
 | 
				
			||||||
 | 
					                </RadzenText>
 | 
				
			||||||
 | 
					                <RadzenTemplateForm Data="@loginModel" Submit="@((Pojo.User args) => { Submit(args); })" Style="width:100%;height:100%" >
 | 
				
			||||||
 | 
					                    <div class="rz-form-row">
 | 
				
			||||||
 | 
					                        <label class="rz-label" for="username">账号</label>
 | 
				
			||||||
 | 
					                        <div class="rz-form-input-wrapper">
 | 
				
			||||||
 | 
					                            <RadzenTextBox id="username" Name="Username" @bind-Value="@loginModel.Username" Style="width:100%" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Component="Username" Text="请填写用户名" />
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="rz-form-row">
 | 
				
			||||||
 | 
					                        <label class="rz-label" for="password">密码</label>
 | 
				
			||||||
 | 
					                        <div class="rz-form-input-wrapper">
 | 
				
			||||||
 | 
					                            <RadzenPassword id="password" Name="Password" @bind-Value="@loginModel.Password" Style="width:100%" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Component="Password" Text="请填写密码" />
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="rz-form-row">
 | 
				
			||||||
 | 
					                        <label class="rz-label"></label>
 | 
				
			||||||
 | 
					                        <div class="rz-form-input-wrapper rz-login-buttons">
 | 
				
			||||||
 | 
					                            <RadzenButton  Style="background:#255dd4;color:white;width:110px" ButtonType="ButtonType.Submit" Text="登录" />
 | 
				
			||||||
 | 
					                            <RadzenButton  Style="border-color:#255dd4;width:110px" Variant="Variant.Outlined" Text="退出" Click="@Exit" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </RadzenTemplateForm>
 | 
				
			||||||
 | 
					            </RadzenCard>
 | 
				
			||||||
 | 
					        </RadzenColumn>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </RadzenRow>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @inject FingerprintUtil FingerprintUtil;
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					    @inject NavigationManager na;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject GlobalStateService globalStateService;
 | 
				
			||||||
 | 
					    @inject IUserDao userDao;
 | 
				
			||||||
 | 
					    @inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> 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)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // 判断是否是操作人优先登录
 | 
				
			||||||
 | 
					            if (opFirst)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // 判断操作人是否已经登录,已经登录说明此时为第二人登录
 | 
				
			||||||
 | 
					                if (globalStateService.Operator != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // 判断是否还是操作人的验证
 | 
				
			||||||
 | 
					                    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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,114 @@
 | 
				
			||||||
 | 
					@page "/add/invoice"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="单据号" Component="InvoiceNo" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenTextBox @bind-Value="InvoiceNo" Style="width: 100%;" Name="InvoiceNo"></RadzenTextBox>
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="请领日期" Component="InvoiceDate" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentDateChanged" @bind-Value="InvoiceDate" Style="width: 100%;" Name="InvoiceDate" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search"  Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					                    LoadData="@LoadData"
 | 
				
			||||||
 | 
					                    RowSelect="@((InOutInvoice oi) => { InvoiceSelected(oi); })"
 | 
				
			||||||
 | 
					                    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					                    Count="@count"
 | 
				
			||||||
 | 
					                    EmptyText="无数据"
 | 
				
			||||||
 | 
					                    Data="@_forecasts"
 | 
				
			||||||
 | 
					                    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					                    SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					                    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Frozen="true" Title="单据号" Property="InvoiceNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="170px" Title="时间" Property="InvoiceDate"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="请领药房" Property="InPharmacyId"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="出库药房" Property="OutPharmacyId"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IInOutInvoiceDao inOutInvoiceDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<InOutInvoice> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<InOutInvoice>? _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<InvoiceAddDialog>(
 | 
				
			||||||
 | 
					                $"调拨入库详情",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "invoice", oi } },
 | 
				
			||||||
 | 
					              new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if (b)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            await reloadGrid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Gap="1rem" Orientation="Orientation.Vertical" JustifyContent="JustifyContent.SpaceBetween" Style="height: 100%;">
 | 
				
			||||||
 | 
					    <RadzenStack class="rz-p-4 rz-border-radius-1" Style="border: var(--rz-grid-cell-border)" Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					        <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">单据号:</RadzenText>
 | 
				
			||||||
 | 
					        <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(invoice?.InvoiceNo)</b></RadzenText>
 | 
				
			||||||
 | 
					        <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">时间:</RadzenText>
 | 
				
			||||||
 | 
					        <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(invoice?.InvoiceDate)</b></RadzenText>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					    <RadzenStack>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            <RadzenDataGrid @ref="grid" Data="@data" ExpandMode="DataGridExpandMode.Multiple"
 | 
				
			||||||
 | 
					                            RowRender="@RowRender"
 | 
				
			||||||
 | 
					                            EmptyText="无数据" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <Template Context="di">
 | 
				
			||||||
 | 
					                    <RadzenDataGrid Data="@di.ChannelStocks" EmptyText="无数据" @ref="di.Grid"
 | 
				
			||||||
 | 
					                                CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args, di.Grid))">
 | 
				
			||||||
 | 
					                        <Columns>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="库位" Property="DrawerNo">
 | 
				
			||||||
 | 
					                                <Template Context="s">
 | 
				
			||||||
 | 
					                                    @s.DrawerNo - @s.ColNo
 | 
				
			||||||
 | 
					                                </Template>
 | 
				
			||||||
 | 
					                            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="库存" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            @* <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="效期" Property="EffDate"></RadzenDataGridColumn> *@
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="入库数量" Property="AddQuantity">
 | 
				
			||||||
 | 
					                                <EditTemplate Context="cs">
 | 
				
			||||||
 | 
					                                    <RadzenNumeric Disabled="status > 0" Style="display: block" Min="0" Max="@di.Quantity" Name="Quantity" @bind-Value=@cs.AddQuantity />
 | 
				
			||||||
 | 
					                                    <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Max="@di.Quantity" Text="请填写正确的添加数量" Component="Quantity" />
 | 
				
			||||||
 | 
					                                    <RadzenCustomValidator Validator="@(() => di.ChannelStocks.Sum(cs2 => cs2.AddQuantity) == di.Quantity)" Component="Quantity" Text="入库总量应等于请领数量" Style="position: absolute;z-index: 9999;" />
 | 
				
			||||||
 | 
					                                </EditTemplate>
 | 
				
			||||||
 | 
					                            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        </Columns>
 | 
				
			||||||
 | 
					                    </RadzenDataGrid>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Invoice.DrugManuNo" Title="批次" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Invoice.EffDate" Title="效期" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Quantity" Title="请领数量" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="StockQuantity" Title="总库存" />
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
 | 
				
			||||||
 | 
					        @if (status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@StartAdd" Disabled="!CanTakeDrug" IsBusy="status > 0" BusyText="加药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="加药" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status == 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@AddFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@((args) => CancelOpera())" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject Radzen.DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject IInOutInvoiceDao inOutInvoiceDao;
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RadzenDataGrid<InvoiceVo> grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly ILog logger = LogManager.GetLogger(typeof(InvoiceAddDialog));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    [Parameter] public InOutInvoice invoice { get; set; }
 | 
				
			||||||
 | 
					    private bool CanTakeDrug = true;
 | 
				
			||||||
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public List<InvoiceVo> 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<ChannelStock> channels = new();
 | 
				
			||||||
 | 
					        for (int i = 0; i < data.Count; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.AddQuantity > 0)).ToList();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<int> 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<int>().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<int>().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<InvoiceVo> args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args, RadzenDataGrid<ChannelStock> Grid)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Grid.EditRow(args.Data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,114 @@
 | 
				
			||||||
 | 
					@page "/take/invoice"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="单据号" Component="InvoiceNo" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenTextBox @bind-Value="InvoiceNo" Style="width: 100%;" Name="InvoiceNo"></RadzenTextBox>
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="请领日期" Component="InvoiceDate" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentDateChanged" @bind-Value="InvoiceDate" Style="width: 100%;" Name="InvoiceDate" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search"  Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					                    LoadData="@LoadData"
 | 
				
			||||||
 | 
					                    RowSelect="@((InOutInvoice oi) => { InvoiceSelected(oi); })"
 | 
				
			||||||
 | 
					                    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					                    Count="@count"
 | 
				
			||||||
 | 
					                    EmptyText="无数据"
 | 
				
			||||||
 | 
					                    Data="@_forecasts"
 | 
				
			||||||
 | 
					                    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					                    SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					                    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Frozen="true" Title="单据号" Property="InvoiceNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="170px" Title="时间" Property="InvoiceDate"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="请领药房" Property="InPharmacyId"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="出库药房" Property="OutPharmacyId"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IInOutInvoiceDao inOutInvoiceDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<InOutInvoice> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<InOutInvoice>? _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<InvoiceOutDialog>(
 | 
				
			||||||
 | 
					                $"调拨出库详情",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "invoice", oi } },
 | 
				
			||||||
 | 
					              new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if (b)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            await reloadGrid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Gap="1rem" Orientation="Orientation.Vertical" JustifyContent="JustifyContent.SpaceBetween" Style="height: 100%;">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <RadzenStack class="rz-p-4 rz-border-radius-1" Style="border: var(--rz-grid-cell-border)" Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					        <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">单据号:</RadzenText>
 | 
				
			||||||
 | 
					        <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(invoice?.InvoiceNo)</b></RadzenText>
 | 
				
			||||||
 | 
					        <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">时间:</RadzenText>
 | 
				
			||||||
 | 
					        <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(invoice?.InvoiceDate)</b></RadzenText>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					    <RadzenStack>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            <RadzenDataGrid @ref="grid" Data="@data" ExpandMode="DataGridExpandMode.Multiple"
 | 
				
			||||||
 | 
					                            RowRender="@RowRender"
 | 
				
			||||||
 | 
					                            EmptyText="无数据" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <Template Context="di">
 | 
				
			||||||
 | 
					                <RadzenDataGrid Data="@di.ChannelStocks" EmptyText="无数据" @ref="di.Grid"
 | 
				
			||||||
 | 
					                                CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args, di.Grid))">
 | 
				
			||||||
 | 
					                        <Columns>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="库位" Property="DrawerNo">
 | 
				
			||||||
 | 
					                                <Template Context="s">
 | 
				
			||||||
 | 
					                                    @s.DrawerNo - @s.ColNo
 | 
				
			||||||
 | 
					                                </Template>
 | 
				
			||||||
 | 
					                            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="库存" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            @* <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="效期" Property="EffDate"></RadzenDataGridColumn> *@
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="出库数量" Property="TakeQuantity">
 | 
				
			||||||
 | 
					                                <EditTemplate Context="cs">
 | 
				
			||||||
 | 
					                                    <RadzenNumeric Style="display: block" Min="0" Max="@cs.Quantity" Name="Quantity" @bind-Value=@cs.TakeQuantity />
 | 
				
			||||||
 | 
					                                    <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Max="@cs.Quantity" Text="请填写正确的取出数量" Component="Quantity" />
 | 
				
			||||||
 | 
					                                    <RadzenCustomValidator Validator="@(() => di.ChannelStocks.Sum(cs2 => cs2.TakeQuantity) == di.Quantity)" Component="Quantity" Text="出库总量应等于请领数量"  Style="position: absolute;z-index: 9999;" />
 | 
				
			||||||
 | 
					                                </EditTemplate>
 | 
				
			||||||
 | 
					                            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        </Columns>
 | 
				
			||||||
 | 
					                    </RadzenDataGrid>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Invoice.DrugManuNo" Title="批次" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Invoice.EffDate" Title="效期" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Quantity" Title="请领数量" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="StockQuantity" Title="总库存" />
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
 | 
				
			||||||
 | 
					        @if (status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@StartTake" Disabled="!CanTakeDrug" IsBusy="status > 0" BusyText="取药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="取药" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status == 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@TakeFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status <= 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@((args) => CancelOpera())" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject Radzen.DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject IInOutInvoiceDao inOutInvoiceDao;
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RadzenDataGrid<InvoiceVo> grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly ILog logger = LogManager.GetLogger(typeof(InvoiceOutDialog));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    [Parameter] public InOutInvoice invoice { get; set; }
 | 
				
			||||||
 | 
					    private bool CanTakeDrug = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public List<InvoiceVo> 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<ChannelStock> channels = new();
 | 
				
			||||||
 | 
					        for(int i = 0; i < data.Count; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.TakeQuantity > 0)).ToList();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<int> drawerNos = channels.GroupBy(it => it.DrawerNo).Select(it => it.Key).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 根据抽屉类型来决定打开前是否需要查询数量
 | 
				
			||||||
 | 
					        var promiseUtil = new PromiseUtil<int>();
 | 
				
			||||||
 | 
					        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<int>().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<InvoiceVo> args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args, RadzenDataGrid<ChannelStock> Grid)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Grid.EditRow(args.Data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,118 @@
 | 
				
			||||||
 | 
					@page "/take/record/{type}"
 | 
				
			||||||
 | 
					@page "/add/record/{type}"
 | 
				
			||||||
 | 
					@page "/return/record1/{type}"
 | 
				
			||||||
 | 
					@page "/return/record2/{type}"
 | 
				
			||||||
 | 
					@page "/stock/record/{type}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="开始时间" Component="Start" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" ShowTime="true" @bind-Value="start" Style="width: 100%;" Name="Start" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="结束时间" Component="End" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" ShowTime="true" @bind-Value="end" Style="width: 100%;" Name="End" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					                    LoadData="@LoadData"
 | 
				
			||||||
 | 
					                    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					                    Count="@count"
 | 
				
			||||||
 | 
					                    EmptyText="无数据"
 | 
				
			||||||
 | 
					                    Data="@_forecasts"
 | 
				
			||||||
 | 
					                    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					                    SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					                    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Frozen="true" Title="操作人" Property="OperatorUser.NickName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="170px" Title="操作时间" Property="OperationTime"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="200px" Title="药品名称" Property="Drug.DrugName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="规格" Property="Drug.DrugSpec"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="数量" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="效期" Property="EffDate">
 | 
				
			||||||
 | 
					                            <Template Context="mr">
 | 
				
			||||||
 | 
					                                @mr.EffDate?.ToString("yyyy-MM-dd")
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn title="库位" Property="Location"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IMachineRecordDao machineRecordDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @inject NavigationManager navigate;
 | 
				
			||||||
 | 
					    RadzenDataGrid<MachineRecord> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<MachineRecord>? _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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Gap="1rem" Orientation="Orientation.Vertical" Style="height: 100%;">
 | 
				
			||||||
 | 
					    <RadzenStack>
 | 
				
			||||||
 | 
					        <RadzenStack class="rz-p-4 rz-border-radius-1" Style="border: var(--rz-grid-cell-border)" Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">处方号:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.OrderNo)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">患者姓名:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.PatientName)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">性别:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.Sex)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">年龄:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.Age)</b></RadzenText>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					        @if (CanTakeDrug)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenDataGrid Data="@data" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="ChannelStock" Title="库位">
 | 
				
			||||||
 | 
					                        <Template>
 | 
				
			||||||
 | 
					                            @context.ChannelStock.DrawerNo - @context.ChannelStock.ColNo
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="ChannelStock.ManuNo" Title="批次" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="ChannelStock.EffDate" Title="效期" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Quantity" Title="数量" />
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenDataGrid Data="@data" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Quantity" Title="取药数量" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="StockQuantity" Title="库存" />
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
 | 
				
			||||||
 | 
					        @if (status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@OpenDrawer" Disabled="!CanTakeDrug" IsBusy="status > 0" BusyText="取药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="取药" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status == 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@TakeFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status <= 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@((args) => dialogService.Close(false))" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject Radzen.DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject IOrderInfoDao orderInfoDao;
 | 
				
			||||||
 | 
					    @inject IChannelListDao channelListDao;
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> 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<OrderTakeVo> 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<OrderTakeVo> drawerNos = this.data.GroupBy(it => it.ChannelStock.DrawerNo).Select(it => it.First()).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 根据抽屉类型来决定打开前是否需要查询数量
 | 
				
			||||||
 | 
					        var promiseUtil = new PromiseUtil<int>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Gap="1rem" Orientation="Orientation.Vertical" Style="height: 100%;">
 | 
				
			||||||
 | 
					    <RadzenStack>
 | 
				
			||||||
 | 
					        <RadzenStack class="rz-p-4 rz-border-radius-1" Style="border: var(--rz-grid-cell-border)" Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">处方号:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.OrderNo)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">患者姓名:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.PatientName)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">性别:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.Sex)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">年龄:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.Age)</b></RadzenText>
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					        <RadzenDataGrid @ref="grid" Data="@data" ExpandMode="DataGridExpandMode.Multiple"
 | 
				
			||||||
 | 
					                        RowRender="@RowRender"
 | 
				
			||||||
 | 
					                        EmptyText="无数据" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <Template Context="di">
 | 
				
			||||||
 | 
					                <RadzenDataGrid Data="@di.ChannelStocks" EmptyText="无数据" @ref="di.Grid"
 | 
				
			||||||
 | 
					                                CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args, di.Grid))">
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="库位" Property="DrawerNo">
 | 
				
			||||||
 | 
					                            <Template Context="s">
 | 
				
			||||||
 | 
					                                @s.DrawerNo - @s.ColNo
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="库存" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="入库数量" Property="AddQuantity">
 | 
				
			||||||
 | 
					                            <EditTemplate Context="cs">
 | 
				
			||||||
 | 
					                                <RadzenNumeric Disabled="status > 0" Style="display: block" Min="0" Max="@di.Quantity" Name="Quantity" @bind-Value=@cs.ReturnQuantity />
 | 
				
			||||||
 | 
					                                <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Max="@di.Quantity" Text="请填写正确的添加数量" Component="Quantity" />
 | 
				
			||||||
 | 
					                                <RadzenCustomValidator Validator="@(() => di.ChannelStocks.Sum(cs2 => cs2.ReturnQuantity) == di.Quantity)" Component="Quantity" Text="添加总量应等于退药量" Style="position: absolute;z-index: 9999;" />
 | 
				
			||||||
 | 
					                            </EditTemplate>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					            </Template>
 | 
				
			||||||
 | 
					            <Columns>
 | 
				
			||||||
 | 
					                <RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
 | 
				
			||||||
 | 
					                <RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                <RadzenDataGridColumn Property="data.ManuNo" Title="批次" />
 | 
				
			||||||
 | 
					                <RadzenDataGridColumn Property="data.EffDate" Title="效期" />
 | 
				
			||||||
 | 
					                <RadzenDataGridColumn Property="Quantity" Title="退药量" />
 | 
				
			||||||
 | 
					                <RadzenDataGridColumn Property="StockQuantity" Title="总库存" />
 | 
				
			||||||
 | 
					            </Columns>
 | 
				
			||||||
 | 
					        </RadzenDataGrid>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
 | 
				
			||||||
 | 
					        @if(status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@OpenDrawer" Disabled="!CanReturnDrug" IsBusy="status > 0" BusyText="退药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="退药" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if(status == 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@TakeFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if(status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@((args) => dialogService.Close(false))" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject Radzen.DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject IOrderInfoDao orderInfoDao;
 | 
				
			||||||
 | 
					    @inject IChannelListDao channelListDao;
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					    private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog));
 | 
				
			||||||
 | 
					    RadzenDataGrid<OperationVo<MachineRecord>> grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Parameter] public OrderInfo order { get; set; }
 | 
				
			||||||
 | 
					    private bool CanReturnDrug = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public List<OperationVo<MachineRecord>> 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<ChannelStock> channels = new();
 | 
				
			||||||
 | 
					        for (int i = 0; i < data.Count; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.AddQuantity > 0)).ToList();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<int> 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<int>().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<int>().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<OperationVo<MachineRecord>> args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args, RadzenDataGrid<ChannelStock> Grid)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Grid.EditRow(args.Data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,118 @@
 | 
				
			||||||
 | 
					@page "/return/order"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="处方号" Component="OrderNo" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenTextBox @bind-Value="OrderNo" Style="width: 100%;" Name="OrderNo"></RadzenTextBox>
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="处方时间" Component="OrderDate" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentDateChanged" @bind-Value="OrderDate" Style="width: 100%;" Name="OrderDate" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search"  Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					                    LoadData="@LoadData"
 | 
				
			||||||
 | 
					                    RowSelect="@((OrderInfo oi) => { OrderSelected(oi); })"
 | 
				
			||||||
 | 
					                    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					                    Count="@count"
 | 
				
			||||||
 | 
					                    EmptyText="无数据"
 | 
				
			||||||
 | 
					                    Data="@_forecasts"
 | 
				
			||||||
 | 
					                    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					                    SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					                    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Frozen="true" Title="处方号" Property="OrderNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="170px" Title="开方时间" Property="OrderDate"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="医生" Property="DoctorName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="姓名" Property="PatientName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="性别" Property="Sex"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="年龄" Property="Age"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="科室" Property="DeptName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="诊断" Property="Disease"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IOrderInfoDao orderInfoDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<OrderInfo> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<OrderInfo>? _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<OrderDetailReturnDialog>(
 | 
				
			||||||
 | 
					                $"退药处方详情",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "order", oi } },
 | 
				
			||||||
 | 
					              new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if(b)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            await reloadGrid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,118 @@
 | 
				
			||||||
 | 
					@page "/take/order"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="处方号" Component="OrderNo" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenTextBox @bind-Value="OrderNo" Style="width: 100%;" Name="OrderNo"></RadzenTextBox>
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="处方时间" Component="OrderDate" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentDateChanged" @bind-Value="OrderDate" Style="width: 100%;" Name="OrderDate" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search"  Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					                    LoadData="@LoadData"
 | 
				
			||||||
 | 
					                    RowSelect="@((OrderInfo oi) => { OrderSelected(oi); })"
 | 
				
			||||||
 | 
					                    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					                    Count="@count"
 | 
				
			||||||
 | 
					                    EmptyText="无数据"
 | 
				
			||||||
 | 
					                    Data="@_forecasts"
 | 
				
			||||||
 | 
					                    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					                    SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					                    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Frozen="true" Title="处方号" Property="OrderNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="170px" Title="开方时间" Property="OrderDate"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="医生" Property="DoctorName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="姓名" Property="PatientName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="性别" Property="Sex"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="年龄" Property="Age"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="科室" Property="DeptName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="诊断" Property="Disease"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IOrderInfoDao orderInfoDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<OrderInfo> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<OrderInfo>? _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<OrderDetailDialog>(
 | 
				
			||||||
 | 
					                $"处方详情",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "order", oi } },
 | 
				
			||||||
 | 
					              new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if(b)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            await reloadGrid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,144 @@
 | 
				
			||||||
 | 
					@page "/return/byRecord"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .rz-custom-header {
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="开始时间" Component="Start" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" ShowTime="true" @bind-Value="start" Style="width: 100%;" Name="Start" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="结束时间" Component="End" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" ShowTime="true" @bind-Value="end" Style="width: 100%;" Name="End" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					                    LoadData="@LoadData"
 | 
				
			||||||
 | 
					                    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					                    Count="@count"
 | 
				
			||||||
 | 
					                    EmptyText="无数据"
 | 
				
			||||||
 | 
					                    Data="@_forecasts"
 | 
				
			||||||
 | 
					                    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					                    AllowRowSelectOnRowClick="true"
 | 
				
			||||||
 | 
					                    CellClick="@((DataGridCellMouseEventArgs<MachineRecord> args) => OnCellClick(args))"
 | 
				
			||||||
 | 
					                    AllowPaging="true" PageSize="8" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                    <HeaderTemplate>
 | 
				
			||||||
 | 
					                        <RadzenRow JustifyContent="JustifyContent.End">
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Warning" Disabled="_forecasts == null || !_forecasts.Any(mr => mr.CurrentReturnQuantity > 0)" Variant="Variant.Outlined" Shade="Shade.Light" Text="归还" Click="@OpenReturnDialog" />
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </HeaderTemplate>
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Frozen="true" Title="操作人" Property="OperatorUser.NickName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="170px" Title="操作时间" Property="OperationTime"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="200px" Title="药品名称" Property="Drug.DrugName">
 | 
				
			||||||
 | 
					                            <Template Context="mr">
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@mr.Drug?.DrugName</RadzenText>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Caption">@mr.Drug?.DrugSpec</RadzenText>
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="批次" Property="ManuNo">
 | 
				
			||||||
 | 
					                            <Template Context="mr">
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@mr.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Caption"> @mr.EffDate?.ToString("yyyy-MM-dd")</RadzenText>
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="借出数量" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="已还药品" Property="ReturnQuantity1"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="已还空瓶" Property="ReturnQuantity2"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="本次归还" Property="CurrentReturnQuantity">
 | 
				
			||||||
 | 
					                            <EditTemplate Context="mr">
 | 
				
			||||||
 | 
					                                <RadzenNumeric Min="0" Style="display: block" Max="@(mr.Quantity - mr.ReturnQuantity1 - mr.ReturnQuantity2)" Name="Quantity" @bind-Value=@mr.CurrentReturnQuantity />
 | 
				
			||||||
 | 
					                            </EditTemplate>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IMachineRecordDao machineRecordDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<MachineRecord> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private List<MachineRecord>? _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<RecordReturnDrugDialog>(
 | 
				
			||||||
 | 
					                $"记录还药",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "records", list } },
 | 
				
			||||||
 | 
					              new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if (b)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            await reloadGrid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void OnCellClick(DataGridCellMouseEventArgs<MachineRecord> args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        grid.EditRow(args.Data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Gap="1rem" Orientation="Orientation.Vertical" JustifyContent="JustifyContent.SpaceBetween" Style="height: 100%;">
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <RadzenStack>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            <RadzenDataGrid @ref="grid" Data="@data" ExpandMode="DataGridExpandMode.Multiple"
 | 
				
			||||||
 | 
					                            RowRender="@RowRender"
 | 
				
			||||||
 | 
					                            EmptyText="无数据" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <Template Context="di">
 | 
				
			||||||
 | 
					                    <RadzenDataGrid Data="@di.ChannelStocks" EmptyText="无数据" @ref="di.Grid"
 | 
				
			||||||
 | 
					                                CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args, di.Grid))">
 | 
				
			||||||
 | 
					                        <Columns>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="库位" Property="DrawerNo">
 | 
				
			||||||
 | 
					                                <Template Context="s">
 | 
				
			||||||
 | 
					                                    @s.DrawerNo - @s.ColNo
 | 
				
			||||||
 | 
					                                </Template>
 | 
				
			||||||
 | 
					                            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="库存" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            @* <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="效期" Property="EffDate"></RadzenDataGridColumn> *@
 | 
				
			||||||
 | 
					                            <RadzenDataGridColumn Title="入库数量" Property="ReturnQuantity">
 | 
				
			||||||
 | 
					                                <EditTemplate Context="cs">
 | 
				
			||||||
 | 
					                                    <RadzenNumeric Disabled="status > 0" Style="display: block" Min="0" Max="@di.Quantity" Name="Quantity" @bind-Value=@cs.ReturnQuantity />
 | 
				
			||||||
 | 
					                                    <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Max="@di.Quantity" Text="请填写正确的添加数量" Component="Quantity" />
 | 
				
			||||||
 | 
					                                <RadzenCustomValidator Validator="@(() => di.ChannelStocks.Sum(cs2 => cs2.ReturnQuantity) == di.Quantity)" Component="Quantity" Text="入库总量应等于请领数量" Style="position: absolute;z-index: 9999;" />
 | 
				
			||||||
 | 
					                                </EditTemplate>
 | 
				
			||||||
 | 
					                            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        </Columns>
 | 
				
			||||||
 | 
					                    </RadzenDataGrid>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="ManuNo" Title="批次">
 | 
				
			||||||
 | 
					                        <Template Context="ov">
 | 
				
			||||||
 | 
					                            @ov.data.First().ManuNo
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="EffDate" Title="效期">
 | 
				
			||||||
 | 
					                        <Template Context="ov">
 | 
				
			||||||
 | 
					                            @ov.data.First().EffDate
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Quantity" Title="请领数量" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="StockQuantity" Title="总库存" />
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
 | 
				
			||||||
 | 
					        @if (status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@StartAdd" Disabled="!CanTakeDrug" IsBusy="status > 0" BusyText="加药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="加药" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status == 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@AddFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@((args) => CancelOpera())" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject Radzen.DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject IMachineRecordDao machineRecordDao;
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RadzenDataGrid<OperationVo<List<MachineRecord>>> grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly ILog logger = LogManager.GetLogger(typeof(InvoiceAddDialog));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    [Parameter] public List<MachineRecord> records { get; set; }
 | 
				
			||||||
 | 
					    private bool CanTakeDrug = true;
 | 
				
			||||||
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public List<OperationVo<List<MachineRecord>>> 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<ChannelStock> 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<int> 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<int>().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<int>().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<OperationVo<List<MachineRecord>>> args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args, RadzenDataGrid<ChannelStock> Grid)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Grid.EditRow(args.Data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,129 @@
 | 
				
			||||||
 | 
					@page "/return/empty"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .rz-custom-header {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        @*  <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="开始时间" Component="Start" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" ShowTime="true" @bind-Value="start" Style="width: 100%;" Name="Start" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="结束时间" Component="End" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" ShowTime="true" @bind-Value="end" Style="width: 100%;" Name="End" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div> *@
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					            LoadData="@LoadData"
 | 
				
			||||||
 | 
					            IsLoading="@isLoading"
 | 
				
			||||||
 | 
					            EmptyText="无数据"
 | 
				
			||||||
 | 
					            Data="@_forecasts"
 | 
				
			||||||
 | 
					            AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					            AllowRowSelectOnRowClick="true"
 | 
				
			||||||
 | 
					            CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args))" >
 | 
				
			||||||
 | 
					                @*           <HeaderTemplate>
 | 
				
			||||||
 | 
					                    <RadzenRow JustifyContent="JustifyContent.End">
 | 
				
			||||||
 | 
					                        <RadzenButton ButtonStyle="ButtonStyle.Warning" Disabled="_forecasts == null || !_forecasts.Any(mr => mr.DrawerNo > 0)" Variant="Variant.Outlined" Shade="Shade.Light" Text="归还" Click="@OpenReturnDialog" />
 | 
				
			||||||
 | 
					                    </RadzenRow>
 | 
				
			||||||
 | 
					                </HeaderTemplate> *@
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Frozen="true" Title="库位" Property="Location"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Width="200px" Title="药品名称" Property="Drug.DrugName">
 | 
				
			||||||
 | 
					                        @* <Template Context="mr">
 | 
				
			||||||
 | 
					                            <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@mr.Drug?.DrugName</RadzenText>
 | 
				
			||||||
 | 
					                            <RadzenText TextStyle="TextStyle.Caption">@mr.Drug?.DrugSpec</RadzenText>
 | 
				
			||||||
 | 
					                        </Template> *@
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="厂家" Property="Drug.Manufactory"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="库存" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="可归还数量" Property="CanReturnQuantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    @*<RadzenDataGridColumn Title="本次归还" Property="CurrentReturnQuantity">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="mr">
 | 
				
			||||||
 | 
					                             <RadzenNumeric Min="0" Style="display: block" Max="@(mr.Quantity - mr.ReturnQuantity1 - mr.ReturnQuantity2)" Name="Quantity" @bind-Value=@mr.CurrentReturnQuantity /> 
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>*@
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IMachineRecordDao machineRecordDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    RadzenDataGrid<ChannelStock> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private List<ChannelStock>? _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<ChannelStock> 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<RecordReturnEmptyDialog>(
 | 
				
			||||||
 | 
					                $"归还空瓶",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "records", list } },
 | 
				
			||||||
 | 
					              new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if (b)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            await reloadGrid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenFieldset Text="药品信息">
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" Gap="10px" JustifyContent="JustifyContent.Center" AlignItems="AlignItems.Center" Wrap="FlexWrap.NoWrap" Style="height: 80px;padding:20px;">
 | 
				
			||||||
 | 
					        <RadzenStack class="rz-p-1  rz-text-align-center" Style="width:500px">
 | 
				
			||||||
 | 
					            药品:@drugName
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					        <RadzenStack class="rz-p-1 rz-text-align-center" Style="width:500px">
 | 
				
			||||||
 | 
					            规格:@drugSpec
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					        <RadzenStack class="rz-p-1 rz-text-align-center" Style="width:500px">
 | 
				
			||||||
 | 
					            厂家:@drugManufactory
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					        <RadzenStack class="rz-p-1   rz-text-align-center" Style="width:500px">
 | 
				
			||||||
 | 
					            可还空瓶数:@emptyQuantity
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenFieldset>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					                LoadData="@LoadData"
 | 
				
			||||||
 | 
					                IsLoading="@isLoading"
 | 
				
			||||||
 | 
					                Count="@count"
 | 
				
			||||||
 | 
					                EmptyText="无数据"
 | 
				
			||||||
 | 
					                Data="@_returnEmptys"
 | 
				
			||||||
 | 
					                AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					                AllowRowSelectOnRowClick="true"
 | 
				
			||||||
 | 
					                CellClick="@((DataGridCellMouseEventArgs<MachineRecord> args) => OnCellClick(args))"
 | 
				
			||||||
 | 
					                AllowPaging="true" PageSize="8" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					    <Columns>
 | 
				
			||||||
 | 
					        <RadzenDataGridColumn Width="60px" Sortable="false" Filterable="false">
 | 
				
			||||||
 | 
					            <HeaderTemplate>
 | 
				
			||||||
 | 
					                选择
 | 
				
			||||||
 | 
					            </HeaderTemplate>
 | 
				
			||||||
 | 
					            <Template Context="LoadData">
 | 
				
			||||||
 | 
					                <RadzenCheckBox TriState="false" Value="@LoadData.IsSelected" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select item" }})"
 | 
				
			||||||
 | 
					                                TValue="bool" />
 | 
				
			||||||
 | 
					            </Template>
 | 
				
			||||||
 | 
					        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        <RadzenDataGridColumn Frozen="true" Title="操作人" Property="OperatorUser.NickName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        <RadzenDataGridColumn Width="170px" Title="操作时间" Property="OperationTime"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        <RadzenDataGridColumn Title="批次" Property="ManuNo">
 | 
				
			||||||
 | 
					            <Template Context="mr">
 | 
				
			||||||
 | 
					                <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@mr.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                <RadzenText TextStyle="TextStyle.Caption"> @mr.EffDate?.ToString("yyyy-MM-dd")</RadzenText>
 | 
				
			||||||
 | 
					            </Template>
 | 
				
			||||||
 | 
					        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        <RadzenDataGridColumn Title="数量" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        <RadzenDataGridColumn Title="已还药品" Property="ReturnQuantity1"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        <RadzenDataGridColumn Title="已还空瓶" Property="ReturnQuantity2"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        <RadzenDataGridColumn Title="本次归还" Property="CurrentReturnQuantity">
 | 
				
			||||||
 | 
					            <EditTemplate Context="mr">
 | 
				
			||||||
 | 
					                <RadzenNumeric Min="0" Style="display: block" Max="@(mr.Quantity - mr.ReturnQuantity1 - mr.ReturnQuantity2)" Name="Quantity" @bind-Value=@mr.CurrentReturnQuantity />
 | 
				
			||||||
 | 
					            </EditTemplate>
 | 
				
			||||||
 | 
					        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					    </Columns>
 | 
				
			||||||
 | 
					</RadzenDataGrid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem" Style="margin-top:15px;">
 | 
				
			||||||
 | 
					    @if (status < 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        <RadzenButton Click="@StartAdd" IsBusy="status > 0" BusyText="还空瓶中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="归还" Style="width: 120px" />
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    @if (status == 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        <RadzenButton Click="@AddFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    @if (status < 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        <RadzenButton Click="@((args) => CancelOpera())" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					@code
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    @inject IMachineRecordDao machineRecordDao;
 | 
				
			||||||
 | 
					    @inject Radzen.DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject IMachineRecordDao machineRecordDao;
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Parameter]
 | 
				
			||||||
 | 
					    public ChannelStock records { get; set; }
 | 
				
			||||||
 | 
					    // public PageData<MachineRecord> data { get; set; }
 | 
				
			||||||
 | 
					    string drugName = string.Empty;
 | 
				
			||||||
 | 
					    string drugSpec = string.Empty;
 | 
				
			||||||
 | 
					    string drugManufactory = string.Empty;
 | 
				
			||||||
 | 
					    int emptyQuantity = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RadzenDataGrid<MachineRecord> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private List<MachineRecord>? _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<MachineRecord> 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<int>().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<int>().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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,101 @@
 | 
				
			||||||
 | 
					@page "/return/record2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="开始时间" Component="Start" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" ShowTime="true" @bind-Value="start" Style="width: 100%;" Name="Start" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="结束时间" Component="End" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" ShowTime="true" @bind-Value="end" Style="width: 100%;" Name="End" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="查询" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					                    LoadData="@LoadData"
 | 
				
			||||||
 | 
					                    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					                    Count="@count"
 | 
				
			||||||
 | 
					                    EmptyText="无数据"
 | 
				
			||||||
 | 
					                    Data="@_forecasts"
 | 
				
			||||||
 | 
					                    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					                    SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					                    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                    <Columns>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Frozen="true" Title="操作人" Property="OperatorUser.NickName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="170px" Title="操作时间" Property="OperationTime"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Width="200px" Title="药品名称" Property="Drug.DrugName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="规格" Property="Drug.DrugSpec"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="数量" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                        <RadzenDataGridColumn Title="效期" Property="EffDate">
 | 
				
			||||||
 | 
					                            <Template Context="mr">
 | 
				
			||||||
 | 
					                                @mr.EffDate?.ToString("yyyy-MM-dd")
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                        </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    </Columns>
 | 
				
			||||||
 | 
					                </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IMachineRecordDao machineRecordDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<MachineRecord> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<MachineRecord>? _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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,268 @@
 | 
				
			||||||
 | 
					@page "/manage/role"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.SpaceBetween">
 | 
				
			||||||
 | 
					                        <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="角色名称" Component="RoleName" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="RoleName" Style="width: 100%;" Name="RoleName"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                    <RadzenButton Size="ButtonSize.Medium" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="查询" />
 | 
				
			||||||
 | 
					                                    <RadzenButton Size="ButtonSize.Medium" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenStack>
 | 
				
			||||||
 | 
					                        <RadzenButton Size="ButtonSize.Medium" ButtonStyle="ButtonStyle.Success" Icon="add_circle_outline" Click="@(() => InsertRow())" Disabled="@(rolesToInsert.Count() > 0)" Text="新增" />
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					            <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					            LoadData="@LoadData"
 | 
				
			||||||
 | 
					            IsLoading="@isLoading"
 | 
				
			||||||
 | 
					            Count="@count"
 | 
				
			||||||
 | 
					            EmptyText="无数据"
 | 
				
			||||||
 | 
					            Data="@roleList"
 | 
				
			||||||
 | 
					            AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					            RowUpdate="@((Pojo.Role r) => { OnUpdateRow(r); })" RowCreate="@((Pojo.Role r) => { OnCreateRow(r); })"
 | 
				
			||||||
 | 
					            SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					            AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Width="50px" Title="ID" Property="Id"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Width="120px" Title="角色名称" Property="RoleName">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="role">
 | 
				
			||||||
 | 
					                            <RadzenTextBox Name="RoleName" @bind-Value="role.RoleName" Style="width:100%; display: block;" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Style="position: absolute;z-index: 9999;" Text="请填写角色名称" Component="RoleName" Popup="true" />
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="权限" Property="permissions">
 | 
				
			||||||
 | 
					                        <Template Context="role">
 | 
				
			||||||
 | 
					                            @string.Join(", ", allPremissions.Where(g => role.permissionIds?.Contains(g.Id) == true).Select(g => $"{g.PremissionName}"))
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                        <EditTemplate Context="role">
 | 
				
			||||||
 | 
					                            <RadzenDropDown @ref=dd @bind-Value=@role.permissionIds TValue="IEnumerable<int>" AllowClear="true" Name="Permissions"
 | 
				
			||||||
 | 
					                            Data=@allPremissions Style="width: 100%; max-width: 400px; display: block;" ItemRender="ItemRender">
 | 
				
			||||||
 | 
					                                <Template Context="p">
 | 
				
			||||||
 | 
					                                    <RadzenCheckBox TValue="bool?" TriState=false Value="@IsGroupSelected(role,p)" Change="@(args => SelectGroup(args, role, (Premission)p))" />
 | 
				
			||||||
 | 
					                                    <RadzenLabel Style=@($"margin-inline-start: 0.5rem; font-weight: {(p.Parent == null ? "bold" : "normal")}")
 | 
				
			||||||
 | 
					                                    Text="@(p.PremissionName)"
 | 
				
			||||||
 | 
					                                    onclick="event.target.previousElementSibling.querySelector('.rz-chkbox-box').click()" />
 | 
				
			||||||
 | 
					                                </Template>
 | 
				
			||||||
 | 
					                                <ValueTemplate Context="p">
 | 
				
			||||||
 | 
					                                    @string.Join(", ", allPremissions.Where(g => role.permissionIds?.Contains(g.Id) == true).Take(dd.MaxSelectedLabels).Select(g => $"{g.PremissionName}"))
 | 
				
			||||||
 | 
					                                </ValueTemplate>
 | 
				
			||||||
 | 
					                            </RadzenDropDown>
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Style="position: absolute;z-index: 9999;" Text="请选择权限" Component="Permissions" Popup="true" />
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Width="200px" Context="role" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Frozen="true" FrozenPosition="FrozenColumnPosition.Right">
 | 
				
			||||||
 | 
					                        <Template Context="role">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@(args => EditRow(role))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(role))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                        <EditTemplate Context="role">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => SaveRow(role))" aria-label="Save">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@((args) => CancelEdit(role))" aria-label="Cancel">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(role))" aria-label="Delete">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IRoleDao roleDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<Pojo.Role> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<Pojo.Role>? roleList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RadzenDropDown<IEnumerable<int>> dd;
 | 
				
			||||||
 | 
					    IEnumerable<Premission> allPremissions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    string RoleName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected override async Task OnInitializedAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        await base.OnInitializedAsync();
 | 
				
			||||||
 | 
					        List<Premission> t = new Premission().getAdminPremission();
 | 
				
			||||||
 | 
					        IEnumerable<Premission> t2 = Enumerable.Empty<Premission>();
 | 
				
			||||||
 | 
					        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<Pojo.Role> rolesToInsert = new List<Pojo.Role>();
 | 
				
			||||||
 | 
					    List<Pojo.Role> rolesToUpdate = new List<Pojo.Role>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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<ConfirmDialo>(
 | 
				
			||||||
 | 
					               $"删除确认",
 | 
				
			||||||
 | 
					             new Dictionary<string, object>() { { "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<IEnumerable<int>> 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<int> 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<int> permissionIds = role.permissionIds;
 | 
				
			||||||
 | 
					        var newValues = permissionIds ?? Enumerable.Empty<int>();
 | 
				
			||||||
 | 
					        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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,294 @@
 | 
				
			||||||
 | 
					@page "/take/self"
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <RadzenTemplateForm Data="@orderInfo" Submit="@(((OrderInfo args) => { Submit(args); }))">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="手写处方">
 | 
				
			||||||
 | 
					                    <RadzenRow Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="处方号" Component="OrderNo" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="orderInfo.OrderNo" Style="width: 100%;" Name="OrderNo"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                    <RadzenRequiredValidator Text="请输入处方号" Component="OrderNo" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="处方时间" Component="OrderDate" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenDatePicker DateFormat="yyyy-MM-dd HH:mm:ss" CurrentDateChanged="@OnCurrentDateChanged"
 | 
				
			||||||
 | 
					                                    ShowTime="true" ShowSeconds="true"
 | 
				
			||||||
 | 
					                                    @bind-Value="orderInfo.OrderDate" Style="width: 100%;" Name="OrderDate" />
 | 
				
			||||||
 | 
					                                    <RadzenRequiredValidator Text="请输入处方时间" Component="OrderDate" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="患者姓名" Component="PatientName" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="orderInfo.PatientName" Style="width: 100%;" Name="PatientName"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                    <RadzenRequiredValidator Text="请输入患者姓名" Component="PatientName" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="2">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="性别" Component="Sex" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="orderInfo.Sex" Style="width: 100%;" Name="Sex"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                    <RadzenRequiredValidator Text="请输入患者性别" Component="Sex" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="2">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="年龄" Component="Age" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="orderInfo.Age" Style="width: 100%;" Name="Age"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                    <RadzenRequiredValidator Text="请输入患者年龄" Component="Age" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="处方医生" Component="DoctorName" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="orderInfo.DoctorName" Style="width: 100%;" Name="DoctorName"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                    <RadzenRequiredValidator Text="请输入处方医生" Component="DoctorName" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="科室" Component="DeptName" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="orderInfo.DeptName" Style="width: 100%;" Name="DeptName"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                    <RadzenRequiredValidator Text="请输入科室" Component="DeptName" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="6">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="2">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="诊断" Component="Disease" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="10">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="orderInfo.Disease" Style="width: 100%;" Name="Disease"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                    <RadzenRequiredValidator Text="请输入诊断" Component="Disease" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                        <RadzenColumn Size="6">
 | 
				
			||||||
 | 
					                            <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.SpaceBetween">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" ButtonType="ButtonType.Submit" Disabled="@(detailsToInsert.Count() > 0 || detailsToUpdate.Count() > 0)" Text="确定" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Large" Icon="add_circle_outline" ButtonStyle="ButtonStyle.Success" Click="@InsertRow" Disabled="@(detailsToInsert.Count() > 0)" Text="添加" />
 | 
				
			||||||
 | 
					                            </RadzenStack>
 | 
				
			||||||
 | 
					                        </RadzenColumn>
 | 
				
			||||||
 | 
					                    </RadzenRow>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </RadzenTemplateForm>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					            EmptyText="请添加手写处方详情"
 | 
				
			||||||
 | 
					            Data="@orderDetails"
 | 
				
			||||||
 | 
					            EditMode="DataGridEditMode.Single"
 | 
				
			||||||
 | 
					            RowUpdate="@((OrderDetail od) => { OnUpdateRow(od); })" RowCreate="@((OrderDetail od) => { OnCreateRow(od); })"
 | 
				
			||||||
 | 
					            AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					            SelectionMode="DataGridSelectionMode.Single">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="药品名称" Property="Drug.DrugName">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="od">
 | 
				
			||||||
 | 
					                            @* <RadzenDropDown Name="Drug" TValue="DrugInfo" @bind-Value="od.Drug" Data="@drugInfos" Style="width:100%; display: block;"  /> *@
 | 
				
			||||||
 | 
					                            <RadzenDropDownDataGrid AllowVirtualization="true" Name="Drug" TValue="DrugInfo" @bind-Value="od.Drug" Data="@drugInfos" Style="width:100%; display: block;" AllowFilteringByAllStringColumns="true">
 | 
				
			||||||
 | 
					                                <Columns>
 | 
				
			||||||
 | 
					                                    <RadzenDropDownDataGridColumn Property="DrugId" Title="药品编码" />
 | 
				
			||||||
 | 
					                                    <RadzenDropDownDataGridColumn Property="DrugName" Width="120px" Title="名称" />
 | 
				
			||||||
 | 
					                                    <RadzenDropDownDataGridColumn Property="DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                                    <RadzenDropDownDataGridColumn Property="StockQuantity" Title="库存" Frozen="true" FrozenPosition="FrozenColumnPosition.Right" />
 | 
				
			||||||
 | 
					                                </Columns>
 | 
				
			||||||
 | 
					                            </RadzenDropDownDataGrid>
 | 
				
			||||||
 | 
					                            <RadzenCustomValidator Style="position: absolute;z-index: 9999;" Component="Drug" Validator="@(() => !String.IsNullOrEmpty(od.Drug.DrugId ))" Text="请选择药品" />
 | 
				
			||||||
 | 
					                            <RadzenCustomValidator Component="Drug" Validator="@(() => ValidateDrug(od.Drug))" Text="已经选择的药品不能再次选择" />
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="规格" Property="Drug.DrugSpec"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="数量" Property="Quantity">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="od">
 | 
				
			||||||
 | 
					                            <RadzenNumeric Style="width:100%; display: block;" Name="Quantity" @bind-Value=@od.Quantity />
 | 
				
			||||||
 | 
					                            <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="1" Max="@od.Drug.StockQuantity" Text="请填写正确的取出数量" Component="Quantity" />
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Context="detail" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Frozen="true" FrozenPosition="FrozenColumnPosition.Right">
 | 
				
			||||||
 | 
					                        <Template Context="detail">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@(args => EditRow(detail))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(detail))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                        <EditTemplate Context="detail">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => SaveRow(detail))" aria-label="Save">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@((args) => CancelEdit(detail))" aria-label="Cancel">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(detail))" aria-label="Delete">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IChannelListDao channelListDao;
 | 
				
			||||||
 | 
					    @inject IDrugInfoDao drugInfoDao;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<OrderDetail> grid;
 | 
				
			||||||
 | 
					    List<OrderDetail> orderDetails = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<DrugInfo> drugInfos = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<OrderDetail> detailsToInsert = new();
 | 
				
			||||||
 | 
					    List<OrderDetail> 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<SelfTakeDialog>(
 | 
				
			||||||
 | 
					                $"取药详情",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Gap="1rem" Orientation="Orientation.Vertical" Style="height: 100%;">
 | 
				
			||||||
 | 
					    <RadzenStack>
 | 
				
			||||||
 | 
					        <RadzenStack class="rz-p-4 rz-border-radius-1" Style="border: var(--rz-grid-cell-border)" Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">处方号:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.OrderNo)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">患者姓名:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.PatientName)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">性别:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.Sex)</b></RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">年龄:</RadzenText>
 | 
				
			||||||
 | 
					            <RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(order?.Age)</b></RadzenText>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </RadzenStack>
 | 
				
			||||||
 | 
					        @if (CanTakeDrug)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenDataGrid Data="@data" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="ChannelStock" Title="库位">
 | 
				
			||||||
 | 
					                        <Template>
 | 
				
			||||||
 | 
					                            @context.ChannelStock.DrawerNo - @context.ChannelStock.ColNo
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="ChannelStock.ManuNo" Title="批次" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="ChannelStock.EffDate" Title="效期" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Quantity" Title="数量" />
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenDataGrid Data="@data" AllowAlternatingRows="false">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="Quantity" Title="取药数量" />
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Property="StockQuantity" Title="库存" />
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
 | 
				
			||||||
 | 
					        @if (status < 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@OpenDrawer" Disabled="!CanTakeDrug" IsBusy="status > 0" BusyText="取药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="取药" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status == 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@TakeFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        @if (status <= 2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            <RadzenButton Click="@((args) => dialogService.Close(false))" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					@inject Radzen.DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					    @inject ISelfTakeDao selfTakeDao;
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Parameter] public OrderInfo order { get; set; }
 | 
				
			||||||
 | 
					    [Parameter] public List<OrderDetail> orderDetails{ get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private bool CanTakeDrug = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public List<OrderTakeVo> 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<OrderTakeVo> drawerNos = this.data.GroupBy(it => it.ChannelStock.DrawerNo).Select(it => it.First()).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 根据抽屉类型来决定打开前是否需要查询数量
 | 
				
			||||||
 | 
					        var promiseUtil = new PromiseUtil<int>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,66 @@
 | 
				
			||||||
 | 
					@page "/signature/{user}"
 | 
				
			||||||
 | 
					@layout EmptyLayout
 | 
				
			||||||
 | 
					<RadzenStack AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center">
 | 
				
			||||||
 | 
					    @if (user.Sign != null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        <RadzenImage Path="@($"data:image/png;base64,{Convert.ToBase64String(user.Sign)}")" Style="width:160px;height:80px;" />
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    <div class="border">
 | 
				
			||||||
 | 
					        <canvas />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center">
 | 
				
			||||||
 | 
					        <RadzenButton Text="清除" Click="@(() => handleClear())" />
 | 
				
			||||||
 | 
					        <RadzenButton Text="撤销" Click="@(() => handleUndo())" />
 | 
				
			||||||
 | 
					        <RadzenButton Text="保存" Click="@(() => handlePreview())" />
 | 
				
			||||||
 | 
					    </RadzenStack>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@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<IJSObjectReference>("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<bool>("isEmpty");
 | 
				
			||||||
 | 
					        if (flag)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string base64 = await module.InvokeAsync<string>("getPNG");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await userDao.UpdateSign(user.Id, base64.Split(",")[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            dialogService.Close(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,290 @@
 | 
				
			||||||
 | 
					@page "/stock/binding"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        @* <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="药品" Component="Drug" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDropDownDataGrid AllowVirtualization="true" Name="Drug" TValue="DrugInfo" @bind-Value="drugInfo" Data="@drugInfos"
 | 
				
			||||||
 | 
					                                                        Style="width:100%; display: block;" AllowFilteringByAllStringColumns="true" TextProperty="DrugName">
 | 
				
			||||||
 | 
					                                    <Columns>
 | 
				
			||||||
 | 
					                                        <RadzenDropDownDataGridColumn Property="DrugId" Title="药品编码" />
 | 
				
			||||||
 | 
					                                        <RadzenDropDownDataGridColumn Property="DrugName" Width="120px" Title="名称" />
 | 
				
			||||||
 | 
					                                        <RadzenDropDownDataGridColumn Property="DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                                    </Columns>
 | 
				
			||||||
 | 
					                                </RadzenDropDownDataGrid>
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                <RadzenLabel Text="批次" Component="DropDownBindValue" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                <RadzenDropDownDataGrid @bind-Value=@drugManuNo Data=@drugInfo?.Manus Disabled="@(drugInfo == null)" Name="DropDownBindValue" TextProperty="ManuNo">
 | 
				
			||||||
 | 
					                                    <Columns>
 | 
				
			||||||
 | 
					                                        <RadzenDropDownDataGridColumn Property="ManuNo" Title="批次" />
 | 
				
			||||||
 | 
					                                        <RadzenDropDownDataGridColumn Property="EffDate" Title="效期" />
 | 
				
			||||||
 | 
					                                    </Columns>
 | 
				
			||||||
 | 
					                                </RadzenDropDownDataGrid>
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="绑定" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="解绑" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                                <RadzenButton Size="ButtonSize.Medium" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="刷新" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div> *@
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <RadzenDataList @ref="grid" LoadData="@LoadData" WrapItems="true" Count="@count" IsLoading="@isLoading" Data="@_forecasts" PageSize="6" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left"
 | 
				
			||||||
 | 
					            ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenCard class="col-3">
 | 
				
			||||||
 | 
					                        <RadzenRow>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="8" Class="rz-text-truncate">
 | 
				
			||||||
 | 
					                                <b class="rz-pr-3">@(channel.DrawerNo) - @(channel.ColNo)</b>
 | 
				
			||||||
 | 
					                                @if(channel.DrawerType == 1)
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    switch(channel.BoardType)
 | 
				
			||||||
 | 
					                                    {
 | 
				
			||||||
 | 
					                                        case 1:
 | 
				
			||||||
 | 
					                                            <b>物理隔板</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 2:
 | 
				
			||||||
 | 
					                                            <b>单支计数</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 3:
 | 
				
			||||||
 | 
					                                            <b>管控药盒</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 4:
 | 
				
			||||||
 | 
					                                            <b>储物箱</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 5:
 | 
				
			||||||
 | 
					                                            <b>智能显示</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 6:
 | 
				
			||||||
 | 
					                                            <b>称重计数</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 63:
 | 
				
			||||||
 | 
					                                            <b>称重计数药盒</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 653:
 | 
				
			||||||
 | 
					                                            <b>称重计数药盒智能显示</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                else if (channel.DrawerType == 2)
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    switch (channel.BoardType)
 | 
				
			||||||
 | 
					                                    {
 | 
				
			||||||
 | 
					                                        case 1:
 | 
				
			||||||
 | 
					                                            <b>内置回收</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 2:
 | 
				
			||||||
 | 
					                                            <b>内置计数回收</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 3:
 | 
				
			||||||
 | 
					                                            <b>内置药盒回收</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 4:
 | 
				
			||||||
 | 
					                                            <b>储物回收箱</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 5:
 | 
				
			||||||
 | 
					                                            <b>内置智能显示回收</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 6:
 | 
				
			||||||
 | 
					                                            <b>内置称重计数回收</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 63:
 | 
				
			||||||
 | 
					                                            <b>内置称重计数药盒回收</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                        case 653:
 | 
				
			||||||
 | 
					                                            <b>内置称重计数药盒智能显示回收</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                else
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    switch (channel.BoardType)
 | 
				
			||||||
 | 
					                                    {
 | 
				
			||||||
 | 
					                                        case 1:
 | 
				
			||||||
 | 
					                                            <b>外置回收</b>
 | 
				
			||||||
 | 
					                                            break;
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                            <RadzenColumn Size="4" Class="rz-text-align-end">
 | 
				
			||||||
 | 
					                                @if(channel.Quantity == 0)
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    <RadzenButton ButtonStyle="ButtonStyle.Secondary" Variant="Variant.Outlined" Size="ButtonSize.Small" Click="@(() => EditChannel(channel))" Text="绑定/解绑" />
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            </RadzenColumn>
 | 
				
			||||||
 | 
					                        </RadzenRow>
 | 
				
			||||||
 | 
					                        <hr style="border: none; background-color: rgba(0,0,0,.2); height: 1px; margin: 1rem 0;" />
 | 
				
			||||||
 | 
					                        <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                            <RadzenStack Gap="0">
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Overline" class="rz-display-flex rz-mt-2 rz-my-0">药品</RadzenText>
 | 
				
			||||||
 | 
					                                @if (channel.DrugId == null || channel.Quantity == 0)
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    <RadzenDropDownDataGrid Change="@((args) => { channel.drugManuNo = null; })" AllowVirtualization="true" Name="@("Drug_" + channel.Id)" TValue="DrugInfo" @bind-Value="channel.Drug" Data="@drugInfos"
 | 
				
			||||||
 | 
					                                    Style="width:100%; display: block;" AllowFilteringByAllStringColumns="true" TextProperty="DrugName">
 | 
				
			||||||
 | 
					                                        <Columns>
 | 
				
			||||||
 | 
					                                            <RadzenDropDownDataGridColumn Property="DrugId" Title="药品编码" />
 | 
				
			||||||
 | 
					                                            <RadzenDropDownDataGridColumn Property="DrugName" Width="120px" Title="名称" />
 | 
				
			||||||
 | 
					                                            <RadzenDropDownDataGridColumn Property="DrugSpec" Title="规格" />
 | 
				
			||||||
 | 
					                                        </Columns>
 | 
				
			||||||
 | 
					                                    </RadzenDropDownDataGrid>
 | 
				
			||||||
 | 
					                                } else
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Body1"><b>@(channel.Drug?.DrugName)</b></RadzenText>
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Body1"><b>@(channel.Drug?.DrugSpec)</b></RadzenText>
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                @if(channel.DrawerType == 1)
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Overline" class="rz-display-flex rz-mt-4 rz-mb-0">批次</RadzenText>
 | 
				
			||||||
 | 
					                                    @if (channel.DrugId == null || channel.Quantity == 0)
 | 
				
			||||||
 | 
					                                    {
 | 
				
			||||||
 | 
					                                        <RadzenDropDownDataGrid @bind-Value=@channel.drugManuNo Data=@channel.Drug?.Manus Disabled="@(channel.Drug == null)" TValue="DrugManuNo" Name="@("Drugmanu_" + channel.Id)" TextProperty="ManuNo">
 | 
				
			||||||
 | 
					                                            <Columns>
 | 
				
			||||||
 | 
					                                                <RadzenDropDownDataGridColumn Property="ManuNo" Title="批次" />
 | 
				
			||||||
 | 
					                                                <RadzenDropDownDataGridColumn Property="EffDate" Title="效期" />
 | 
				
			||||||
 | 
					                                            </Columns>
 | 
				
			||||||
 | 
					                                        </RadzenDropDownDataGrid>
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                    else
 | 
				
			||||||
 | 
					                                    {
 | 
				
			||||||
 | 
					                                        <RadzenText TextStyle="TextStyle.Body1"><b>@(channel.ManuNo)</b></RadzenText>
 | 
				
			||||||
 | 
					                                        <RadzenText TextStyle="TextStyle.Body1"><b>@(channel.EffDate)</b></RadzenText>
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Overline" class="rz-display-flex rz-mt-4 rz-mb-0">库存</RadzenText>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Body1"><b>@(channel.Quantity)</b></RadzenText>
 | 
				
			||||||
 | 
					                            </RadzenStack>
 | 
				
			||||||
 | 
					                        </RadzenStack>
 | 
				
			||||||
 | 
					                    </RadzenCard>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataList>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IChannelListDao channelListDao;
 | 
				
			||||||
 | 
					    @inject IDrugInfoDao drugInfoDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    RadzenDataList<ChannelStock> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<ChannelStock>? _forecasts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<DrugInfo> drugInfos;
 | 
				
			||||||
 | 
					    List<DrugManuNo> 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
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,307 @@
 | 
				
			||||||
 | 
					@page "/stock/check"
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Pojo.Config
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Util
 | 
				
			||||||
 | 
					@using Microsoft.Extensions.Options
 | 
				
			||||||
 | 
					@using Newtonsoft.Json
 | 
				
			||||||
 | 
					@using log4net
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    .rz-custom-header {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<RadzenStack Orientation="Orientation.Horizontal">
 | 
				
			||||||
 | 
					    <div class="row  justify-content-center">
 | 
				
			||||||
 | 
					        <div class="col-12 row justify-content-center align-items-center text-center" style="background: url('/images/box.png')  no-repeat; background-size: 100% 100%; width: 380px; height:650px">
 | 
				
			||||||
 | 
					            @* <RadzenStack AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center" Orientation="Orientation.Vertical" Style="margin-top: 220px"> *@
 | 
				
			||||||
 | 
					            <div class="row justify-content-around align-items-center" style="margin-top: 220px; height: 430px;">
 | 
				
			||||||
 | 
					                @foreach (int i in DrawerNos)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton class="col-5" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            @* </RadzenStack> *@
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					    LoadData="@LoadData"
 | 
				
			||||||
 | 
					    IsLoading="@isLoading"
 | 
				
			||||||
 | 
					    Count="@count"
 | 
				
			||||||
 | 
					    EmptyText="无数据"
 | 
				
			||||||
 | 
					    Data="@channels"
 | 
				
			||||||
 | 
					    AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					    CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args))"
 | 
				
			||||||
 | 
					    AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					        <HeaderTemplate>
 | 
				
			||||||
 | 
					            <RadzenRow JustifyContent="JustifyContent.End">
 | 
				
			||||||
 | 
					                @if (status < 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton IsBusy="@(status>0)" BusyText="盘点中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="盘点" Click="@OpenDrawer" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @if (status == 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="完成" Click="@CheckFinish" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @if (status > 0 && status <= 3)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    <RadzenButton Variant="Variant.Flat" Shade="Shade.Light" Text="取消" Click="@Cancel" Style="width: 120px" />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </RadzenRow>
 | 
				
			||||||
 | 
					        </HeaderTemplate>
 | 
				
			||||||
 | 
					        <Columns>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Width="70px" Title="库位" Property="ColNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="药品名称" Property="Drug.DrugName">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.Drug?.DrugName</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Caption">@channel.Drug?.DrugSpec</RadzenText>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="批次" Property="ManuNo">
 | 
				
			||||||
 | 
					                <Template Context="channel">
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                    <RadzenText TextStyle="TextStyle.Caption">@channel.drugManuNo?.EffDate</RadzenText>
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					                <EditTemplate Context="channel">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    @if (channel.Quantity == 0 && !String.IsNullOrEmpty(channel.DrugId))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenDropDown TValue="DrugManuNo" Name="ManuNo" @bind-Value="channel.drugManuNo" Data="@channel.Drug?.Manus" Style="width:100%; display: block;">
 | 
				
			||||||
 | 
					                            <Template>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
 | 
				
			||||||
 | 
					                                <RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
 | 
				
			||||||
 | 
					                            </Template>
 | 
				
			||||||
 | 
					                            <ValueTemplate>
 | 
				
			||||||
 | 
					                                <RadzenStack Orientation="Orientation.Horizontal">
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
 | 
				
			||||||
 | 
					                                    <RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
 | 
				
			||||||
 | 
					                                </RadzenStack>
 | 
				
			||||||
 | 
					                            </ValueTemplate>
 | 
				
			||||||
 | 
					                        </RadzenDropDown>
 | 
				
			||||||
 | 
					                        <RadzenRequiredValidator Text="请选择批次" Component="ManuNo" Popup="true" />
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
 | 
				
			||||||
 | 
					                        <RadzenText TextStyle="TextStyle.Caption">@channel.drugManuNo?.EffDate</RadzenText>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </EditTemplate>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="库存" Property="Quantity">
 | 
				
			||||||
 | 
					                <Template Context="cs">
 | 
				
			||||||
 | 
					                    <RadzenButton ButtonStyle="ButtonStyle.Info" Variant="Variant.Flat" Shade="Shade.Lighter" class="m-1" Text="@cs.Quantity.ToString()" />
 | 
				
			||||||
 | 
					                </Template>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn MinWidth="120px" Title="盘点数量" Property="CheckQuantity">
 | 
				
			||||||
 | 
					                <EditTemplate Context="cs">
 | 
				
			||||||
 | 
					                    @if (cs.BoardType == 2)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        @cs.CheckQuantity
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        <RadzenNumeric Min="0" Style="display: block" Name="CheckQuantity" @bind-Value=@cs.CheckQuantity />
 | 
				
			||||||
 | 
					                        <RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Text="请填写正确的盘点数量" Component="CheckQuantity" Popup="true" />
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </EditTemplate>
 | 
				
			||||||
 | 
					            </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        </Columns>
 | 
				
			||||||
 | 
					    </RadzenDataGrid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IChannelListDao channelListDao;
 | 
				
			||||||
 | 
					    @inject NavigationManager na;
 | 
				
			||||||
 | 
					    @inject PortUtil PortUtil;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    @inject IOptions<DrawerConfig> setting;
 | 
				
			||||||
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					    int drawerNo = 1;
 | 
				
			||||||
 | 
					    RadzenDataGrid<ChannelStock> grid;
 | 
				
			||||||
 | 
					    private List<ChannelStock>? 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<object>();
 | 
				
			||||||
 | 
					        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<ChannelStock> 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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,90 @@
 | 
				
			||||||
 | 
					@page "/stock/list"
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    .rz-custom-header {
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					        IsLoading="@isLoading"
 | 
				
			||||||
 | 
					        RowRender="@RowRender"
 | 
				
			||||||
 | 
					        EmptyText="无数据"
 | 
				
			||||||
 | 
					        Data="@_forecasts"
 | 
				
			||||||
 | 
					        AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					        SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					        ExpandMode="DataGridExpandMode.Multiple">
 | 
				
			||||||
 | 
					        <HeaderTemplate>
 | 
				
			||||||
 | 
					            <RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                <RadzenButton Icon="download" Text="库存导出" Variant="Variant.Outlined" />
 | 
				
			||||||
 | 
					                <RadzenButton Icon="download" Text="专用账册导出" Variant="Variant.Outlined" />
 | 
				
			||||||
 | 
					            </RadzenRow>
 | 
				
			||||||
 | 
					        </HeaderTemplate>
 | 
				
			||||||
 | 
					        <Template Context="di">
 | 
				
			||||||
 | 
					            <RadzenDataGrid Data="@di.Stocks" EmptyText="无数据">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="库位" Property="DrawerNo">
 | 
				
			||||||
 | 
					                        <Template Context="s">
 | 
				
			||||||
 | 
					                            @s.DrawerNo - @s.ColNo
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="数量" Property="Quantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="效期" Property="EffDate"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </Template>
 | 
				
			||||||
 | 
					        <Columns>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Frozen="true" Width="200px" Title="药品名称" Property="DrugName"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="规格" Property="DrugSpec"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					            <RadzenDataGridColumn Title="总库存" Property="StockQuantity"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					        </Columns>
 | 
				
			||||||
 | 
					    </RadzenDataGrid>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IDrugInfoDao drugInfoDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    RadzenDataGrid<DrugInfo> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<DrugInfo>? _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<DrugInfo> args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        args.Expandable = args.Data.Stocks.Count > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,87 @@
 | 
				
			||||||
 | 
					@page "/TEST"
 | 
				
			||||||
 | 
					@layout EmptyLayout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" AlignItems="AlignItems.Center" Gap="0.5rem" class="rz-p-12">
 | 
				
			||||||
 | 
					    <RadzenLabel Text="Select Value" Component="DropDownDataGridBindValue" />
 | 
				
			||||||
 | 
					    <RadzenDropDownDataGrid @ref=grid Data="@data" ColumnWidth="200px" TValue="IDictionary<string, object>"
 | 
				
			||||||
 | 
					                            AllowFiltering="true" AllowSorting="true" Value="@selectedItem" Change="@OnChange">
 | 
				
			||||||
 | 
					                            @* TextProperty="@(PropertyAccess.GetDynamicPropertyExpression("LastName", typeof(string)))"> *@
 | 
				
			||||||
 | 
					        <ValueTemplate>
 | 
				
			||||||
 | 
					            @string.Join(", ", columns.Where(c => c.Value == typeof(string)).Take(grid.MaxSelectedLabels).Select(c => context[c.Key]))
 | 
				
			||||||
 | 
					        </ValueTemplate>
 | 
				
			||||||
 | 
					        <Columns>
 | 
				
			||||||
 | 
					            @foreach (var column in columns)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                <RadzenDropDownDataGridColumn @key=@column.Key Title="@column.Key" Type="column.Value">
 | 
				
			||||||
 | 
					                                              @* Property="@PropertyAccess.GetDynamicPropertyExpression(column.Key, column.Value)"> *@
 | 
				
			||||||
 | 
					                    <Template>
 | 
				
			||||||
 | 
					                        @context[@column.Key]
 | 
				
			||||||
 | 
					                    </Template>
 | 
				
			||||||
 | 
					                </RadzenDropDownDataGridColumn>
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        </Columns>
 | 
				
			||||||
 | 
					    </RadzenDropDownDataGrid>
 | 
				
			||||||
 | 
					</RadzenStack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    RadzenDropDownDataGrid<IDictionary<string, object>> grid;
 | 
				
			||||||
 | 
					    IDictionary<string, object> selectedItem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public IEnumerable<IDictionary<string, object>> data { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public IDictionary<string, Type> columns { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public enum EnumTest
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        EnumValue1,
 | 
				
			||||||
 | 
					        EnumValue2
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void OnChange(object value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        selectedItem = (IDictionary<string, object>)value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected override async Task OnInitializedAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        await base.OnInitializedAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        columns = new Dictionary<string, Type>()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            { "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<string, object>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,306 @@
 | 
				
			||||||
 | 
					@page "/manage/user"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@using log4net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <form onsubmit="@(() => grid.Reload())">
 | 
				
			||||||
 | 
					                <RadzenFieldset Text="查询">
 | 
				
			||||||
 | 
					                    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.SpaceBetween">
 | 
				
			||||||
 | 
					                        <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="4">
 | 
				
			||||||
 | 
					                                    <RadzenLabel Text="用户名" Component="nickname" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="8">
 | 
				
			||||||
 | 
					                                    <RadzenTextBox @bind-Value="nickname" Style="width: 100%;" Name="nickname"></RadzenTextBox>
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <RadzenRow AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                                <RadzenColumn Size="12">
 | 
				
			||||||
 | 
					                                    <RadzenButton Size="ButtonSize.Medium" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="查询" />
 | 
				
			||||||
 | 
					                                    <RadzenButton Size="ButtonSize.Medium" Click="reloadGrid" IsBusy="isLoading" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
 | 
				
			||||||
 | 
					                                </RadzenColumn>
 | 
				
			||||||
 | 
					                            </RadzenRow>
 | 
				
			||||||
 | 
					                        </RadzenStack>
 | 
				
			||||||
 | 
					                        <RadzenButton Size="ButtonSize.Medium" ButtonStyle="ButtonStyle.Success" Icon="add_circle_outline" Click="@InsertRow" Disabled="@(usersToInsert.Count() > 0)" Text="新增" />
 | 
				
			||||||
 | 
					                    </RadzenStack>
 | 
				
			||||||
 | 
					                </RadzenFieldset>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-12 mb-4">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <RadzenDataGrid @ref="grid"
 | 
				
			||||||
 | 
					            LoadData="@LoadData"
 | 
				
			||||||
 | 
					            IsLoading="@isLoading"
 | 
				
			||||||
 | 
					            Count="@count"
 | 
				
			||||||
 | 
					            EmptyText="无数据"
 | 
				
			||||||
 | 
					            Data="@userList"
 | 
				
			||||||
 | 
					            Page="@Reset"
 | 
				
			||||||
 | 
					            EditMode="DataGridEditMode.Single"
 | 
				
			||||||
 | 
					            AllowColumnResize="true" AllowAlternatingRows="false"
 | 
				
			||||||
 | 
					            RowUpdate="@((Pojo.User u) => { OnUpdateRow(u); })" RowCreate="@((Pojo.User u) => { OnCreateRow(u); })"
 | 
				
			||||||
 | 
					            SelectionMode="DataGridSelectionMode.Single"
 | 
				
			||||||
 | 
					            AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
 | 
				
			||||||
 | 
					                <Columns>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="ID" Property="Id"></RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="用户名" Property="NickName">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="user">
 | 
				
			||||||
 | 
					                            <RadzenTextBox Name="NickName" @bind-Value="user.NickName" Style="width:100%; display: block;" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Text="请填写用户名" Component="NickName" Popup="true" />
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="账号" Property="Username">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="user">
 | 
				
			||||||
 | 
					                            <RadzenTextBox Name="Username" @bind-Value="user.Username" Style="width:100%; display: block;" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Text="请填写账号" Component="Username" Popup="true" />
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Title="权限" Property="role.RoleName">
 | 
				
			||||||
 | 
					                        <EditTemplate Context="user">
 | 
				
			||||||
 | 
					                            <RadzenDropDown Name="RoleId" @bind-Value="user.RoleId" Data="@roles" TextProperty="RoleName" ValueProperty="Id" Style="width:100%; display: block;"
 | 
				
			||||||
 | 
					                            InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select customer" }})" />
 | 
				
			||||||
 | 
					                            <RadzenRequiredValidator Text="请选择角色" Component="RoleId" Popup="true" />
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <RadzenDataGridColumn Context="user" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Frozen="true" FrozenPosition="FrozenColumnPosition.Right">
 | 
				
			||||||
 | 
					                        <Template Context="user">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@(args => EditRow(user))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="edit_document" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" Click="@(args => Signatrue(user))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="fingerprint" ButtonStyle="ButtonStyle.Info" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => Reg2ZWJ(user))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(user))" @onclick:stopPropagation="true">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="https" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => ResetPasswordRow(user))" aria-label="ResetPassword">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        </Template>
 | 
				
			||||||
 | 
					                        <EditTemplate Context="user">
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => SaveRow(user))" aria-label="Save">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@((args) => CancelEdit(user))" aria-label="Cancel">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                           <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(user))" aria-label="Delete">
 | 
				
			||||||
 | 
					                            </RadzenButton>
 | 
				
			||||||
 | 
					                            <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="https" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => ResetPasswordRow(user))" aria-label="ResetPassword">
 | 
				
			||||||
 | 
					                            </RadzenButton> 
 | 
				
			||||||
 | 
					                        </EditTemplate>
 | 
				
			||||||
 | 
					                    </RadzenDataGridColumn>
 | 
				
			||||||
 | 
					                </Columns>
 | 
				
			||||||
 | 
					            </RadzenDataGrid>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code {
 | 
				
			||||||
 | 
					    @inject IUserDao userDao;
 | 
				
			||||||
 | 
					    @inject IRoleDao roleDao;
 | 
				
			||||||
 | 
					    @inject DialogService dialogService;
 | 
				
			||||||
 | 
					    @inject NotificationService _message
 | 
				
			||||||
 | 
					    RadzenDataGrid<Pojo.User> grid;
 | 
				
			||||||
 | 
					    bool isLoading;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    private IEnumerable<Pojo.User>? userList;
 | 
				
			||||||
 | 
					    string nickname;
 | 
				
			||||||
 | 
					    DateTime OrderDate;
 | 
				
			||||||
 | 
					    private readonly ILog logger = LogManager.GetLogger(typeof(Pages.User));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<Pojo.Role> roles;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<Pojo.User> usersToInsert = new List<Pojo.User>();
 | 
				
			||||||
 | 
					    List<Pojo.User> usersToUpdate = new List<Pojo.User>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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<FingerRegDialog>(
 | 
				
			||||||
 | 
					                $"录入指纹",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "userId", user.Id } },
 | 
				
			||||||
 | 
					              new DialogOptions() { Width = "55vw", Resizable = true, Draggable = true, ShowClose = false }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async Task Signatrue(Pojo.User user)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var flag = await dialogService.OpenAsync<SignatureDialog>(
 | 
				
			||||||
 | 
					                $"签名-{user.NickName}",
 | 
				
			||||||
 | 
					              new Dictionary<string, object>() { { "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<ConfirmDialo>(
 | 
				
			||||||
 | 
					               $"删除确认",
 | 
				
			||||||
 | 
					             new Dictionary<string, object>() { { "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<ConfirmDialo>(
 | 
				
			||||||
 | 
					               $"密码重置确认",
 | 
				
			||||||
 | 
					             new Dictionary<string, object>() { { "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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 主键 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("id", IsPrimaryKey = true, IsIdentity = true)]
 | 
				
			||||||
 | 
					        public int Id { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 设备id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("machine_id")]
 | 
				
			||||||
 | 
					        public string MachineId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 药品id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("drug_id")]
 | 
				
			||||||
 | 
					        public string DrugId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))]
 | 
				
			||||||
 | 
					        public DrugInfo Drug { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 数量 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("add_quantity")]
 | 
				
			||||||
 | 
					        public int AddQuantity { get; set; }
 | 
				
			||||||
 | 
					        [Column("out_quantity")]
 | 
				
			||||||
 | 
					        public int OutQuantity { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 批号 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("manu_no")]
 | 
				
			||||||
 | 
					        public string ManuNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 操作人id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("operator")]
 | 
				
			||||||
 | 
					        public int? Operator { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(Operator), OtherKey = nameof(User.Id))]
 | 
				
			||||||
 | 
					        public User OperatorUser { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 审核人id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("reviewer")]
 | 
				
			||||||
 | 
					        public int? Reviewer { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(Reviewer), OtherKey = nameof(User.Id))]
 | 
				
			||||||
 | 
					        public User ReviewerUser { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 操作时间 
 | 
				
			||||||
 | 
					        /// 默认值: CURRENT_TIMESTAMP
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("create_time")]
 | 
				
			||||||
 | 
					        public DateTime OperationTime { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 效期 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("eff_date")]
 | 
				
			||||||
 | 
					        public DateTime? EffDate { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 出库入库类型(1领入2发出3日结4日总结5转结) 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("type")]
 | 
				
			||||||
 | 
					        public int Type { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 出入库调拨单id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("invoice_id")]
 | 
				
			||||||
 | 
					        public string InvoiceId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 列号 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("yesterday_quantity")]
 | 
				
			||||||
 | 
					        public int YesterdayQuantity { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 抽屉号 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("manu_stock")]
 | 
				
			||||||
 | 
					        public int ManuStock { get; set; }
 | 
				
			||||||
 | 
					        [Column("total_stock")]
 | 
				
			||||||
 | 
					        public int TotalStock { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 取药科室 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("department")]
 | 
				
			||||||
 | 
					        public string department { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 退药量 
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("create_date")]
 | 
				
			||||||
 | 
					        public string CreateDate { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<ChannelStock> ChannelStocks { get; set; } = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))]
 | 
				
			||||||
 | 
					        public DrugInfo Drug { get; set; } = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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; }
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<ChannelStock> Stocks { get; set;} = new List<ChannelStock>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugManuNo.DrugId))]
 | 
				
			||||||
 | 
					        public List<DrugManuNo> Manus { get; set; } = new List<DrugManuNo>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [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}";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 主键(序号)       
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [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; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 库存管理单位(入库单位代码) 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("storage")]
 | 
				
			||||||
 | 
					        public string storage { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         /// <summary>
 | 
				
			||||||
 | 
					         /// 单据号
 | 
				
			||||||
 | 
					         /// </summary>
 | 
				
			||||||
 | 
					        [Column("invoice_no")]
 | 
				
			||||||
 | 
					        public string InvoiceNo { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Column("invoice_date")]
 | 
				
			||||||
 | 
					        public string InvoiceDate { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 药品id
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("drug_id")]
 | 
				
			||||||
 | 
					        public string DrugId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))]
 | 
				
			||||||
 | 
					        public DrugInfo Drug { get; set; } = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 药品规格
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("drug_spec")]
 | 
				
			||||||
 | 
					        public string DrugSpec { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 计算单位
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("units")]
 | 
				
			||||||
 | 
					        public string Units { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 厂商标识
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("firm_id")]
 | 
				
			||||||
 | 
					        public string FirmId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 包装规格(反映药品含量及包装信息,如0.25g*30)   
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("package_spec")]
 | 
				
			||||||
 | 
					        public string PackageSpec { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 数量(以包装单位所计的数量)      
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("quantity")]
 | 
				
			||||||
 | 
					        public int quantity { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 计量单位,可使用任一级管理上方便的包装
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("package_units")]
 | 
				
			||||||
 | 
					        public string PackageUnits { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 药品批次
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("drug_manu_no")]
 | 
				
			||||||
 | 
					        public string DrugManuNo { get; set; }
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 创建时间(入库日期)
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("create_time")]
 | 
				
			||||||
 | 
					        public DateTime CreateTime { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 2调拨出库1.调拨入库 0.调拨
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("type")]
 | 
				
			||||||
 | 
					        public int Type { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 类型描述
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("type_describe")]
 | 
				
			||||||
 | 
					        public string TypeDescribe { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 供货方
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("supplier")]
 | 
				
			||||||
 | 
					        public string Supplier { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 操作人
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("operator")]
 | 
				
			||||||
 | 
					        public string Operator { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 存放库房
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [Column("sub_storage")]
 | 
				
			||||||
 | 
					        public string SubStorage { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 备注
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [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; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 主键 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("id", IsPrimaryKey = true, IsIdentity = true)]
 | 
				
			||||||
 | 
					        public int Id { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 设备id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("machine_id")]
 | 
				
			||||||
 | 
					        public string MachineId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 药品id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("drug_id")]
 | 
				
			||||||
 | 
					        public string DrugId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))]
 | 
				
			||||||
 | 
					        public DrugInfo Drug { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 数量 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("quantity")]
 | 
				
			||||||
 | 
					        public int Quantity { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 批号 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("manu_no")]
 | 
				
			||||||
 | 
					        public string ManuNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 操作人id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("operator")]
 | 
				
			||||||
 | 
					        public int? Operator { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(Operator), OtherKey = nameof(User.Id))]
 | 
				
			||||||
 | 
					        public User OperatorUser { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 审核人id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("reviewer")]
 | 
				
			||||||
 | 
					        public int? Reviewer { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(Reviewer), OtherKey = nameof(User.Id))]
 | 
				
			||||||
 | 
					        public User ReviewerUser { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 操作时间 
 | 
				
			||||||
 | 
					        /// 默认值: CURRENT_TIMESTAMP
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("operation_time")]
 | 
				
			||||||
 | 
					        public DateTime OperationTime { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 效期 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("eff_date")]
 | 
				
			||||||
 | 
					        public DateTime? EffDate { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 出库入库类型(1入库2出库31还药32还空瓶) 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("type")]
 | 
				
			||||||
 | 
					        public int Type { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 出入库调拨单id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("invoice_id")]
 | 
				
			||||||
 | 
					        public string InvoiceId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 列号 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("col_no")]
 | 
				
			||||||
 | 
					        public int ColNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 抽屉号 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("drawer_no")]
 | 
				
			||||||
 | 
					        public int DrawerNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 取药科室 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("department_id")]
 | 
				
			||||||
 | 
					        public string DepartmentId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 是否已经退药(0:没有1:还了部分2:完成) 
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("status")]
 | 
				
			||||||
 | 
					        public int Status { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 退药量 
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("return_quantity1")]
 | 
				
			||||||
 | 
					        public int ReturnQuantity1 { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 退空瓶量 
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("return_quantity2")]
 | 
				
			||||||
 | 
					        public int ReturnQuantity2 { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Column(IsColumn = false)]
 | 
				
			||||||
 | 
					        public int CurrentReturnQuantity { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 取药记录id 
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("get_id")]
 | 
				
			||||||
 | 
					        public int? GetId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 是否已经销毁 
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,133 @@
 | 
				
			||||||
 | 
					using LinqToDB.Mapping;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					namespace MasaBlazorApp3.Pojo
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// 
 | 
				
			||||||
 | 
					    ///</summary>
 | 
				
			||||||
 | 
					    [Table("order_detail")]
 | 
				
			||||||
 | 
					    public class OrderDetail
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        [PrimaryKey]
 | 
				
			||||||
 | 
					        [Column("id")]
 | 
				
			||||||
 | 
					        public int Id { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        //[SugarColumn(ColumnName = "order_id")]
 | 
				
			||||||
 | 
					        //public int? OrderId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("patient_id")]
 | 
				
			||||||
 | 
					        public string PatientId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("order_no")]
 | 
				
			||||||
 | 
					        public string OrderNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("charge_date")]
 | 
				
			||||||
 | 
					        public DateTime ChargeDate { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        //[SugarColumn(ColumnName = "serial_no")]
 | 
				
			||||||
 | 
					        //public int? SerialNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("drug_id")]
 | 
				
			||||||
 | 
					        public string DrugId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugInfo.DrugId))]
 | 
				
			||||||
 | 
					        public DrugInfo Drug { get; set; } = new();
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("quantity")]
 | 
				
			||||||
 | 
					        public int Quantity { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("order_unit")]
 | 
				
			||||||
 | 
					        public string OrderUnit { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: 1
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("unit_convercoef")]
 | 
				
			||||||
 | 
					        public int? UnitConvercoef { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("set_manu_no")]
 | 
				
			||||||
 | 
					        public string SetManuNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("set_eff_date")]
 | 
				
			||||||
 | 
					        public string SetEffDate { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        //[SugarColumn(ColumnName = "price")]
 | 
				
			||||||
 | 
					        //public string Price { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        //[SugarColumn(ColumnName = "total_price")]
 | 
				
			||||||
 | 
					        //public string TotalPrice { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("use_discrip")]
 | 
				
			||||||
 | 
					        public string UseDiscrip { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("use_frequ")]
 | 
				
			||||||
 | 
					        public string UseFrequ { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("use_once")]
 | 
				
			||||||
 | 
					        public string UseOnce { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("use_by")]
 | 
				
			||||||
 | 
					        public string UseBy { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: '0'
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("use_self")]
 | 
				
			||||||
 | 
					        public string UseSelf { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("use_dosage")]
 | 
				
			||||||
 | 
					        public string UseDosage { get; set; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,159 @@
 | 
				
			||||||
 | 
					using LinqToDB.Mapping;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					namespace MasaBlazorApp3.Pojo
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// 
 | 
				
			||||||
 | 
					    ///</summary>
 | 
				
			||||||
 | 
					    [Table("order_info")]
 | 
				
			||||||
 | 
					    public class OrderInfo
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        [PrimaryKey, Identity]
 | 
				
			||||||
 | 
					        [Column("order_id")]
 | 
				
			||||||
 | 
					        public int OrderId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("pharmacy")]
 | 
				
			||||||
 | 
					        public string Pharmacy { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("order_no")]
 | 
				
			||||||
 | 
					        public string OrderNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("patient_id")]
 | 
				
			||||||
 | 
					        public string PatientId { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("p_name")]
 | 
				
			||||||
 | 
					        public string PatientName { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("sex")]
 | 
				
			||||||
 | 
					        public string Sex { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("age")]
 | 
				
			||||||
 | 
					        public string Age { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("id_number")]
 | 
				
			||||||
 | 
					        public string IdNumber { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("invoice_no")]
 | 
				
			||||||
 | 
					        public string InvoiceNo { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("patient_no")]
 | 
				
			||||||
 | 
					        public string PatientNo { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("doctor_name")]
 | 
				
			||||||
 | 
					        public string DoctorName { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("order_date")]
 | 
				
			||||||
 | 
					        public DateTime OrderDate { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("charge_date")]
 | 
				
			||||||
 | 
					        public DateTime ChargeDate { get; set; } = DateTime.Now;
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("recv_date")]
 | 
				
			||||||
 | 
					        public DateTime RecvDate { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("dept_name")]
 | 
				
			||||||
 | 
					        public string DeptName { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("disease")]
 | 
				
			||||||
 | 
					        public string Disease { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("order_type")]
 | 
				
			||||||
 | 
					        public string OrderType { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: NULL
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("charge_type")]
 | 
				
			||||||
 | 
					        public string ChargeType { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("dm_status")]
 | 
				
			||||||
 | 
					        public int Status { get; set; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("his_disp_flag")]
 | 
				
			||||||
 | 
					        public int? HisDispFlag { get; set; }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("cancel_flag")]
 | 
				
			||||||
 | 
					        public int? CancelFlag { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("win_no")]
 | 
				
			||||||
 | 
					        public int WinNo { get; set; } = 0;
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///  
 | 
				
			||||||
 | 
					        /// 默认值: 0
 | 
				
			||||||
 | 
					        ///</summary>
 | 
				
			||||||
 | 
					        [Column("state")]
 | 
				
			||||||
 | 
					        public int state { get; set; } = 0;
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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; }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 菜单路径 
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        public string PremissionPath { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<Premission> Items { get; set; } = Enumerable.Empty<Premission>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public List<Premission> getAdminPremission()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var list = new List<Premission>();
 | 
				
			||||||
 | 
					            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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<Premission> permissionList {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Column(IsColumn = false)]
 | 
				
			||||||
 | 
					        public IEnumerable<int> permissionIds
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return !String.IsNullOrEmpty(permissions) ? permissions.Split(",").Select(s => Convert.ToInt32(s)): Enumerable.Empty<int>();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            set
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (value == null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    permissions = "";
 | 
				
			||||||
 | 
					                } else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    permissions = string.Join(",", value);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<ChannelStock> 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<ChannelStock> Grid { get; set; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<T>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public DrugInfo Drug { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public T data { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public List<ChannelStock> 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<ChannelStock> Grid { get; set; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<int> ColNoLst { get; set; } = new List<int>();
 | 
				
			||||||
 | 
					        // 当前操作开药盒的库位号
 | 
				
			||||||
 | 
					        public int OpenBoxColNo { get; set; } = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private readonly PortConfig _portConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public PortUtil(IOptions<PortConfig> 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<byte[]> 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<byte[]> 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<bool> 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<byte[]> 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<bool> 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<byte[]> 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<byte[]> 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<int> 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<byte[]> 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<byte[]> 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<byte[]> 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);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 开指定库位的药盒
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="ColNo"></param>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public async Task<bool> 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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 打开药盒
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="ColNo"></param>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        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<byte[]> 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<byte[]> 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<byte[]> 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<byte[]> 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<int[]> 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<byte[]> 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<int[]> 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<int> 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<int> 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<int[]> 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<ChannelStock> 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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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>("#app");
 | 
				
			||||||
 | 
					        appBuilder.Services.AddRadzenComponents();
 | 
				
			||||||
 | 
					        // 指纹机工具类
 | 
				
			||||||
 | 
					        appBuilder.Services.AddSingleton<FingerprintUtil>();
 | 
				
			||||||
 | 
					        // 串口工具类
 | 
				
			||||||
 | 
					        appBuilder.Services.AddSingleton<PortUtil>();
 | 
				
			||||||
 | 
					        // 登录用户全局存放
 | 
				
			||||||
 | 
					        appBuilder.Services.AddSingleton<GlobalStateService>();
 | 
				
			||||||
 | 
					        // 框架自带通知服务注入
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<NotificationService>(); 
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<TooltipService>();
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<DialogService>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 注入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<FingerPojo>(config.GetSection("finger"));
 | 
				
			||||||
 | 
					        appBuilder.Services.Configure<SettingConfig>(config.GetSection("setting"));
 | 
				
			||||||
 | 
					        appBuilder.Services.Configure<PortConfig>(config.GetSection("port"));
 | 
				
			||||||
 | 
					        appBuilder.Services.Configure<DrawerConfig>(config.GetSection("drawer"));
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // i18n
 | 
				
			||||||
 | 
					        //appBuilder.Services.AddI18nText();
 | 
				
			||||||
 | 
					        // 数据库
 | 
				
			||||||
 | 
					        appBuilder.Services.AddLinqToDBContext<AppDataConnection>((provider, options) =>
 | 
				
			||||||
 | 
					                options.UseMySql(config.GetValue<String>("connectionStrings"))
 | 
				
			||||||
 | 
					                .UseDefaultLogging(provider));
 | 
				
			||||||
 | 
					        // dao层数据库操作
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<IUserDao, UserDao>();
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<IRoleDao, RoleDao>();
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<IChannelListDao, ChannelListDao>();
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<IOrderInfoDao, OrderInfoDao>();
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<IDrugInfoDao, DrugInfoDao>();
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<IMachineRecordDao, MachineRecordDao>();
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<IInOutInvoiceDao, InOutInvoiceDao>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //自选取药
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<ISelfTakeDao, SelfTakeDao>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //药品批次
 | 
				
			||||||
 | 
					        appBuilder.Services.AddScoped<IDrugManuNoDao, DrugManuNoDao>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					@inherits LayoutComponentBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div style="width:100vw;height:100vh">
 | 
				
			||||||
 | 
					    @Body
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<RadzenNotification />
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,154 @@
 | 
				
			||||||
 | 
					@namespace MasaBlazorApp3
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Pojo.Config
 | 
				
			||||||
 | 
					@using MasaBlazorApp3.Util
 | 
				
			||||||
 | 
					@using log4net
 | 
				
			||||||
 | 
					@inherits LayoutComponentBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    .my-tab-menu{
 | 
				
			||||||
 | 
					    padding: 10px 20px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .my-tab-menu:hover{
 | 
				
			||||||
 | 
					    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.7); /* 阴影效果 */
 | 
				
			||||||
 | 
					    text-decoration: none !important;
 | 
				
			||||||
 | 
					    background: #255dd6;
 | 
				
			||||||
 | 
					    border-radius: 20px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    a.active {
 | 
				
			||||||
 | 
					    background: #255dd4;
 | 
				
			||||||
 | 
					    border-radius: 20px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RadzenLayout>
 | 
				
			||||||
 | 
					    <RadzenHeader Style="height: 75px;">
 | 
				
			||||||
 | 
					        <RadzenRow JustifyContent="JustifyContent.Start" AlignItems="AlignItems.Center" Style="height: 100%;">
 | 
				
			||||||
 | 
					            <RadzenColumn Size="2">
 | 
				
			||||||
 | 
					                <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                    <RadzenIcon Icon="chevron_left" Style="font-size:3rem;cursor: pointer;padding: 0 10px;" @onclick="@(() => { backHome(); })" />
 | 
				
			||||||
 | 
					                </RadzenStack>
 | 
				
			||||||
 | 
					            </RadzenColumn>
 | 
				
			||||||
 | 
					            <RadzenColumn Size="8" Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.End">
 | 
				
			||||||
 | 
					                <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" AlignItems="AlignItems.Center">
 | 
				
			||||||
 | 
					                    @foreach (Premission p in children)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        if (childrenIds.Any(id => id == p.Id))
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            <RadzenLink Match="NavLinkMatch.All" class="my-tab-menu" Path="@p.PremissionPath">@p.PremissionName</RadzenLink>
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </RadzenStack>
 | 
				
			||||||
 | 
					            </RadzenColumn>
 | 
				
			||||||
 | 
					            <RadzenColumn Size="2">
 | 
				
			||||||
 | 
					                <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center">
 | 
				
			||||||
 | 
					                    @* <RadzenText TextAlign="TextAlign.Center" class="rz-color-white">退出</RadzenText> *@
 | 
				
			||||||
 | 
					                    <RadzenIcon Icon="exit_to_app" Style="font-size:2rem;cursor: pointer;" class="rz-ripple" IconColor="white" @onclick="@(() => { logout(); })" />
 | 
				
			||||||
 | 
					                </RadzenStack>
 | 
				
			||||||
 | 
					            </RadzenColumn>
 | 
				
			||||||
 | 
					        </RadzenRow>
 | 
				
			||||||
 | 
					    </RadzenHeader>
 | 
				
			||||||
 | 
					    <RadzenBody>
 | 
				
			||||||
 | 
					        <div class="container-fluid rz-p-1">
 | 
				
			||||||
 | 
					            <RadzenCard>
 | 
				
			||||||
 | 
					                @Body
 | 
				
			||||||
 | 
					            </RadzenCard>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </RadzenBody>
 | 
				
			||||||
 | 
					    <RadzenNotification />
 | 
				
			||||||
 | 
					    <RadzenComponents />
 | 
				
			||||||
 | 
					</RadzenLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    @inject GlobalStateService globalStateService;
 | 
				
			||||||
 | 
					    @inject NavigationManager na;
 | 
				
			||||||
 | 
					    int selectedIndex = 0;
 | 
				
			||||||
 | 
					    Pojo.User Operator;
 | 
				
			||||||
 | 
					    List<int> childrenIds;
 | 
				
			||||||
 | 
					    List<Premission> children;
 | 
				
			||||||
 | 
					    @inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> 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<object>();
 | 
				
			||||||
 | 
					            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
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 创建结构体用于返回捕获时间
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        [StructLayout(LayoutKind.Sequential)]
 | 
				
			||||||
 | 
					        struct LASTINPUTINFO
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// 设置结构体块容量
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            [MarshalAs(UnmanagedType.U4)]
 | 
				
			||||||
 | 
					            public int cbSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// 抓获的时间
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            [MarshalAs(UnmanagedType.U4)]
 | 
				
			||||||
 | 
					            public uint dwTime;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [DllImport("user32.dll")]
 | 
				
			||||||
 | 
					        private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 获取键盘和鼠标没有操作的时间
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns>用户上次使用系统到现在的时间间隔,单位为秒</returns>
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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<T>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int _delay { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public T? _data { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task taskAsyncLoop(int delay, T data, Action<PromiseUtil<T>, 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;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///     win10 虚拟键盘路径
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private const string Win10TabTipPath = @"C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///     win7 虚拟键盘路径
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private const string Win7OskPath = @"C:\WINDOWS\system32\osk.exe";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///     虚拟键盘 窗口名称
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 判断键盘是否连接
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///     打开虚拟键盘,目前支持win7 64位,win10 64位,exe编译为x86。
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 关闭虚拟键盘
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        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);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					using FluentValidation;
 | 
				
			||||||
 | 
					using MasaBlazorApp3.Pojo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MasaBlazorApp3.Validator
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class LoginModelValidator : AbstractValidator<User>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public LoginModelValidator()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            RuleFor(u => u.Username).NotEmpty().WithMessage("用户名不能为空");
 | 
				
			||||||
 | 
					            RuleFor(u => u.Password).NotEmpty();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var result = await ValidateAsync(ValidationContext<User>.CreateWithOptions((User)model, x => x.IncludeProperties(propertyName)));
 | 
				
			||||||
 | 
					            if (result.IsValid)
 | 
				
			||||||
 | 
					                return Array.Empty<string>();
 | 
				
			||||||
 | 
					            return result.Errors.Select(e => e.ErrorMessage);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					@ -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": []
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 264 KiB  | 
| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "login": "LOGIN",
 | 
				
			||||||
 | 
					  "exit": "EXIT"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "login": "登录",
 | 
				
			||||||
 | 
					  "exit": "退出"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue