添加项目文件。

This commit is contained in:
马巧 2025-10-11 17:22:03 +08:00
parent 7eb4819567
commit 336ddb3f6f
178 changed files with 43713 additions and 0 deletions

31
MasaBlazorApp3.sln Normal file
View File

@ -0,0 +1,31 @@

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
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
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}.Debug|x64.ActiveCfg = Debug|x64
{B589889C-FAEB-4394-A21D-DDCADF39382D}.Debug|x64.Build.0 = Debug|x64
{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
{B589889C-FAEB-4394-A21D-DDCADF39382D}.Release|x64.ActiveCfg = Release|x64
{B589889C-FAEB-4394-A21D-DDCADF39382D}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {304B4C57-445A-464F-829B-444D21AFE355}
EndGlobalSection
EndGlobal

15
MasaBlazorApp3/App.razor Normal file
View File

@ -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">抱歉,找不到此页面。</p>
</LayoutView>
</NotFound>
</Router>

View File

@ -0,0 +1,41 @@
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>();
public ITable<SettingManu> SettingManu => this.GetTable<SettingManu>();
public ITable<Plan> Plan => this.GetTable<Plan>();
public ITable<PlanDetails> PlanDetails => this.GetTable<PlanDetails>();
public ITable<AccountBookG2> AccountBookG2 => this.GetTable<AccountBookG2>();
public ITable<HkcChangeShifts> HkcChangeShifts => this.GetTable<HkcChangeShifts>();
public ITable<HkcChangeShiftsDetail> HkcChangeShiftsDetail => this.GetTable<HkcChangeShiftsDetail>();
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MasaBlazorApp3.DataAccess
{
public class ChannelStockWidthDrawerInfo<ChannelStock>
{
//抽屉信息(抽屉号,抽屉类型)
public List<Dictionary<int,int>> DrawerInfo { get; set; }
public List<ChannelStock> ChannelStocks { get; set; } = new List<ChannelStock>();
}
}

View File

@ -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<T>
{
public int[] DrawerArray { get; set; }
public List<T> ChannelStocks { get; set; } = new List<T>();
}
}

View File

@ -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 CheckInfo<T>
{
public string StrInfo { get; set; }
public List<T> TEntity { get; set; } = new List<T>();
}
}

View File

@ -0,0 +1,104 @@
using System;
using MasaBlazorApp3.Pojo;
using MasaBlazorApp3.Pojo.Vo;
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,BoxModel boxNum,List<ChannelList> channelLists);
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);
//抽屉获取库存数据--药品绑定
Task<ChannelStockWithDrawerCount<ChannelStock>> GetChannelStockByBiaoDing(int DrawerNo, int Quantity=0);
//手术室药盒获取绑定数据
Task<PageMultiData<ChannelList, Plan>> GetAllChannelListWithPlan(int? take, int? skip);
/// <summary>
/// 手术室药盒绑定套餐
/// </summary>
/// <returns></returns>
Task<bool> BindBox(ChannelList list, Plan plan);
/// <summary>
/// 手术室药盒绑定套餐
/// </summary>
/// <returns></returns>
Task<bool> BindBox(ChannelList channelList);
/// <summary>
/// 手术室药盒解绑套餐
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
Task<bool> UnBindBox(ChannelList list);
//获取手术室药盒中所有要补药的数据
Task<PageData<ChannelList>> GetAllBoxAddDrug(int? take, int? skip);
//手术室药盒补药获取毒麻柜中的药品信息
Task<List<BoxTakeVo>> getTakeInfoByBox(ChannelList cl);
//手术室药盒补药完成
Task<bool> BoxTakeFinish(List<BoxTakeVo> datas, ChannelList boxChannelList);
//手术室药盒入库
Task<PageData<ChannelList>> GetBoxWaitInfo(int? take, int? skip);
// 药盒入库弹窗页面获取要入库的药品明细信息
Task<List<ChannelStock>> GetBoxAddToBox(ChannelList cl);
//手术室药盒入库获取待入库明细
Task<List<BoxTakeVo>> getBoxWaitByBox(ChannelList cl, int? take, int? skip);
// 手术室药盒待入库明细入库完成
Task<bool> BoxAddBoxFinish(ChannelList boxChannelList);
//手术室药盒获取药盒药品及库存信息
Task<PageData<PlanDetails>> GetBoxDrugInfo(string DrawerNo, int? take, int? skip);
//药盒移库时获取选中药盒号的药品信息
Task<PageData<ChannelStock>> GetChannelStockByDrug(ChannelStock cs, string drawerNo,int? take, int? skip);
/// <summary>
/// 药盒交换药品获取所有除本药盒外的所有药盒号
/// </summary>
/// <param name="machineId"></param>
/// <returns></returns>
Task<string[]> GetDrawerNum(ChannelStock channelStock);
/// <summary>
/// 药盒移除药品,获取所有除本药盒外的所有包含该药品的药盒号
/// </summary>
/// <param name="machineId"></param>
/// <returns></returns>
Task<string[]> GetDrawerNumForRemove(ChannelStock channelStock);
//手术室药盒交换药品完成
Task<bool> BoxReplaceFinish(ChannelStock stock, List<ChannelStock> Stocks);
//手术室药盒移出药品完成
Task<bool> BoxRemoveFinish(ChannelStock stock, string SelectedDrawerNo, int removeQuantity);
Task<List<ChannelList>> GetAllBox();
//根据药盒查询药品信息
Task<List<ChannelStock>> GetChannelStockByBox(int BoxNum);
//根据套餐下无库存的药箱
Task<List<ChannelStock>> GetChannelStockByPlan(string plan);
//手术室药盒获取绑定数据
Task<List<ChannelList>> GetAllChannelList();
//抽屉取药向药盒加药校验药盒中是否存在该药
Task<CheckInfo<ChannelList>> CheckBoxDrugInfo(BoxModel BoxNum,List<ChannelStock> channelStockList);
//药箱中的药移入到抽屉
Task<bool> RemoveDrugToDrawerFinish(string SelectedDrawerNo, ChannelStock channelStock, int quantity);
}
}

View File

@ -0,0 +1,36 @@
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>> GetAllDrugAndStockByBox(BoxModel boxModel);
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);
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,16 @@
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 IHkcChangeShiftsDao
{
//查询交接班记录
public Task<PageData<HkcChangeShifts>> GetChangeShiftRecordAsync(DateTime start, DateTime end, int? take, int? skip);
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -0,0 +1,53 @@
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>> GetAllOrderInfoForImport(string name, string OrderrNo, DateTime OrderDate, BoxModel boxModel, 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);
//获取药盒中的用药信息
public Task<PageData<OrderInfo>> GetAllOrderInfoByBox(int box,string OrderrNo, DateTime OrderDate, int? take, int? skip);
//获取待处理处方中的麻醉师
public Task<PageData<OrderInfo>> GetAllOrderInfo(string Name, string BoxNum, string PatientName,string OrderrNo, DateTime? OrderDate, int? take, int? skip);
public Task<PageData<ChannelStock>> GetAllOrderInfoDrugByBox(BoxModel boxNum, string roomName, DateTime? OrderDate);
//获取麻醉师信息
public Task<List<Anaesthetist>> GetAnaesthetistName();
//获取麻醉师单对应的手术间号
public Task<List<BoxModel>> GetOperationNum(int boxColor);
//获取麻醉师单对应的手术间号(查询全部手术间已绑套餐的手术间)
public Task<List<BoxModel>> GetAllBindOperationNum();
//获取所有药盒号
public Task<List<ChannelStock>> GetDrawerNum(string machineId);
/// 获取指定药盒号
public Task<List<BoxModel>> GetDrawerNumByOperationNum(string machineId, List<int> operationNum);
//核对处方
public Task<bool> CheckOrderInfo(IList<OrderInfo> selectedOrderInfos, BoxModel boxModel);
//查询药品对应的库位 drawerType=1药品库位其他则是回收库位
public Task<List<ChannelStock>> GetStockByDRrug(string drugId, string manuNo, int drawerType);
//核对处方通过库位下的药品
public Task<bool> CheckOrderInfoByChannelStock(IList<ChannelStock> csList, BoxModel boxModel);
}
}

View File

@ -0,0 +1,71 @@
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 IPlanDao
{
/// <summary>
/// 获取所有套餐数据
/// </summary>
/// <returns></returns>
Task<PageMultiData<Plan,DrugInfo>> GetAllPlanInfo();
/// <summary>
/// 根据套餐ID获取套餐数据
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
Task<Plan> GetPlanById(int Id);
/// <summary>
/// 新增套餐
/// </summary>
/// <param name="plan"></param>
/// <returns></returns>
Task<bool> InsertPlanInfo(Plan plan);
/// <summary>
/// 更新套餐
/// </summary>
/// <param name="plan"></param>
/// <returns></returns>
Task<bool> UpdatePlanInfo(Plan plan);
/// <summary>
/// 删除套餐
/// </summary>
/// <param name="planId"></param>
/// <returns></returns>
Task<bool> DeletePlanInfo(int planID);
/// <summary>
/// 向套餐添加药品
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
Task<bool> AddPlanDetail(PlanDetails details);
/// <summary>
/// 修改套餐中的药品
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
Task<bool> UpdatePlanDetail(PlanDetails details);
//查询要删除的套餐下是否有绑定,且绑定有库存
Task<bool> CheckPlanBind(int planId);
//查询要删除的药品是否有绑定且库存大于0
Task<bool> CheckPlanDetailBind(PlanDetails planDetail);
/// <summary>
/// 删除套餐中的药品
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
Task<bool> DeletePlanDetail(PlanDetails planID);
/// <summary>
/// 根据套餐明细获取套餐
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
bool CheckDrugById(PlanDetails details);
}
}

View File

@ -0,0 +1,23 @@
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 IReportDataDao
{
//获取库存导出数据
Task<PageData<ReportStockDateInfo>> GetStockExportData(string drugName);
//专用账册导出数据
Task<PageData<ReportAccountDateInfo>> GetAccountExportData(DateTime? startDate, DateTime? endDate, string drugName);
//手术室患者麻醉药品使用登记本主表数据
Task<List<ReportUsageParentDateInfo>> GetOrderInfoParentData(DateTime? startDate);
//手术室患者麻醉药品使用登记本
Task<List<ReportUsageDateInfo>> GetOrderInfoData(DateTime? startDate);
//请领登记表导出
Task<PageData<ReportApplyInfo>> GetApplyInfoDate(DateTime searchDate);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,14 @@
using MasaBlazorApp3.Pojo;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MasaBlazorApp3.DataAccess.Dao
{
interface ISettingManuDao
{
public Task<List<SettingManu>> GetMenuItemsAsync();
}
}

View File

@ -0,0 +1,29 @@
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);
bool UpdateUserPassword(User user);
//查询当前值班信息
HkcChangeShifts GetOnDuty();
//保存交接班信息
Task<bool> UpdateChangeShift(HkcChangeShifts changeShift, HkcChangeShifts changeShiftNew);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,174 @@
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();
List<DrugInfo> drugList = 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();
if(drugList!=null&&drugList.Count>0)
{
for (int i = 0; i < drugList.Count; i++)
{
List<ChannelStock> channelStocks = _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.boxMachineId) && cs.DrugId == drugList[i].DrugId).OrderBy(cs=> new{ cs.DrawerNo, cs.ColNo}).ToList();
var nomalBoxStockList= channelStocks.Where(cs => cs.DrawerNo <= 30).GroupBy(cs =>new { cs.ManuNo, cs.EffDate }).Select(g => new { manuNo=g.Key.ManuNo,effdate=g.Key.EffDate,Quantity=g.Sum(k=>k.Quantity)}).ToList();
foreach (var item in nomalBoxStockList)
{
ChannelStock nomalBox = new ChannelStock() { DrugId = drugList[i].DrugId,ManuNo=item.manuNo,Quantity=item.Quantity,EffDate=item.effdate,MachineId= "DM5" };
drugList[i].Stocks.Add(nomalBox);
}
drugList[i].Stocks.AddRange(channelStocks.Where(cs=>cs.DrawerNo>30));
}
}
return drugList;
//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<List<DrugInfo>> GetAllDrugAndStockByBox(BoxModel boxModel)
{
var query = _connection.DrugInfo.AsQueryable();
return await query
.LoadWith(di => di.Stocks.Where(cs => cs.Quantity > 0 && cs.MachineId == _setting.boxMachineId&&cs.DrawerNo==boxModel.BoxName&&cs.ColNo==boxModel.BoxNo))
.InnerJoin(
_connection.ChannelStock.Where(cl => cl.MachineId == _setting.boxMachineId && cl.DrawerNo==boxModel.BoxName&&cl.ColNo==boxModel.BoxNo).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.PackH,drugInfo.PackH)
.Set(di => di.Manufactory, drugInfo.Manufactory);
return statement.Update() > 0;
}
catch (Exception ex)
{
logger.Error($"修改药品{drugInfo.DrugId}失败,错误:" + ex.Message);
return false;
}
}
}
}

View File

@ -0,0 +1,56 @@
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)
{
if (!string.IsNullOrEmpty(id))
{
int manuNo= _connection.DrugManuNo.Where(dm => dm.Id == id).Count();
if (manuNo > 0)
{
return _connection.DrugManuNo.Where(dm => dm.Id == id).Delete() > 0;
}
else return true;
}
else
{
return true;
}
}
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;
}
}
}

View File

@ -0,0 +1,51 @@
using LinqToDB;
using log4net;
using MasaBlazorApp3.DataAccess.Dao;
using MasaBlazorApp3.Pojo;
using MasaBlazorApp3.Pojo.Config;
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 HkcChangeShiftsDao: IHkcChangeShiftsDao
{
private readonly AppDataConnection _connection;
private readonly SettingConfig _setting;
private readonly ILog logger = LogManager.GetLogger(typeof(HkcChangeShifts));
private readonly PortUtil _portUtil;
public HkcChangeShiftsDao(AppDataConnection connection, IOptions<SettingConfig> setting, PortUtil portUtil)
{
_connection = connection;
_setting = setting.Value;
_portUtil = portUtil;
}
public async Task<PageData<HkcChangeShifts>> GetChangeShiftRecordAsync(DateTime start, DateTime end, int? take, int? skip)
{
var query = _connection.HkcChangeShifts.AsQueryable().Where(it => it.MachineId.Equals(_setting.machineId));
if (start != null && start != DateTime.MinValue)
{
query = query.Where(mr => mr.optDate > start);
}
if (end != null && end != DateTime.MinValue)
{
query = query.Where(mr => mr.optDate < end);
}
int pagedData = await query.CountAsync();
List<HkcChangeShifts> Records = await query
.OrderByDescending(mr => mr.optDate)
.Skip((int)skip)
.Take((int)take)
.ToListAsync();
return new PageData<HkcChangeShifts>() { Desserts = Records, TotalDesserts = pagedData };
}
}
}

View File

@ -0,0 +1,621 @@
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.ChannelStock.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_stock 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 => Convert.ToDateTime(ioi.InvoiceDate).Date.Equals(invoiceDate.Date));
//query3 = query3.Where(ioi => ioi.InvoiceNo.Contains(invoiceNo));
}
if (!String.IsNullOrEmpty(_setting.inPharmacyId))
{
if (type == 1)
{
query = query.Where(ioi => ioi.InPharmacyId.Equals(_setting.inPharmacyId));
//query = query.Where(ioi => ioi.OutPharmacyId.Equals(_setting.inPharmacyId));
//query3 = query3.Where(ioi => ioi.OutPharmacyId.Equals(_setting.storage));
}
// 调拨出库
else if (type == 2)
{
query = query.Where(ioi => ioi.InPharmacyId.Equals(_setting.inPharmacyId));
//query3 = query3.Where(ioi => ioi.OutPharmacyId.Equals(_setting.storage));
}
}
// 调拨入库
if (type == 1)
{
query = query.Where(ioi => (ioi.Type == 2 && 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 query
.OrderByDescending(ioi => ioi.CreateTime)
.Skip((int)skip)
.Take((int)take)
.ToListAsync();
int pagedData = await query.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) && manuNo != "X")
{
query = query.Where(cs => cs.ManuNo.Equals(manuNo));
}
}
else
{
if (!String.IsNullOrEmpty(manuNo) && manuNo != "X")
{
query = query.Where(cs => cs.ManuNo.Equals(manuNo) || String.IsNullOrEmpty(cs.ManuNo) || cs.Quantity == 0);
}
}
return await query.LoadWith(cl => cl.drugManuNo)
.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).LoadWith(di => di.Manus).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);
if (Drug != null && stockList != null && stockList.Count > 0)
{
stockList.ForEach(sl => sl.Drug = Drug);
}
if (stockList != null && stockList.Count > 0)
{
if (Drug != null && Drug.SmallUnit != detail.Units)
{
Quantity = detail.quantity * stockList[0].Drug.ConvertRatio;
}
}
// 当前药品的库存总量
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);
if (Drug != null && stockList != null && stockList.Count > 0)
{
stockList.ForEach(sl => sl.Drug = Drug);
}
// 当前药品的库存总量
var total = stockList.Aggregate(0, (current, next) => current + next.Quantity);
// 当前detail加药数量
var Quantity = detail.quantity;
if(stockList!=null&&stockList.Count>0)
{
if (stockList[0].Drug != null && stockList[0].Drug.SmallUnit!=detail.Units)
{
Quantity = detail.quantity * stockList[0].Drug.ConvertRatio;
}
}
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];
if (!DateTime.TryParse(ChannelStock.EffDate, out DateTime dEffDate))
{
//效期转换出错
if (ChannelStock.EffDate != null)
{
string[] idate = ChannelStock.EffDate.Split('/');
foreach (string iS in idate)
{
if (!string.IsNullOrEmpty(iS.Trim()))
{
switch (iS.Trim().Length)
{
case 4:
ChannelStock.EffDate = iS.Trim();
break;
case 2:
ChannelStock.EffDate += "-" + iS.Trim();
break;
case 1:
ChannelStock.EffDate += "-0" + iS.Trim();
break;
}
}
}
}
}
else
{
ChannelStock.EffDate = dEffDate.ToString("yyyy-MM-dd");
}
// 出库记录
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, ChannelStock.drugManuNo.ManuNo);
ChannelStock.Dmnguid = drugManuNo.Id;
ChannelStock.ManuNo = drugManuNo.ManuNo;
ChannelStock.EffDate = drugManuNo.EffDate?.ToString("yyyy-MM-dd");
q = q.Set(cs => cs.Dmnguid, ChannelStock.Dmnguid)
.Set(cs => cs.ManuNo, ChannelStock.ManuNo)
.Set(cs => cs.EffDate, ChannelStock.EffDate);
}
int r = q.Update();
if (!DateTime.TryParse(ChannelStock.EffDate, out DateTime dEffDate))
{
//效期转换出错
if (ChannelStock.EffDate != null)
{
string[] idate = ChannelStock.EffDate.Split('/');
foreach (string iS in idate)
{
if (!string.IsNullOrEmpty(iS.Trim()))
{
switch (iS.Trim().Length)
{
case 4:
ChannelStock.EffDate = iS.Trim();
break;
case 2:
ChannelStock.EffDate += "-" + iS.Trim();
break;
case 1:
ChannelStock.EffDate += "-0" + iS.Trim();
break;
}
}
}
}
}
else
{
ChannelStock.EffDate = dEffDate.ToString("yyyy-MM-dd");
}
// 入库记录
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> returnChannelStockList = _connection.ChannelStock.Where(cs => cs.MachineId == _setting.machineId && cs.DrawerType == 2 && cs.DrugId == ChannelStock.DrugId && cs.Quantity > 0).OrderBy(cs => cs.Quantity).ToList();
//if (returnChannelStockList != null && returnChannelStockList.Count > 0 && returnChannelStockList.Sum(rcs => rcs.Quantity) <= ChannelStock.AddQuantity)
//{
// //空瓶数小于等于入库数量,直接清空所有回收箱中药品空瓶数
// returnChannelStockList.ForEach(rcs => rcs.Quantity = 0);
// _connection.Update(returnChannelStockList);
//}
//else if(returnChannelStockList != null && returnChannelStockList.Count > 0)
//{
// for (int rt = 0; rt < ChannelStock.AddQuantity; rt++)
// {
// int AddQuan = ChannelStock.AddQuantity;
// int StockQuan = returnChannelStockList[rt].Quantity;
// returnChannelStockList[rt].Quantity = (StockQuan - AddQuan) <= 0 ? 0 : (StockQuan - AddQuan);
// ChannelStock.AddQuantity = AddQuan - StockQuan;
// }
// _connection.Update(returnChannelStockList);
//}
// 获取更新完库存之后的药品库存
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;
}
}
}
}

View File

@ -0,0 +1,489 @@
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 System.Collections.Generic;
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;
private GlobalStateService _globalStateService;
//public UserDao(MyContext context)
//{
// Context = context;
//}
public MachineRecordDao(AppDataConnection connection, IOptions<SettingConfig> setting, PortUtil portUtil, GlobalStateService globalStateService)
{
_connection = connection;
_setting = setting.Value;
_portUtil = portUtil;
_globalStateService = globalStateService;
}
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)&&it.InvoiceId.StartsWith("DRAWER_"));
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.AddDays(1));
}
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 = from mr in _connection.MachineRecord select mr ;
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.AddDays(1));
}
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);
}
query = query.OrderByDescending(mr => mr.OperationTime);
query =from mr in query
from dr in _connection.DrugInfo.Where(d => d.DrugId == mr.DrugId)
from us in _connection.User.Where(u => u.Id == mr.Operator)
select MachineRecord.Build(mr, dr, us);
int pagedData = await query.CountAsync();
List<MachineRecord> MachineRecords = await query
//.OrderByDescending(mr => mr.OperationTime)
.Skip((int)skip)
.Take((int)take)
.ToListAsync();
//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.AddDays(1));
//}
//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);
}
// 获取更新完库存之后的药品库存
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(record.DrugId))
.ToListAsync();
//账册添加入库记录
int accountID = _connection.InsertWithInt32Identity(new AccountBook()
{
MachineId = _setting.machineId,
DrugId = record.DrugId,
ManuNo = record.ManuNo,
EffDate = !String.IsNullOrEmpty(record.EffDate) ? DateTime.ParseExact(record.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
OperationTime = DateTime.Now,
Type = 31,
AddQuantity = record.ReturnQuantity,
Operator = _globalStateService.Operator.Id,
Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
ManuStock = list.Where(it => it.ManuNo == record.ManuNo).Sum(it => it.Quantity),
TotalStock = list.Sum(it => it.Quantity),
InvoiceId = data.data.First().InvoiceId,
});
}
// 更新 取药记录 设置还药数量、状态
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);
//更新药盒库存(原库存减已还药数)
if(record.BoxDrawer>0)
{
//查询药盒库位中对应的药品信息
ChannelStock csBox = _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.boxMachineId) && cs.DrugId == record.DrugId && cs.ManuNo == record.ManuNo && cs.DrawerNo == record.BoxDrawer && cs.ColNo == record.BoxColNo).FirstOrDefault();
if(csBox!=null)
{
csBox.Quantity = csBox.Quantity - sumQuantity;
int iUpdateBox= _connection.Update(csBox);
if(iUpdateBox<=0)
{
logger.Info("更新药品库存失败");
}
}
else
{
logger.Info($"未查询到药品{record.DrugId}批次{record.ManuNo}在库位{record.BoxDrawer}-{record.BoxColNo}中信息");
}
}
}
}
_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 = 32,
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
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,461 @@
using Google.Protobuf;
using LinqToDB;
using log4net;
using MasaBlazorApp3.DataAccess.Dao;
using MasaBlazorApp3.Pojo;
using MasaBlazorApp3.Pojo.Config;
using MasaBlazorApp3.Pojo.Vo;
using Microsoft.Extensions.Options;
using Org.BouncyCastle.Crypto;
using Radzen;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using ZstdSharp.Unsafe;
namespace MasaBlazorApp3.DataAccess.Impl
{
public class PlanDao : IPlanDao
{
private AppDataConnection _connection;
private readonly SettingConfig _setting;
private readonly ILog logger = LogManager.GetLogger(typeof(DrugInfoDao));
private GlobalStateService _globalStateService;
private NotificationService _message;
public PlanDao(AppDataConnection connection, IOptions<SettingConfig> setting, GlobalStateService globalStateService,NotificationService message)
{
_connection = connection;
_setting = setting.Value;
_globalStateService = globalStateService;
_message = message;
}
/// <summary>
/// 获取所有套餐数据
/// </summary>
/// <returns></returns>
public async Task<PageMultiData<Plan, DrugInfo>> GetAllPlanInfo()
{
var query = _connection.Plan.AsQueryable();
List<Plan> list = await query.Where(p => p.UseState == 1 && p.MachineId==_setting.boxMachineId)
.LoadWith(p => p._PlanDetails.Where(pd => pd.UseState == 1))
//.ThenLoad(p=>p._DrugInfo)
.OrderBy(r => r.Id)
.ToListAsync();
if (list != null && list.Count > 0)
{
for (int i = 0; i < list.Count(); i++)
{
for (int j = 0; j < list[i]._PlanDetails.Count(); j++)
{
list[i]._PlanDetails[j]._DrugInfo =
_connection.DrugInfo.AsQueryable().Where(di => di.DrugId == list[i]._PlanDetails[j].DrugId).First();
}
}
}
var other = _connection.DrugInfo.AsQueryable();
List<DrugInfo> drugInfos = await other
.LoadWith(di => di.Manus)
.OrderBy((di) => di.DrugId)
.ToListAsync();
int pagedData = await query.CountAsync();
return new PageMultiData<Plan, DrugInfo>()
{
TotalDesserts = pagedData,
Desserts = list,
Other = drugInfos
};
}
/// <summary>
/// 根据套餐ID获取套餐数据
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public async Task<Plan> GetPlanById(int Id)
{
var query = _connection.Plan.AsQueryable().Where(p => p.Id == Id && p.UseState == 1 && p.MachineId == _setting.boxMachineId);
List<Plan> list = await query
.LoadWith(p => p._PlanDetails)
//.ThenLoad(p=>p._DrugInfo)
.OrderBy(r => r.Id)
.ToListAsync();
if (list != null && list.Count > 0)
{
for (int i = 0; i < list.Count(); i++)
{
for (int j = 0; j < list[i]._PlanDetails.Count(); j++)
{
list[i]._PlanDetails[j]._DrugInfo =
_connection.DrugInfo.AsQueryable().Where(di => di.DrugId == list[i]._PlanDetails[j].DrugId).First();
}
}
}
return list[0];
}
/// <summary>
/// 新增套餐
/// </summary>
/// <param name="plan"></param>
/// <returns></returns>
public async Task<bool> InsertPlanInfo(Plan plan)
{
try
{
plan.AddTime = DateTime.Now;
plan.OperatorUser = _globalStateService.Operator.Id;
plan.ReviewerUser = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id;
plan.UseState = 1;
plan.MachineId = _setting.boxMachineId;
if(_connection.InsertWithInt32Identity(plan) > 0)
{
//保存操作记录
int mid = _connection.InsertWithInt32Identity(new MachineRecord()
{
MachineId = _setting.boxMachineId,
OperationTime = DateTime.Now,
Type = 50,
Operator = _globalStateService.Operator.Id,
Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
InvoiceId = $"新增套餐{plan.Name}",
});
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
logger.Error($"添加套餐{plan.Name}失败,错误:" + ex.Message);
return false;
}
}
/// <summary>
/// 更新套餐
/// </summary>
/// <param name="plan"></param>
/// <returns></returns>
public async Task<bool> UpdatePlanInfo(Plan plan)
{
try
{
var iResult = _connection.Plan
.Where(p => p.Id == plan.Id && p.MachineId == _setting.boxMachineId)
.Set(p => p.Name, plan.Name)
.Set(p => p.Description, plan.Description);
return iResult.Update() > 0;
}
catch (Exception ex)
{
logger.Error($"修改套餐{plan.Name}失败,错误:" + ex.Message);
return false;
}
}
//查询要删除的套餐下是否有绑定,且绑定有库存
public async Task<bool> CheckPlanBind(int planId)
{
try
{
//查询是否有绑定,没有绑定可以删除,有绑定则不允许删除
List<string> channelListsId = await _connection.ChannelList.AsQueryable().Where(cl => cl.DrugId == planId.ToString() && cl.MachineId == _setting.boxMachineId).Select(cl => cl.Id).ToListAsync();
if (channelListsId != null && channelListsId.Count > 0)
{
bool searchResult = _connection.ChannelStock.AsQueryable().Where(cs => channelListsId.Contains(cs.ListId)).Any(cs => cs.Quantity > 0);
if (searchResult)
{
return false;
}
else
{
return true;
}
}
else
{
return true;
}
}
catch (Exception ex)
{
logger.Error($"查询要删除的套餐下是否有绑定异常{ex.Message}");
return false;
}
}
/// <summary>
/// 删除套餐
/// </summary>
/// <param name="planId"></param>
/// <returns></returns>
public async Task<bool> DeletePlanInfo(int planId)
{
try
{
_connection.BeginTransaction();
//如果套餐下有绑药且库存为0的也将绑定药品信息一并删除
List<string> listIds = await _connection.ChannelList.Where(cl => cl.DrugId == planId.ToString()).Select(cl => cl.Id).ToListAsync();
int iDelResult = 1;
int iDelChannelListResult = 1;
if (listIds != null && listIds.Count > 0)
{
//删除channelStock表中的绑定药品
iDelResult = _connection.ChannelStock.Where(cs => listIds.Contains(cs.ListId)).Delete();
_connection.ChannelList.Where(cl => listIds.Contains(cl.Id)).Set(cl => cl.DrugId, "").Update();
}
bool flag = false;
logger.Error($"删除套餐{planId}");
//查询该套餐下是否有药品,如果有则一并删除
int iHasPd = _connection.PlanDetails.Where(pd => pd.PlanId == planId).Count();
int pdResult = 1;
if (iHasPd > 0)
{
pdResult = await _connection.PlanDetails.Where(pd => pd.PlanId == planId).Set(pd => pd.UseState, 0).UpdateAsync();
}
int pResult = await _connection.Plan.Where(p => p.Id == planId).Set(pd => pd.UseState, 0).UpdateAsync();
if (pdResult > 0 && pResult > 0 && iDelResult > 0 && iDelChannelListResult > 0)
{
//保存操作记录
int mid = _connection.InsertWithInt32Identity(new MachineRecord()
{
MachineId = _setting.boxMachineId,
OperationTime = DateTime.Now,
Type = 51,
Operator = _globalStateService.Operator.Id,
Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
InvoiceId = $"删除套餐{planId}",
});
flag = true;
}
if (flag)
{
_connection.CommitTransaction();
}
else
{
_connection.RollbackTransaction();
}
return flag;
}
catch (Exception ex)
{
logger.Error($"修改套餐失败,错误:" + ex.Message);
_connection.RollbackTransaction();
return false;
}
}
/// <summary>
/// 向套餐中添加药品
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
public async Task<bool> AddPlanDetail(PlanDetails details)
{
try
{
if (!string.IsNullOrEmpty(details.DrugId))
{
int id = await _connection.InsertWithInt32IdentityAsync(details);
details.Id = id;
//保存操作记录
int mid = _connection.InsertWithInt32Identity(new MachineRecord()
{
MachineId = _setting.boxMachineId,
OperationTime = DateTime.Now,
Type = 52,
Operator = _globalStateService.Operator.Id,
Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
InvoiceId = $"套餐{details.PlanId}添加药品{details.DrugId},基数{details.BaseQuantity}",
});
return id > 0;
}
else
{
return false;
}
}
catch (Exception ex)
{
logger.Error($"添加药品{details._DrugInfo.DrugName}失败,错误:" + ex.Message);
return false;
}
}
/// <summary>
/// 修改套餐中的药品
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
public async Task<bool> UpdatePlanDetail(PlanDetails details)
{
try
{
var iResult = _connection.PlanDetails
.Where(p => p.Id == details.Id)
.Set(p => p.DrugId, details._DrugInfo.DrugId)
.Set(p => p.BaseQuantity, details.BaseQuantity);
//保存操作记录
int mid = _connection.InsertWithInt32Identity(new MachineRecord()
{
MachineId = _setting.boxMachineId,
OperationTime = DateTime.Now,
Type = 53,
Operator = _globalStateService.Operator.Id,
Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
InvoiceId = $"修改套餐{details.PlanId},药品{details.DrugId}-{details._DrugInfo.DrugId},基数{details.BaseQuantity}",
});
return await iResult.UpdateAsync() > 0;
}
catch (Exception ex)
{
logger.Error($"修改药品{details._DrugInfo.DrugName}失败,错误:" + ex.Message);
return false;
}
}
//查询要删除的药品是否有绑定且库存大于0
public async Task<bool> CheckPlanDetailBind(PlanDetails planDetail)
{
try
{
bool bFlag = true;
List<string> idList = await _connection.ChannelList.AsQueryable().Where(cl => cl.DrugId == planDetail.PlanId.ToString()).Select(cl => cl.Id).ToListAsync();
if (idList != null && idList.Count > 0)
{
bFlag = !(_connection.ChannelStock.AsQueryable().Where(cs => idList.Contains(cs.ListId) && cs.DrugId == planDetail.DrugId).Any(cs => cs.Quantity > 0));
}
return bFlag;
}
catch (Exception ex)
{
logger.Error($"查询要删除的药品是否有绑定异常{ex.Message}");
return true;
}
}
/// <summary>
/// 删除套餐中的药品
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
public async Task<bool> DeletePlanDetail(PlanDetails detail)
{
try
{
_connection.BeginTransaction();
logger.Error($"删除套餐中的药品{detail._DrugInfo.DrugName}");
int iDelResult = 1;
//删除该套餐下该药品对应绑定的库位
List<string> idList = await _connection.ChannelList.AsQueryable().Where(cl => cl.DrugId == detail.PlanId.ToString()).Select(cl => cl.Id).ToListAsync();
if (idList != null && idList.Count > 0)
{
iDelResult = await _connection.ChannelStock.AsQueryable().Where(cs => idList.Contains(cs.ListId) && cs.DrugId == detail.DrugId).DeleteAsync();
}
//if (iDelResult > 0)
//{
bool bUpdateResult = _connection.PlanDetails.Where(p => p.Id == detail.Id).Set(p => p.UseState, 0).Update() > 0;
if (bUpdateResult)
{
//保存操作记录
int mid = _connection.InsertWithInt32Identity(new MachineRecord()
{
MachineId = _setting.boxMachineId,
OperationTime = DateTime.Now,
Type = 54,
Operator = _globalStateService.Operator.Id,
Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
InvoiceId = $"删除套餐{detail.PlanId},中的药品{detail._DrugInfo.DrugName}ID:{detail.DrugId}",
});
_connection.CommitTransaction();
return true;
}
else
{
_connection.RollbackTransaction();
return false;
}
//}
//else
//{
// logger.Error($"套餐中的药品{detail._DrugInfo.DrugName}无绑定");
// return false;
//}
}
catch (Exception ex)
{
logger.Error($"添加药品失败,错误:" + ex.Message);
return false;
}
}
public bool CheckDrugById(PlanDetails details)
{
if (details._DrugInfo.DrugId != null)
{
//查询该药品是否已在套餐中存在,存在则不再添加
PlanDetails pdDrug = _connection.PlanDetails.Where(p => p.PlanId == details.PlanId && p.DrugId == details._DrugInfo.DrugId && p.UseState == 1).FirstOrDefault();
if (details.Id > 0)
{
//修改原数据
if (pdDrug != null && pdDrug.Id == details.Id)
{
return true;
}
else
{
return false;
}
}
else
{
//新增数据
if (pdDrug != null)
{
return !(pdDrug.Id > 0);
}
else
{
return true;
}
}
//return !(hasCount > 0);
}
else
{
return true;
}
}
}
}

View File

@ -0,0 +1,178 @@
using LinqToDB;
using log4net;
using MasaBlazorApp3.DataAccess.Dao;
using MasaBlazorApp3.Pojo;
using MasaBlazorApp3.Pojo.Config;
using Microsoft.Extensions.Options;
using Mysqlx.Crud;
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 ReportDataDao : IReportDataDao
{
private AppDataConnection _connection;
private readonly SettingConfig _setting;
private readonly ILog logger = LogManager.GetLogger(typeof(ReportDataDao));
public ReportDataDao(AppDataConnection connection, IOptions<SettingConfig> setting)
{
_connection = connection;
_setting = setting.Value;
}
//获取库存导出数据
public async Task<PageData<ReportStockDateInfo>> GetStockExportData(string drugName)
{
try
{
List<ReportStockDateInfo> reportStockList = new List<ReportStockDateInfo>();
int pagedData = 0;
string SQL = $@"SELECT cl.drug_id AS DrugId,di.`drug_name` AS DrugName,di.drug_type AS DrugType,di.drug_spec AS DrugSpec,di.manufactory AS Manufactory,
di.pack_unit AS pack_unit,di.py_code AS PyCode,null AS Stocks,NULL AS Manus,db.baseQuantity AS BaseQuantity,CONCAT(cl.row_no,cl.col_no) as location,
cl.manu_no as ManuNo,cl.eff_date as EffDate,cl.Quantity AS Quantity,cl.manu_no,cl.eff_date FROM channel_stock cl INNER JOIN drug_info di ON di.`drug_id` = cl.`drug_id`
LEFT JOIN drug_base db ON db.drugid=di.drug_id and db.machine_id= '{_setting.machineId}'
WHERE cl.`machine_id` = '{_setting.machineId}' AND cl.`drawer_type` = 1 ";
if (!string.IsNullOrEmpty(drugName))
{
SQL += $" and (di.drug_name like '%{drugName}%'|| di.py_code like '%{drugName}%'||di.drug_id like '%{drugName}%')";
}
SQL += " ORDER BY cl.`drug_id`";
// 加载模板文件
//Report.LoadFromFile(new FileInfo(AppDomain.CurrentDomain.BaseDirectory) + "ReportTemp//" + "stock_template.grf");
var reportList = _connection.FromSql<ReportStockDateInfo>(SQL);
if (reportList != null)
{
foreach (var report in reportList)
{
reportStockList.Add(report);
}
pagedData = await reportList.CountAsync();
}
return new PageData<ReportStockDateInfo>()
{
TotalDesserts = pagedData,
Desserts = reportStockList
};
}
catch (Exception ex)
{
logger.Info($"获取库存导出数据异常:{ex.Message}");
return null;
}
}
//中部战区总医院麻醉药品、第一类精神药品进出专用账册
public async Task<PageData<ReportAccountDateInfo>> GetAccountExportData(DateTime? startDate, DateTime? endDate, string drugName)
{
List<ReportAccountDateInfo> accountList = new List<ReportAccountDateInfo>();
int pagedData = 0;
DateTime? p_startDate = startDate ?? Convert.ToDateTime("2010-1-1");
DateTime? p_endDate = endDate ?? DateTime.Now.AddDays(1);
string SQL = $@"SELECT ab.`create_time` AS `OperationTime`,ab.manu_no AS ManuNo,ab.eff_date as EffDate, ab.add_quantity AS `inQuantity`,
ab.out_quantity AS `outQuantity`,ab.manu_quantity as ManuQuantity,ab.total_quantity as StockQuantity,
u1.`user_name` AS `operatorName`, u2.`user_name` AS `reviewerName`, ab.`drug_id` AS `drugId`,di.`drug_name` AS `drugName`,di.`drug_spec` AS `drugSpec`, di.`pack_unit` AS `BigUnit`, di.`dosage` AS `dosage`,
di.`manufactory` AS `manufactory`, ab.`invoice_id` AS `invoiceId`, ab.department as department,'' as Remarks FROM
account_book ab LEFT JOIN drug_info di ON ab.`drug_id` = di.`drug_id` LEFT JOIN user_list u1 ON ab.`operator` = u1.`id`
LEFT JOIN user_list u2 ON ab.`reviewer` = u2.`id` WHERE ab.`machine_id` = '{_setting.machineId}' AND ab.type in(1,2,31) DATE_FORMAT(ab.`create_time`,'%Y-%m-%d') > '{p_startDate}'
AND DATE_FORMAT(ab.`create_time`,'%Y-%m-%d') < '{p_endDate}'";
if (!string.IsNullOrEmpty(drugName))
{
SQL += $" AND (di.drug_name like '%{drugName}%' or di.drug_id like '%{drugName}%' or di.py_code like '%{drugName}%')";
}
SQL += " ORDER BY ab.`create_time`, ab.`drug_id`";
var reportList = _connection.FromSql<ReportAccountDateInfo>(SQL);
if (reportList != null)
{
foreach (var report in reportList)
{
accountList.Add(report);
}
pagedData = await reportList.CountAsync();
}
return new PageData<ReportAccountDateInfo>()
{
TotalDesserts = pagedData,
Desserts = accountList
};
}
//手术室患者麻醉药品使用登记本(主表数据)
public async Task<List<ReportUsageParentDateInfo>> GetOrderInfoParentData(DateTime? searchDate)
{
//List<ReportUsageParentDateInfo> accountList = new List<ReportUsageParentDateInfo>();
int pagedData = 0;
string SQL = $@"SELECT od.drug_id drugId1, di.drug_Name drugName1,od.set_manu_No as manuNo1,sum(od.quantity) quantity1 ,oi.charge_Date as portDate
from order_info oi inner join order_detail od on oi.order_no=od.order_no inner join drug_info di on od.drug_id=di.drug_id
WHERE DATE_FORMAT(oi.charge_Date,'%Y-%m-%d')='{searchDate?.ToString("yyyy-MM-dd")}' and oi.dm_status=2 and oi.cancel_flag=0 and oi.his_disp_flag=0 and di.pack_h=1 group by od.drug_id,od.set_manu_No";
var reportList =await _connection.FromSql<ReportUsageParentDateInfo>(SQL).ToListAsync();
//if (reportList != null)
//{
// foreach (var report in reportList)
// {
// accountList.Add(report);
// }
// pagedData = await reportList.CountAsync();
//}
return reportList;
}
//手术室患者麻醉药品使用登记本(子数据)
public async Task<List<ReportUsageDateInfo>> GetOrderInfoData(DateTime? searchDate)
{
string SQL = $@"SELECT oi.charge_Date as portdate, od.drug_id as DrugId,1 as ShouShuJian,oi.anaesthetist_code as doctor1,oi.anaesthetist_name as doctor2,oi.patient_id as patientId,oi.p_name as PName,oi.disease as Diagnose,
CONCAT(di.drug_name,' ',di.drug_spec) as DrugName,od.set_manu_No as ManuNo,od.use_dosage as UsageDosage,'' as CanYeLiang,'' as CanYeChuZhi,'' as UseUserName,'' as CheckUserName,od.quantity as quantity
from order_info oi inner join order_detail od on oi.order_no=od.order_no inner join drug_info di on od.drug_id=di.drug_id
WHERE DATE_FORMAT(oi.charge_Date,'%Y-%m-%d')='{searchDate?.ToString("yyyy-MM-dd")}' and oi.dm_status=2 and oi.cancel_flag=0 and oi.his_disp_flag=0 and di.pack_h=1 order by oi.anaesthetist_code,oi.anaesthetist_name, od.drug_id";
var reportList =await _connection.FromSql<ReportUsageDateInfo>(SQL).ToListAsync();
return reportList;
}
//麻醉科毒麻药品请领登记表
public async Task<PageData<ReportApplyInfo>> GetApplyInfoDate(DateTime searchDate)
{
List<ReportApplyInfo> accountList = new List<ReportApplyInfo>();
int pagedData = 0;
string SQL = $@"SELECT Drawerno as BoxNum,Create_date AS applyinfo,userfirst,usersecond,drugid,doctor,manager
from applyinfo ap inner join drug_info di on ap.drugid=di.drug_id
WHERE machine_id='{_setting.boxMachineId}' and DATE_FORMAT(ap.Create_date,'%Y-%m-%d')='{searchDate.ToString("yyyy-MM-dd")}' ";
var reportList = _connection.FromSql<ReportApplyInfo>(SQL);
if (reportList != null&& reportList.Count()>0)
{
foreach (var report in reportList)
{
accountList.Add(report);
}
pagedData = await reportList.CountAsync();
}
return new PageData<ReportApplyInfo>()
{
TotalDesserts = pagedData,
Desserts = accountList
};
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -0,0 +1,37 @@
using LinqToDB;
using MasaBlazorApp3.DataAccess.Dao;
using MasaBlazorApp3.Pojo;
using MasaBlazorApp3.Pojo.Config;
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 SettingManuDao : ISettingManuDao
{
private AppDataConnection _connection;
private readonly SettingConfig _setting;
private GlobalStateService _globalStateService;
public SettingManuDao(AppDataConnection connection, IOptions<SettingConfig> setting, GlobalStateService globalStateService, PortUtil portUtil)
{
_globalStateService = globalStateService;
_connection = connection;
_setting = setting.Value;
}
public async Task<List<SettingManu>> GetMenuItemsAsync()
{
var query = _connection.SettingManu.Where(s=>s.UseStatus==1).AsQueryable();
return await query
.OrderBy((sm) => sm.Id)
.ToListAsync();
}
}
}

View File

@ -0,0 +1,198 @@
using Google.Protobuf.WellKnownTypes;
using LinqToDB;
using log4net;
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;
private readonly ILog logger = LogManager.GetLogger(typeof(OrderInfoDao));
//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;
}
//修改密码
public bool UpdateUserPassword(User user)
{
var statement = _connection.User
.Where(u => u.Id == user.Id)
.Set(u => u.Password, MD5.GetMD5Hash(user.Password).ToLower());
return statement.Update() > 0;
}
//查询当前值班信息
public HkcChangeShifts GetOnDuty()
{
try
{
return _connection.HkcChangeShifts.Where(cs => cs.MachineId == _setting.machineId && cs.State == "0").FirstOrDefault();
}
catch (Exception ex)
{
logger.Info($"查询当前值班信息异常{ex.Message}");
return null;
}
}
//保存交接班信息
public async Task<bool> UpdateChangeShift(HkcChangeShifts changeShift, HkcChangeShifts changeShiftNew)
{
try
{
_connection.BeginTransaction();
var insertResult = _connection.InsertWithInt32Identity(changeShiftNew);
int updateResult = _connection.HkcChangeShifts
.Where(cs => cs.Id == changeShift.Id)
.Set(cs => cs.State, "1")
.Set(cs => cs.ToDate, DateTime.Now)
.Set(cs => cs.ToOperator, changeShift.ToOperator).Update();
//插入交接班时药品数据信息
var channelStockList = _connection.ChannelStock
.Where(cs => (cs.MachineId == _setting.machineId || cs.MachineId == _setting.boxMachineId) && cs.DrawerType == 1)
.GroupBy(cs => cs.DrugId)
.Select(g => new
{
drugId = g.Key,
sumQuantity = g.Sum(cs => cs.Quantity)
}).ToList();
if (channelStockList != null && channelStockList.Count > 0)
{
//将药品库存信息写入交接明细表
for (int i = 0; i < channelStockList.Count; i++)
{
//查询药品上次交接的明细,用于记录处方数
HkcChangeShiftsDetail? historyList = _connection.HkcChangeShiftsDetail
.Where(d => d.DrugId == channelStockList[i].drugId && d.ChangeshiftsId == changeShift.Id).FirstOrDefault();
HkcChangeShiftsDetail detail = new HkcChangeShiftsDetail()
{
ChangeshiftsId = insertResult,
DrugId = channelStockList[i].drugId,
RealNumber = channelStockList[i].sumQuantity,
OrderNumber = historyList != null ? historyList.OrderNumber + historyList.RealNumber - channelStockList[i].sumQuantity : 0
};
var insertDetailResult = _connection.InsertWithInt32Identity(detail);
}
}
if (insertResult <= 0 || updateResult <= 0)
{
_connection.RollbackTransaction();
return false;
}
else
{
_connection.CommitTransaction();
return true;
}
}
catch (Exception ex)
{
logger.Error($"更新交接班信息异常: {ex.Message}");
return false;
}
}
}
}

View File

@ -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>();
}
}

View File

@ -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>();
}
}

View File

@ -0,0 +1,139 @@
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 Task<bool> ConnectionMain()
{
return await Task<bool>.Run(() =>
{
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);
}
}
return bIsConnected;
});
}
//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;
}
}
}

View File

@ -0,0 +1,42 @@
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 bool isInit { get; set; } = false;
public event PropertyChangedEventHandler? PropertyChanged;
//protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
//{
//}
}
}

View File

@ -0,0 +1,106 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<ApplicationIcon>favicon.ico</ApplicationIcon>
<Platforms>AnyCPU;x64</Platforms>
</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="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<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\use_book.grf">
<CopyToOutputDirectory>PreserveNewest</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>
<None Update="ReportTemp\Usage_Temp.grf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,256 @@
@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||!setting.Value.weigh.Contains(i))" 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">
@if (status < 3)
{
<RadzenButton IsBusy="@(status>0)" BusyText="抽屉已打开。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="开抽屉" Click="@OpenDrawer" />
}
@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.ToString().Substring(0,10)</RadzenText>
</Template>
</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>
<RadzenGridColumn Title="状态" Property="BiaoDingStatus">
</RadzenGridColumn>
</Columns>
</RadzenDataGrid>
</RadzenStack>
@code {
@inject IChannelListDao channelListDao;
@inject NavigationManager na;
@inject PortUtil PortUtil;
@inject NotificationService _message
@inject IOptions<DrawerConfig> setting;
@inject DialogService dialogService;
int status = 0;
int drawerNo = 0;
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(BiaoDing));
// 当前操作的库位号列表
public List<int> ColNos { get; set; } = new List<int>();
//当前操作的库位数据
ChannelStock currentChannelStock;
bool CompleteIsEnable = true;
bool CancleIsEnable = true;
void SelectDrawer(int drawerNo)
{
this.drawerNo = drawerNo;
grid.Reload();
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
if (drawerNo > 0)
{
var result = await channelListDao.GetChannelStockByBiaoDing(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(300, null, async (data, next, stop) =>
{
try
{
if (this.status == 0)
{
stop();
}
else
{
if (this.status == 1)
{
PortUtil.DrawerNo = this.drawerNo;
var b = await PortUtil.OpenDrawerStatusForErZhong(this.drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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
{
//查询抽屉状态
var b = await PortUtil.CheckDrawerStatusForErZhong(drawerNo);
if (!b)
{
if (this.status == 2)
{
//药盒称重抽屉
if (currentChannelStock != null && currentChannelStock.BoardType.ToString().Contains("3"))
{
//打开药盒
await PortUtil.OpenBoxByColNoForErZhong(currentChannelStock.ColNo);
this.status = 3;
}
}
if (this.status == 3)
{
this.status = 4;
//弹出标定对话框
var dialog = await dialogService.OpenAsync<BiaoDingDialog>(
$"标定库位{currentChannelStock.ColNo}",
new Dictionary<string, object>() { { "channelStockInfo",
currentChannelStock } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
currentChannelStock = null;
//关闭弹窗后将状态置为2以便下次点击药盒进行开药盒操作
this.status = 2;
}
next();
}
else
{
//抽屉已关闭
stop();
this.status = 0;
logger.Info($"抽屉关闭");
}
}
}
}
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 Cancel()
{
this.status = 0;
}
void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args)
{
if (this.status == 0)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync("请先打开抽屉后再点开药盒");
}
else
{
currentChannelStock = args.Data;
if (args.Data.BoardType.ToString().Contains("3"))
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync("正在打开药盒");
}
// else
// {
// grid.EditRow(args.Data);
// }
}
}
}

View File

@ -0,0 +1,194 @@
@using MasaBlazorApp3.Util
@using log4net
<RadzenStack>
@* <RadzenTemplateForm Submit="@((int BDQuantity) => { ConfirmOK(BDQuantity); })" Style="width:100%;height:100%"> *@
<div class="rz-form-row">
<div class="rz-form-input-wrapper">
<!--@onfocusin="@(() => Util.VirtualKeyboardHelper.ShowVirtualKeyboard())"-->
@if (channelStockInfo.Quantity>0)
{
<RadzenText TextStyle="TextStyle.Body1" Style="color: var(--rz-text-tertiary-color); align-content:center; text-align:center; font-size:medium;">库位库存不为零,请取出药品后点击【清空】按钮,清空完成后输入标定数量并放入对应数量药品并根据下一步提示操作</RadzenText>
}
else
{
<RadzenText TextStyle="TextStyle.Body1" Style="color: var(--rz-text-tertiary-color); align-content:center; text-align:center; font-size:medium;">正在清零,清零完成后输入标定数量并放入对应数量药品后点击【标定】按钮</RadzenText>
}
<RadzenTextBox id="BDQuantity" Name="BDQuantity" Value="10" Style="width:100%" />
<RadzenRequiredValidator Component="BDQuantity" Text="请填写标定数量" />
</div>
</div>
@* </RadzenTemplateForm> *@
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
<RadzenButton Click="@Clear" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Disabled="@(channelStockInfo.Quantity<=0)" Text="清空" Style="width: 120px" />
<RadzenButton Click="ConfirmOK" ButtonStyle="ButtonStyle.Success" IsBusy="@(status==2)" BusyText="正在标定。。。" Variant="Variant.Flat" Text="标定" Disabled=@(this.status<=0||this.status==2||iClearFinish>0) Style="width: 120px" />
<RadzenButton Click="@CancelClick" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
</RadzenStack>
</RadzenStack>
@code {
@inject Radzen.DialogService dialogService;
@inject NotificationService _message
@inject PortUtil PortUtil;
[Parameter] public ChannelStock channelStockInfo { get; set; }
PromiseUtil<object> promiseUtil = new PromiseUtil<object>();
private readonly ILog logger = LogManager.GetLogger(typeof(BiaoDingDialog));
int BDQuantity = 10;
int status = 0;
int iClear = 0;
int iBiaoDing = 0;
int iClearFinish = 1;
protected override async Task OnInitializedAsync()
{
if(channelStockInfo!=null&&channelStockInfo.Quantity<=0)
{
//库存为零,直接进行清空操作
await Clear();
}
base.OnInitializedAsync();
}
//清空按钮
async Task Clear()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"正在清空,请稍等");
this.status = 1;
int i = 0;
await promiseUtil.taskAsyncLoop(200, null, async (data, next, stop) =>
{
i++;
if (this.status == 0)
{
iClear = 0;
stop();
}
else
{
try
{
if (iClear == 0)
{
logger.Info($"清零操作{i}");
//无库存发送计数清零指令
await PortUtil.ClearCountForErZhong(channelStockInfo.DrawerNo, channelStockInfo.ColNo);
iClear += 1;
next();
}
else
{
logger.Info($"查数操作{i}");
//发查数指令
PortUtil.DrawerNo = channelStockInfo.DrawerNo;
PortUtil.Operate = true;
int stock = await PortUtil.CheckQuantityForBiaoDingForErZhong(channelStockInfo.ColNo);
if (stock != 0)
{
_message.Notify(
new NotificationMessage
{ Severity = NotificationSeverity.Success, Summary = "提示", Detail = "清空操作成功", Duration = 3000 }
);
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync("清空完成请放入10个药品放好后点击标定按钮");
iClear = 0;
iClearFinish = 0;
stop();
}
else
{
next();
}
}
}
catch (Exception ex)
{
logger.Info($"清空操作异常");
next();
}
}
});
}
//标定按钮
async Task ConfirmOK()
{
if (BDQuantity > 0)
{
try
{
status = 2;
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync("正在标定,请稍等");
//提示输入标定数量发26指令
await PortUtil.SetNumCountForErZhong(channelStockInfo.DrawerNo, channelStockInfo.ColNo, BDQuantity);
await Task.Delay(200);
int i = 1;
await promiseUtil.taskAsyncLoop(200, null, async (data, next, stop) =>
{
if(status==0)
{
stop();
}
if (status == 2)
{
//查数量
int quantity = await PortUtil.CheckQuantityForBiaoDingForErZhong(channelStockInfo.ColNo);
if (quantity == BDQuantity)
{
//标定完成
status = 0;
_message.Notify(
new NotificationMessage
{ Severity = NotificationSeverity.Success, Summary = "提示", Detail = "标定成功", Duration = 3000 }
);
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync("标定完成,请取出药品");
status = 0;
i = 0;
stop();
// 关闭弹窗
dialogService.Close(true);
}
else
{
i++;
logger.Info($"标定数量不一致{quantity}-{BDQuantity},标定次数{i}");
next();
}
}
});
}
catch (Exception ex)
{
logger.Error($"标定异常{ex.Message}");
_message.Notify(
new NotificationMessage
{ Severity = NotificationSeverity.Error, Summary = "提示", Detail = "标定异常", Duration = 3000 }
);
}
}
else
{
_message.Notify(
new NotificationMessage
{ Severity = NotificationSeverity.Error, Summary = "提示", Detail = "请输入标定数量", Duration = 3000 });
}
}
// 取消
async Task CancelClick()
{
status = 0;
// 关闭弹窗
dialogService.Close(true);
}
}

View File

@ -0,0 +1,150 @@
@page "/Box/BoxAddBox"
<style>
@@keyframes shake {
0% {
opacity: 1;
color: red;
}
25% {
opacity: 1;
color: orange;
}
50% {
opacity: 0;
color: yellow;
}
75% {
opacity: 1;
color: crimson;
}
100% {
opacity: 1;
color: red;
}
}
.rz-custom-header {
width: 100%;
}
.shaky-text {
animation: shake 2s infinite ease-in-out;
/* 你可以根据需要调整动画的持续时间和迭代次数 */
transition: color 0.5s linear,opacity 0.5s linear;
}
</style>
<div class="container-fluid">
<RadzenDataGrid @ref="grid" RowSelect="@OnRowSelect" TItem="ChannelList"
RowRender="@RowRender"
EmptyText="无数据"
Data="@_forecasts" @bind-Value=@selectedChannelLists
AllowColumnResize="true" AllowAlternatingRows="false"
SelectionMode="DataGridSelectionMode.Single" LoadData="@LoadData" IsLoading="@isLoading"
Count="@count" AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据"
ExpandMode="DataGridExpandMode.Multiple">
<Template Context="cs">
<RadzenDataGrid Data="@cs.ChannelStocks" EmptyText="无数据">
<Columns>
<RadzenDataGridColumn Title="药品名称" Property="Drug.DrugName">
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="规格" Property="Drug.DrugSpec">
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="厂家" Property="Drug.Manufactory">
</RadzenDataGridColumn>
@* <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="效期" Property="EffDate">
</RadzenDataGridColumn> *@
<RadzenDataGridColumn Title="基数" Property="BaseQuantity">
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="需补药数" Property="NeedQuantity">
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</Template>
<Columns>
<RadzenDataGridColumn Frozen="true" Width="200px" Title="药盒号" Property="DrawerNo">
<Template Context="DrawerNo">
@DrawerNo.DrawerNo 号药盒
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="总库存" Property="TotalQuantity"></RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</div>
@code {
@inject IChannelListDao channelStockDao;
@inject DialogService dialogService;
RadzenDataGrid<ChannelList> grid;
bool isLoading;
int count;
private IEnumerable<ChannelList>? _forecasts;
DateTime start;
DateTime end;
IList<ChannelList> selectedChannelLists;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
var result = await channelStockDao.GetBoxWaitInfo(args.Top, args.Skip);
// Update the Data property
_forecasts = result.Desserts;
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<ChannelList> args)
{
args.Expandable = args.Data.ChannelStocks.Count > 0;
}
async void OnRowSelect(ChannelList cl)
{
var b = await dialogService.OpenAsync<BoxAddBoxDetailDialog>(
$"{cl.DrawerNo}号药盒药品入库",
new Dictionary<string, object>() { { "boxChannelList", cl } },
new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
await grid.Reload();
}
}
async void StockExport()
{
}
async void AccountBookExport()
{
}
}

View File

@ -0,0 +1,301 @@
@page "/Box/BoxAddBoxDetail"
@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>
<RadzenDataGrid Data="@channelStockList" AllowAlternatingRows="true" LoadData="@LoadData"
AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
<Columns>
<RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
<RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
<RadzenDataGridColumn Property="Quantity" Title="库存" />
<RadzenDataGridColumn Title="药品批次">
<Template Context="channelStockList">
@for (int i = 0; i < channelStockList.drugManuNoList.Count; i++)
{
DrugManuNo manu = channelStockList.drugManuNoList[i];
<RadzenText TextStyle="TextStyle.Subtitle2" class="rz-mb-0">@manu.ManuNo</RadzenText>
}
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="效期">
<Template Context="channelStockList">
@for (int i = 0; i < channelStockList.drugManuNoList.Count; i++)
{
DrugManuNo manu = channelStockList.drugManuNoList[i];
<RadzenText TextStyle="TextStyle.Subtitle2" class="rz-mb-0">@manu.EffDate?.ToString("yyyy-MM-dd")</RadzenText>
}
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="入药盒数量">
<Template Context="channelStockList">
@for (int i = 0; i < channelStockList.drugManuNoList.Count; i++)
{
DrugManuNo manu = channelStockList.drugManuNoList[i];
<RadzenText TextStyle="TextStyle.Subtitle2" class="rz-mb-0">@manu.Quantity</RadzenText>
}
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
<RadzenButton Click="@Finish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="保存" Style="width: 120px" />
<RadzenButton Click="@Cancel" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
</RadzenStack>
</RadzenStack>
@code {
@inject Radzen.DialogService dialogService;
@inject IChannelListDao channelListDao;
@inject IOptions<DrawerConfig> setting;
@inject NotificationService _message
@inject PortUtil PortUtil;
private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog));
// int status;
bool isLoading;
int count;
[Parameter] public ChannelList boxChannelList { get; set; }
List<ChannelStock> channelStockList = new List<ChannelStock>();
public List<BoxTakeVo> data { get; set; }
//称重取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//开抽屉前操作标识
List<string> DrawerNoColNoList = new List<string>();
protected override async Task OnInitializedAsync()
{
channelStockList = await channelListDao.GetBoxAddToBox(boxChannelList);
base.OnInitializedAsync();
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
data = await channelListDao.getBoxWaitByBox(boxChannelList, args.Top, args.Skip);
// Update the Data property
isLoading = false;
}
// async Task OpenDrawer()
// {
// this.status = 1;
// // 解析需要打开的抽屉列表
// List<BoxTakeVo> 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());
// }
// for (int i = 0; i < data.Count; i++)
// {
// if (!DrawerNoColNoList.Contains(data[i].ChannelStock.DrawerNo.ToString() + data[i].ChannelStock.ColNo))
// {
// if (data[i].ChannelStock.BoardType.ToString().Contains("6"))
// {
// PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;
// PortUtil.ColNoLst.Add(data[i].ChannelStock.ColNo);
// data[i].BeforeQuantity[data[i].ChannelStock.ColNo - 1] = await PortUtil.CheckQuantityForSingle(data[i].ChannelStock.ColNo);
// logger.Info($"称重抽屉,开抽屉前检测数量【{string.Join(",", orderTakeVo.BeforeQuantity)}】");
// await Task.Delay(200);
// }
// //是药盒抽屉开药盒
// if (data[i].ChannelStock.BoardType.ToString().Contains("3"))
// {
// PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;
// await PortUtil.OpenBoxByColNo(data[i].ChannelStock.ColNo);
// await Task.Delay(200);
// }
// DrawerNoColNoList.Add(data[i].ChannelStock.DrawerNo.ToString() + data[i].ChannelStock.ColNo);
// }
// }
// var b = await PortUtil.OpenDrawerStatus(drawerNo);
// if (b)
// {
// PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
// 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.speechSynthesizer.SpeakAsyncCancelAll();
// PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
// PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认");
// this.status = 2;
// string alertMessage = string.Empty;
// //检查是否称重抽屉,核对实际取出数量是否与应取数量一致,不一致则弹出提示
// for (int i = 0; i < data.Count; i++)
// {
// if (data[i].ChannelStock.BoardType.ToString().Contains("6"))
// {
// PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;// drawerNo;
// PortUtil.ColNoLst.Add(data[i].ChannelStock.ColNo);
// orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1] = await PortUtil.CheckQuantityForSingle(data[i].ChannelStock.ColNo);
// logger.Info($"称重抽屉,关抽屉后检测数量【{string.Join(",", orderTakeVo.AfterQuantity)}】");
// WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
// if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
// {
// //称重自动计数数量与实际要取数量不一致弹出提示,确认后保存数据
// alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
// }
// await Task.Delay(200);
// }
// if (data[i].ChannelStock.BoardType.ToString().Contains("2"))
// {
// 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)}】");
// WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = orderTakeVo.BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
// if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
// {
// alertMessage += $"{data[i].Drug.DrugName}应取数量【{orderTakeVo.Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
// }
// }
// }
// if (!string.IsNullOrEmpty(alertMessage))
// {
// //弹出确认对话框
// alertMessage += "应取数与实际取出数不一致确认要保存吗?";
// //弹出确认提示框
// var confirm = await dialogService.OpenAsync<ConfirmDialog>(
// $"保存确认",
// new Dictionary<string, object>() { { "confirmInfo", alertMessage } },
// new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
// logger.Info(alertMessage);
// if (!confirm)
// {
// RestData();
// logger.Info("取消保存");
// // 关闭弹窗
// dialogService.Close(false);
// }
// }
// stop();
// }
// else
// {
// options._data += 1;
// next();
// }
// }
// else
// {
// next(); // continue iteration
// }
// }
// }
// }
// catch (Exception e)
// {
// RestData();
// logger.Info($"{boxChannelList.DrawerNo}药盒取药发生错误,{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 Cancel()
{
// 关闭弹窗
dialogService.Close(false);
}
async Task Finish()
{
// 保存账册、操作记录
var b = await channelListDao.BoxAddBoxFinish(boxChannelList);
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);
}
}
}

View File

@ -0,0 +1,340 @@
@page "/Box/BoxAddDetail"
@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="@Cancel" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
}
</RadzenStack>
</RadzenStack>
@code {
@inject Radzen.DialogService dialogService;
@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 ChannelList boxChannelList { get; set; }
private bool CanTakeDrug = true;
public List<BoxTakeVo> data { get; set; }
//称重取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//开抽屉前操作标识
List<string> DrawerNoColNoList = new List<string>();
protected override async Task OnInitializedAsync()
{
data = await channelListDao.getTakeInfoByBox(boxChannelList);
// 如果有【stockQuantity】字段说明有药品库存不足
if (data.Any(it => it.ChannelStock == null))
{
CanTakeDrug = false;
}
base.OnInitializedAsync();
}
async Task OpenDrawer()
{
this.status = 1;
await Task.Delay(200);
// 解析需要打开的抽屉列表
List<BoxTakeVo> 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());
}
for (int i = 0; i < data.Count; i++)
{
if (!DrawerNoColNoList.Contains(data[i].ChannelStock.DrawerNo.ToString() + data[i].ChannelStock.ColNo))
{
if (data[i].ChannelStock.BoardType.ToString().Contains("6"))
{
PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;
PortUtil.ColNoLst.Add(data[i].ChannelStock.ColNo);
data[i].BeforeQuantity[data[i].ChannelStock.ColNo - 1] = await PortUtil.CheckQuantityForSingle(data[i].ChannelStock.ColNo);
logger.Info($"称重抽屉,开抽屉前检测数量【{string.Join(",", orderTakeVo.BeforeQuantity)}】");
await Task.Delay(200);
}
//是药盒抽屉开药盒
if (data[i].ChannelStock.BoardType.ToString().Contains("3"))
{
PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;
await PortUtil.OpenBoxByColNo(data[i].ChannelStock.ColNo);
await Task.Delay(200);
}
DrawerNoColNoList.Add(data[i].ChannelStock.DrawerNo.ToString() + data[i].ChannelStock.ColNo);
}
}
var b = await PortUtil.OpenDrawerStatus(drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药");
orderTakeVo.Status = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
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;
// if (data.Any(it => it.ChannelStock.BoardType.ToString().Contains("2")))
// {
// //有单支抽屉则广播灭灯
// PortUtil.AllLightOff();
// }
if (options._data == drawerNos.Count - 1)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认");
this.status = 2;
string alertMessage = string.Empty;
//检查是否称重抽屉,核对实际取出数量是否与应取数量一致,不一致则弹出提示
for (int i = 0; i < data.Count; i++)
{
if (data[i].ChannelStock.BoardType.ToString().Contains("6"))
{
PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;// drawerNo;
PortUtil.ColNoLst.Add(data[i].ChannelStock.ColNo);
orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1] = await PortUtil.CheckQuantityForSingle(data[i].ChannelStock.ColNo);
logger.Info($"称重抽屉,关抽屉后检测数量【{string.Join(",", orderTakeVo.AfterQuantity)}】");
WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
{
//称重自动计数数量与实际要取数量不一致弹出提示,确认后保存数据
alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
}
await Task.Delay(200);
}
if (data[i].ChannelStock.BoardType.ToString().Contains("2") && data[i].ChannelStock.DrawerNo == 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)}】");
WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = orderTakeVo.BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
{
alertMessage += $"{data[i].Drug.DrugName}库位{data[i].ChannelStock.ColNo}应取数量【{data[i].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
}
}
}
//有单支抽屉则广播灭灯
if (!string.IsNullOrEmpty(alertMessage))
{
//弹出确认对话框
alertMessage += "应取数与实际取出数不一致确认要保存吗?";
// //弹出确认提示框
var confirm = await dialogService.OpenAsync<ConfirmDialog>(
$"保存确认",
new Dictionary<string, object>() { { "confirmInfo", alertMessage } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
logger.Info(alertMessage);
if (!confirm)
{
RestData();
logger.Info("取消保存");
// 关闭弹窗
dialogService.Close(false);
}
}
stop();
}
else
{
options._data += 1;
next();
}
}
else
{
next(); // continue iteration
}
}
}
}
catch (Exception e)
{
RestData();
logger.Info($"{boxChannelList.DrawerNo}药盒取药发生错误,{e.Message}");
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 }
);
if (setting.Value.single.Contains(drawerNo))
{
}
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
data.ForEach(it =>
{
it.Status = 0;
it.BeforeQuantity = new int[9];
it.AfterQuantity = new int[9];
});
this.WeightFinnalQuantity = new int[9];
DrawerNoColNoList.Clear();
}
void Cancel()
{
RestData();
// 关闭弹窗
dialogService.Close(false);
}
async Task TakeFinish()
{
// 保存账册、操作记录
var b = await channelListDao.BoxTakeFinish(data, boxChannelList);
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();
}
}

View File

@ -0,0 +1,197 @@
@page "/Box/BoxAdd"
@using MasaBlazorApp3.Report
@using Radzen.Blazor.Rendering
<style>
@@keyframes shake {
0% {
opacity: 1;
color: red;
}
25% {
opacity: 1;
color: orange;
}
50% {
opacity: 0;
color: yellow;
}
75% {
opacity: 1;
color: crimson;
}
100% {
opacity: 1;
color: red;
}
}
.rz-custom-header {
width: 100%;
}
.shaky-text {
animation: shake 2s infinite ease-in-out;
/* 你可以根据需要调整动画的持续时间和迭代次数 */
transition: color 0.5s linear,opacity 0.5s linear;
}
.my-popup {
display: none;
position:absolute;
overflow: hidden;
/* height: 360px;
width: 600px; */
border: var(--rz-panel-border);
background-color: var(--rz-panel-background-color);
box-shadow: var(--rz-panel-shadow);
border-radius: var(--rz-border-radius);
}
</style>
<div class="container-fluid">
@* <RadzenFieldset Text="报表导出">
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
<RadzenButton @ref=button Icon="download" Text="请领登记表导出" Variant="Variant.Outlined" Click="@(args => popup.ToggleAsync(button.Element))" />
<Popup @ref=popup Lazy=true class="my-popup">
<RadzenStack Orientation="Orientation.Vertical" Gap="1rem" class="rz-h-100 rz-p-4">
<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" @bind-Value="start" Style="width: 100%;" Name="Start" />
</RadzenColumn>
</RadzenRow>
<RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
<RadzenButton Icon="download" Text="导出" Variant="Variant.Outlined" Click="AccountBookExport" />
</RadzenRow>
</RadzenStack>
</RadzenFieldset>
</RadzenStack>
</Popup>
</RadzenRow>
</RadzenStack>
</RadzenFieldset> *@
<RadzenDataGrid @ref="grid" RowSelect="@OnRowSelect" TItem="ChannelList"
RowRender="@RowRender"
EmptyText="无数据"
Data="@_forecasts" @bind-Value=@selectedChannelLists
AllowColumnResize="true" AllowAlternatingRows="false"
SelectionMode="DataGridSelectionMode.Single"
ExpandMode="DataGridExpandMode.Multiple" LoadData="@LoadData" IsLoading="@isLoading" Count="@count"
AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
<Template Context="cs">
<RadzenDataGrid Data="@cs.ChannelStocks" EmptyText="无数据">
<Columns>
<RadzenDataGridColumn Title="药品名称" Property="Drug.DrugName">
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="规格" Property="Drug.DrugSpec">
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="厂家" Property="Drug.Manufactory">
</RadzenDataGridColumn>
@* <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="效期" Property="EffDate">
</RadzenDataGridColumn> *@
<RadzenDataGridColumn Title="基数" Property="BaseQuantity">
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="需补药数" Property="NeedQuantity">
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</Template>
<Columns>
<RadzenDataGridColumn Frozen="true" Width="200px" Title="药盒号" Property="DrawerNo">
<Template Context="DrawerNo">
@(DrawerNo.DrawerNo == 99 ? "急诊药盒" : DrawerNo.DrawerNo == 111 ? "恢复室药盒" :
DrawerNo.DrawerNo == 31 ? "胃镜药盒" :
DrawerNo.DrawerNo == 32 ? "导管药盒" :
DrawerNo.DrawerNo == 33 ? "生殖药盒" :
DrawerNo.DrawerNo == 34 ? "妇门药盒" : $"{DrawerNo.DrawerNo}-{(DrawerNo.ColNo == 1 ? '白' : '绿')}")
@* @(DrawerNo.DrawerNo == 99 ? "急诊药盒" : DrawerNo.DrawerNo == 111 ? "恢复室药盒" : $"{DrawerNo.DrawerNo}-{(DrawerNo.ColNo==1?'白':'绿')}") *@
@* @($"{DrawerNo.DrawerNo}-{DrawerNo.ColNo}") *@
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="总库存" Property="TotalQuantity"></RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</div>
@code {
@inject IChannelListDao channelStockDao;
@inject DialogService dialogService;
@inject IReportDataDao reportDataDao;
RadzenDataGrid<ChannelList> grid;
bool isLoading;
int count;
private IEnumerable<ChannelList>? _forecasts;
DateTime start;
DateTime end;
RadzenButton button;
Popup popup;
IList<ChannelList> selectedChannelLists;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
var result = await channelStockDao.GetAllBoxAddDrug(args.Top, args.Skip);
// Update the Data property
_forecasts = result.Desserts;
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<ChannelList> args)
{
args.Expandable = args.Data.ChannelStocks.Count > 0;
}
async void OnRowSelect(ChannelList cl)
{
var b = await dialogService.OpenAsync<BoxAddDetailDialog>(
cl.DrawerNo==99?"急诊药盒":cl.DrawerNo==111?"恢复室药盒":$"{cl.DrawerNo}-{(cl.ColNo==1?'白':'绿')} 药盒加药",
new Dictionary<string, object>() { { "boxChannelList", cl } },
new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
await grid.Reload();
}
}
//请领登记表导出
async Task AccountBookExport()
{
// string drugId = drugName != null ? drugName.Split('/').Last().Trim():"";
// GridReportUtil gridReportUtil = new GridReportUtil();
PageData<ReportApplyInfo> pageData = await reportDataDao.GetApplyInfoDate(start);
GridReportUtil.PrintReport("account_book_temp.grf", pageData);
}
}

View File

@ -0,0 +1,278 @@
@page "/Box/BoxBindings"
<style>
.mycol {
width: calc(100%/8);
margin: 4px !important;
}
</style>
<div class="container-fluid">
<div class="row">
<div class="col-12 mb-4">
@* <RadzenFieldset Text="查询">
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center">
<RadzenText TextStyle="TextStyle.Overline" class="rz-display-flex rz-mt-2 rz-my-0">选择套餐</RadzenText>
<RadzenDropDownDataGrid AllowVirtualization="true" Name="planName" TValue="Plan" Data="@plans" Value="@selectedPlan" ValueChanged="@OnPlanSelected"
Style="width:100%; display: block;" AllowFilteringByAllStringColumns="true" TextProperty="Name">
<Columns>
<RadzenDropDownDataGridColumn Property="Name" Title="套餐名称" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
<RadzenButton ButtonStyle="ButtonStyle.Secondary" Variant="Variant.Outlined" Size="ButtonSize.Small" Click="@EditChannel" Text="绑定/解绑" />
</RadzenStack>
</RadzenFieldset> *@
<form onsubmit="@(() => EditChannel())">
<RadzenFieldset Text="选择套餐">
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenRow AlignItems="AlignItems.Center">
<RadzenDropDownDataGrid AllowVirtualization="true" Name="planName" TValue="Plan" Data="@plans" Value="@selectedPlan" ValueChanged="@OnPlanSelected"
Style="width:100%; display: block;" AllowFilteringByAllStringColumns="true" TextProperty="Name">
<Columns>
<RadzenDropDownDataGridColumn Property="Name" Title="套餐名称" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
</RadzenRow>
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="12">
<RadzenButton ButtonType="ButtonType.Submit" Size="ButtonSize.Medium" Text="绑定/解绑" />
@* <RadzenButton Size="ButtonSize.Medium" Click="@EditChannel" IsBusy="isLoading" Text="解绑" ButtonStyle="ButtonStyle.Warning" /> *@
</RadzenColumn>
</RadzenRow>
</RadzenStack>
</RadzenFieldset>
</form>
</div>
</div>
<div class="row">
<div class="col-12 mb-4">
<RadzenDataList @ref="grid" LoadData="@LoadData" WrapItems="true" Count="@count" IsLoading="@isLoading" Data="@_forecasts" PageSize="56" style="height:61vh; overflow:auto">
<Template Context="channel">
<RadzenCard class="mycol" onclick="@(() => CardClick(channel))">
<RadzenRow>
<RadzenColumn Size="8" Class="rz-text-truncate">
@if (channel.DrawerNo == 99)
{
<b class="rz-pr-3">@($"急诊药盒")</b>
}
else if(channel.DrawerNo==111)
{
<b class="rz-pr-3">@($"恢复室药盒")</b>
}
else if (channel.DrawerNo == 31)
{
<b class="rz-pr-3">@($"胃镜药盒")</b>
}
else if(channel.DrawerNo==32)
{
<b class="rz-pr-3">@($"导管药盒")</b>
}
else if (channel.DrawerNo == 33)
{
<b class="rz-pr-3">@($"生殖药盒")</b>
}
else if(channel.DrawerNo==34)
{
<b class="rz-pr-3">@($"妇门药盒")</b>
}
else
{
<b class="rz-pr-3">@($"{channel.DrawerNo}-{(channel.ColNo == 1 ? '白':'绿')}")</b>
}
@* <b>号药盒</b> *@
</RadzenColumn>
<RadzenColumn Size="4" class="rz-text-align-end">
<RadzenCheckBox TValue="bool" Disabled=@channel.BoxDisabled @bind-Value=@channel.IsChecked />
</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>
<RadzenText TextStyle="TextStyle.Body1"><b>@(channel.PlanInfo.Name)</b></RadzenText>
<RadzenText TextStyle="TextStyle.Overline" class="rz-display-flex rz-mt-4 rz-mb-0">总库存</RadzenText>
<RadzenText TextStyle="TextStyle.Body1"><b>@(channel.TotalQuantity)</b></RadzenText>
</RadzenStack>
</RadzenStack>
</RadzenCard>
</Template>
</RadzenDataList>
</div>
</div>
</div>
@code {
@inject IChannelListDao channelListDao;
@inject IDrugInfoDao drugInfoDao;
@inject DialogService dialogService;
@inject NotificationService _message
@inject IPlanDao planDao;
RadzenDataList<ChannelList> grid;
bool isLoading;
int count;
private IEnumerable<ChannelList>? _forecasts;
List<DrugInfo> drugInfos;
List<DrugManuNo> drugManuNos;
DrugInfo drugInfo;
DrugManuNo drugManuNo;
List<Plan> plans;
int firstFlag = 0;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
var resultPlan = await planDao.GetAllPlanInfo();
plans = resultPlan.Desserts.Where(p => p._PlanDetails.Count > 0).ToList();
firstFlag = 0;
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
var result = await channelListDao.GetAllChannelListWithPlan(args.Top, args.Skip);
// Update the Data property
_forecasts = result.Desserts;
// Update the count
count = result.TotalDesserts;
isLoading = false;
plans = result.Other;
}
async Task reloadGrid()
{
await grid.Reload();
}
// 默认选中的项
private Plan selectedPlan = new();
// 处理选择变更(可选)
private void OnPlanSelected(Plan plan)
{
selectedPlan = plan;
}
//绑定
async Task EditChannel()
{
List<ChannelList> bindList = _forecasts.Where(b => b.IsChecked).ToList();
if (bindList == null || bindList.Count <= 0)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请先选择药箱号再点击按钮", Duration = 4000 }
);
return;
}
if (!string.IsNullOrEmpty(bindList[0].DrugId))
{
//之前有绑定,在进行解绑
foreach (var item in bindList)
{
var b = await channelListDao.UnBindBox(item);
if (b)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"解除绑定成功", Duration = 4000 }
);
}
await grid.Reload();
}
}
else
{// 否则是进行解绑
if (selectedPlan != null && selectedPlan.Id > 0)
{
foreach (var item in bindList)
{
var b = await channelListDao.BindBox(item, selectedPlan);
if (b)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"绑定成功", Duration = 4000 }
);
}
}
await grid.Reload();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择套餐", Duration = 4000 }
);
}
}
}
async Task CardClick(ChannelList list)
{
if (firstFlag == 0 && !(list.BoxDisabled))
{
firstFlag = 1;
if (!string.IsNullOrEmpty(list.DrugId))
{
list.IsChecked = !list.IsChecked;
//已绑药品需要解绑,未绑定的不可选
if (list.IsChecked)
{
_forecasts.Where(it => it.DrugId != list.DrugId || it.TotalQuantity > 0).ToList().ForEach(it => it.BoxDisabled = true);
selectedPlan = await planDao.GetPlanById(Convert.ToInt32(list.DrugId));
}
else
{
_forecasts.Where(it => it.TotalQuantity <= 0).ToList().ForEach(it => it.BoxDisabled = false);
firstFlag = 0;
}
}
else
{
list.IsChecked = !list.IsChecked;
//未绑定药品则已绑定的不可选
if (list.IsChecked)
{
_forecasts.Where(it => !string.IsNullOrEmpty(it.DrugId) || it.TotalQuantity > 0).ToList().ForEach(it => it.BoxDisabled = true);
}
else
{
_forecasts.ToList().Where(it => it.TotalQuantity <= 0).ToList().ForEach(it => it.BoxDisabled = false);
firstFlag = 0;
}
}
}
else
{
if (!list.BoxDisabled)
{
list.IsChecked = !list.IsChecked;
}
//isChecked==false 1)是否全部是false是则将所有isChecked==true不是则不做改变
if (!_forecasts.Any(b => b.IsChecked == true))
{
_forecasts.Where(it => it.TotalQuantity <= 0).ToList().ForEach(it => it.BoxDisabled = false);
firstFlag = 0;
}
}
await InvokeAsync(StateHasChanged);
}
}

View File

@ -0,0 +1,212 @@
@page "/Box/BoxBindings123"
<div class="container-fluid">
<div class="row">
<RadzenFieldset class="col-12 mb-4" Text="选择药盒">
<div class="col-12 row justify-content-center align-items-center text-center">
<div class="row justify-content-around align-items-center" style="overflow:auto">
@if (BoxList != null)
{
foreach (var item in BoxList)
{
<div class="col-2">
<RadzenCheckBox Style="width:40px;height:40px;margin:2px" TValue="bool" Disabled=@item.BoxDisabled @bind-Value=@item.IsChecked Name="@($"CheckBox_{item.DrawerNo}")" Change="@((bool isChecked) => OnCheckBoxChange(isChecked, item.DrawerNo))" />
@if(item.DrawerNo<51)
{
<RadzenLabel Text="@($"{(item.DrawerNo % 2 == 0 ? item.DrawerNo : item.DrawerNo+1)/2}-{(item.DrawerNo % 2 == 0 ? 2 : 1)}")" Component="@($"CheckBox_{item.DrawerNo}")" />
}
else
{
<RadzenLabel Text="@($"{item.DrawerNo -25}")" Component="@($"CheckBox_{item.DrawerNo}")" />
}
</div>
}
}
</div>
</div>
</RadzenFieldset>
<RadzenCard class="col-12 mb-2">
<RadzenButton ButtonStyle="ButtonStyle.Secondary" Variant="Variant.Outlined" Size="ButtonSize.Small" Click="@EditChannel" Text="绑定/解绑" />
<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>
<RadzenDropDownDataGrid AllowVirtualization="true" Name="planName" TValue="Plan" Data="@plans" Value="@selectedPlan" ValueChanged="@OnPlanSelected"
Style="width:100%; display: block;" AllowFilteringByAllStringColumns="true" TextProperty="Name">
<Columns>
<RadzenDropDownDataGridColumn Property="Name" Title="套餐名称" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
</RadzenStack>
</RadzenStack>
</RadzenCard>
</div>
</div>
@code {
@inject IChannelListDao channelListDao;
@inject IDrugInfoDao drugInfoDao;
@inject DialogService dialogService;
@inject NotificationService _message;
@inject IPlanDao planDao;
int count;
private List<ChannelList>? _forecasts;
private List<ChannelList>? BoxList;
List<DrugInfo> drugInfos;
List<DrugManuNo> drugManuNos;
DrugInfo drugInfo;
DrugManuNo drugManuNo;
int firstFlag = 0;
List<Plan> plans;
// 默认选中的项
private Plan selectedPlan = new();
protected override async Task OnInitializedAsync()
{
await LoadData();
await base.OnInitializedAsync();
//drugInfos = await drugInfoDao.GetAllDrug();
}
async Task LoadData()
{
BoxList = await channelListDao.GetAllBox();
var result = await planDao.GetAllPlanInfo();
plans = result.Desserts.Where(p=>p._PlanDetails.Count>0).ToList();
_forecasts = await channelListDao.GetAllChannelList();
firstFlag = 0;
}
// 处理选择变更(可选)
private void OnPlanSelected(Plan plan)
{
selectedPlan = plan;
}
//绑定
async Task EditChannel()
{
List<ChannelList> bindList = BoxList.Where(b => b.IsChecked).ToList();
if (bindList == null || bindList.Count <= 0)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请先选择药箱号再点击按钮", Duration = 4000 }
);
return;
}
if (!string.IsNullOrEmpty(bindList[0].DrugId))
{
//之前有绑定,在进行解绑
foreach (var item in bindList)
{
var b = await channelListDao.UnBindBox(item);
if (b)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"解除绑定成功", Duration = 4000 }
);
}
}
await LoadData();
}
else
{// 否则是进行绑定
if (selectedPlan != null && selectedPlan.Id > 0)
{
foreach (var item in bindList)
{
var b = await channelListDao.BindBox(item, selectedPlan);
if (b)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"绑定成功", Duration = 4000 }
);
}
}
await LoadData();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择套餐", Duration = 4000 }
);
}
}
}
private async Task OnCheckBoxChange(bool isChecked, int DrawerNo)
{
//isChecked==true 1)当前选择的药箱已经绑药套餐且库存<=0如果有库存则提示不能选择如果无库存则列出与之绑定相同套餐且库存<=0的药箱号其他药箱号不可选择
// 2)当前选择的药箱未绑定套餐则将所有未绑定套餐的药箱号列出来,其他药箱不可操作
if (firstFlag == 0)
{
if (isChecked)
{
firstFlag = 1;
string drugId = BoxList.Where(b => b.DrawerNo == DrawerNo).Select(b => b.DrugId).FirstOrDefault();
//所选药箱已绑定套餐
if (!string.IsNullOrEmpty(drugId))
{
//查询该药箱下的药品库存是否存在不为0的存在则不让选择
List<ChannelStock> stockList = await channelListDao.GetChannelStockByBox(DrawerNo);
if (stockList != null && stockList.Count > 0)
{
//该药箱下存在库存不为0的药品
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"该药盒下的药品仍有库存,请清库存后再操作", Duration = 4000 }
);
BoxList.ForEach(it => it.IsChecked = false);
firstFlag = 0;
return;
}
else
{
//无库存则列出与之绑定相同套餐且库存 <= 0的药箱号其他药箱号不可选择
// BoxList.Where(b => string.IsNullOrEmpty(b.DrugId)).ToList().ForEach(b => b.BoxDisabled = true);
//1)查询套餐下无库存的药箱号
List<ChannelStock>? lists = await channelListDao.GetChannelStockByPlan(drugId);
if (lists != null && lists.Count > 0)
{
int[] boxNum = lists.Select(l => l.DrawerNo).ToArray();
//不在该lists下的药箱号不可选择
BoxList.Where(b => !boxNum.Contains(b.DrawerNo)).ToList().ForEach(b => b.BoxDisabled = true);
}
selectedPlan = await planDao.GetPlanById(Convert.ToInt32(drugId));
}
}
else
{
//未绑定套餐 ,列出所有未绑的药箱号,其他不可操作
BoxList.Where(b => !string.IsNullOrEmpty(b.DrugId)).ToList().ForEach(b => b.BoxDisabled = true);
}
}
}
else
{
if (!isChecked)
{
//isChecked==false 1)是否全部是false是则将所有isChecked==true不是则不做改变
if (!BoxList.Any(b => b.IsChecked == true))
{
BoxList.ForEach(b => b.BoxDisabled = false);
firstFlag = 0;
}
}
}
}
}

View File

@ -0,0 +1,398 @@
@page "/Box/BoxRemove"
@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 Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">药名:</RadzenText>
<RadzenText Class="rz-text-truncate"><b>@(channelStock.Drug.DrugName)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">规格:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(channelStock.Drug.DrugSpec)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">批次:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(channelStock.ManuNo)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">效期:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(channelStock.EffDate)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">库存:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(channelStock.Quantity)</b></RadzenText> *@
<div style="text-align: left;width:15vw">
<div class="rz-text-h6 rz-mb-0">药品名称</div>
@(channelStock.Drug.DrugName)
</div>
<div style="text-align: left;width:6vw">
<div class="rz-text-h6 rz-mb-0">规格</div>
@(channelStock.Drug.DrugSpec)
</div>
<div style="text-align: left;width:8vw;">
<div class="rz-text-h6 rz-mb-0">批次</div>
@(channelStock.ManuNo)
</div>
<div style="text-align: left;width:8vw;">
<div class="rz-text-h6 rz-mb-0">效期</div>
@(channelStock.EffDate)
</div>
<div style="text-align: left;width:4vw;">
<div class="rz-text-h6 rz-mb-0">库存</div>
@(channelStock.Quantity)
</div>
</RadzenStack>
</RadzenStack>
<RadzenStack style="align-content:center">
<RadzenStack class="rz-p-4 rz-border-radius-1" Style="border: var(--rz-grid-cell-border);align-content:center" Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">移入</RadzenText>
<RadzenDropDownDataGrid AllowVirtualization="true" Name="BoxColorList" TValue="BoxModel" Data="@BoxColorList" Value="BoxColor" Style="width: 11vw;"
ValueChanged="@((args) => OnColorChanged(args))" AllowFiltering="false"
AllowFilteringByAllStringColumns="true" TextProperty="药箱号">
<Template>
@((context as BoxModel).BoxNo == 1 ? "白" : (context as BoxModel).BoxNo == 2 ? "绿" : (context as BoxModel).BoxNo == 3 ? "非常规" : "抽屉")
</Template>
<Columns>
<RadzenDropDownDataGridColumn Property="BoxNo" Title="药箱颜色" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
<RadzenDropDown @bind-Value="SelectedDrawerNo" Data="@DrawerNos" Style="display: block;" Name="DropDownChangeEvent">
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@(SelectedDrawerNo)</RadzenText>
</RadzenDropDown>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">移入数量</RadzenText>
<RadzenNumeric Min="0" Style="display: block" Max=@channelStock.Quantity Name="Quantity" @bind-Value="removeQuantity" />
</RadzenStack>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
@if (BoxColor.BoxNo == 4)
{
@if (status < 3)
{
<RadzenButton IsBusy="@(status>0)" BusyText="加药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="加药" Click="@OpenDrawer" Style="width: 120px" />
<RadzenButton Visible="@CancleIsEnable" Variant="Variant.Flat" Text="取消" Click="@Cancel" Style="width: 120px" />
}
@if (status == 3)
{
<RadzenButton Visible="@CompleteIsEnable" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="完成" Click="@AddFinish" Style="width: 120px" />
<RadzenButton Visible="@CancleIsEnable" Variant="Variant.Flat" Text="取消" Click="@Cancel" Style="width: 120px" />
}
}
else
{
<RadzenButton Click="@Save" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
<RadzenButton Click="@Cancel" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
}
</RadzenStack>
</RadzenStack>
@code {
@inject Radzen.DialogService dialogService;
@inject IChannelListDao channelListDao;
@inject IOptions<SettingConfig> setting
@inject IOptions<DrawerConfig> drawerSetting;
@inject NotificationService _message
@inject PortUtil PortUtil;
private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog));
bool CompleteIsEnable = true;
bool CancleIsEnable = true;
int removeQuantity = 0;
int status;
string[] AllDrawerNos;
string[] DrawerNos;
string SelectedDrawerNo = "1-1";
//药盒集合
List<BoxModel> BoxList = new List<BoxModel>();
//药盒颜色集合
List<BoxModel> BoxColorList = new List<BoxModel>()
{
new BoxModel{BoxNo=1,BoxName=1 },
new BoxModel{BoxNo=2 ,BoxName=1},
new BoxModel{BoxNo=3 ,BoxName=1},
new BoxModel{BoxNo=4 ,BoxName=1}
};
BoxModel BoxColor = new BoxModel { BoxNo = 1, BoxName = 1 };
BoxModel BoxNum;
[Parameter] public ChannelStock channelStock { get; set; }
private bool CanTakeDrug = true;
// public List<BoxTakeVo> data { get; set; }
//称重取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//开抽屉前操作标识
List<string> DrawerNoColNoList = new List<string>();
protected override async Task OnInitializedAsync()
{
AllDrawerNos = await channelListDao.GetDrawerNumForRemove(channelStock);
if (AllDrawerNos != null && AllDrawerNos.Count() > 0)
{
DrawerNos = AllDrawerNos.Where(d => d.EndsWith('白')).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0)
SelectedDrawerNo = DrawerNos[0];
// var result = await channelListDao.GetChannelStockByDrug(channelStock, SelectedDrawerNo, 8, 0);
// selectedDrawerData = result.Desserts;
}
else
{
DrawerNos = new string[] { "无库位" };
}
base.OnInitializedAsync();
}
// void RestData()
// {
// PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
// this.status = 0;
// data.ForEach(it =>
// {
// it.Status = 0;
// it.BeforeQuantity = new int[9];
// it.AfterQuantity = new int[9];
// });
// this.WeightFinnalQuantity = new int[9];
// DrawerNoColNoList.Clear();
// }
private async Task OnColorChanged(object value)
{
BoxColor = (BoxModel)value;
if (AllDrawerNos != null && AllDrawerNos.Length > 0 && AllDrawerNos[0] != "无库位")
{
if ((((BoxModel)value).BoxNo) == 3)
{
DrawerNos = AllDrawerNos.Where(d => !(d.EndsWith('白')) && !(d.EndsWith('绿')) && !(d.Contains('-'))).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0 && DrawerNos[0] != "无库位")
{
SelectedDrawerNo = DrawerNos[0];
}
else
{
SelectedDrawerNo = "无库位";
}
await InvokeAsync(StateHasChanged);
}
else
{
if ((((BoxModel)value).BoxNo) == 1)
{
DrawerNos = AllDrawerNos.Where(d => d.EndsWith('白')).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0 && DrawerNos[0] != "无库位")
{
SelectedDrawerNo = DrawerNos[0];
}
else
{
SelectedDrawerNo = "无库位";
}
await InvokeAsync(StateHasChanged);
}
else if ((((BoxModel)value).BoxNo) == 2)
{
DrawerNos = AllDrawerNos.Where(d => d.EndsWith('绿')).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0 && DrawerNos[0] != "无库位")
{
SelectedDrawerNo = DrawerNos[0];
}
else
{
SelectedDrawerNo = "无库位";
}
await InvokeAsync(StateHasChanged);
}
else if ((((BoxModel)value).BoxNo) == 4)
{
DrawerNos = AllDrawerNos.Where(d => !(d.EndsWith('绿')) && !(d.EndsWith('白')) && d.Contains('-')).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0 && DrawerNos[0] != "无库位")
{
SelectedDrawerNo = DrawerNos[0];
}
else
{
SelectedDrawerNo = "无库位";
}
await InvokeAsync(StateHasChanged);
}
}
}
}
void Cancel()
{
RestData();
// 关闭弹窗
dialogService.Close(false);
}
async Task Save()
{
if (removeQuantity <= 0)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = "请输入移入数量", Duration = 4000 });
return;
}
if (string.IsNullOrEmpty(SelectedDrawerNo) || SelectedDrawerNo == "无库位")
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = "无可移入的药盒", Duration = 4000 });
return;
}
SelectedDrawerNo = SelectedDrawerNo == "急诊药盒" ? "99-1" : SelectedDrawerNo == "恢复室药盒" ? "111-1" : SelectedDrawerNo;
var b = await channelListDao.BoxRemoveFinish(channelStock, SelectedDrawerNo, removeQuantity);
if (!b)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
logger.Error($"药盒移出保存数据失败,数据{JsonConvert.SerializeObject(channelStock)}");
}
else
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"交换完成", Duration = 4000 });
// 关闭弹窗
dialogService.Close(true);
}
//重置状态
this.RestData();
}
int drawerNo = 1;
int colNo = 1;
int[] BeforeQuantity = new int[9];
int[] AfterQuantity = new int[9];
async Task OpenDrawer()
{
this.status = 1;
var selectSpl = SelectedDrawerNo.Split('-');
if (selectSpl != null && selectSpl.Count() > 0)
{
drawerNo = Convert.ToInt32(selectSpl[0]);
colNo = Convert.ToInt32(selectSpl[1]);
}
await Task.Delay(200);
PortUtil.DrawerNo = drawerNo;
// 根据抽屉类型来决定打开前是否需要查询数量
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 (drawerSetting.Value.single != null && drawerSetting.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.speechSynthesizer.SpeakAsyncCancelAll();
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)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatus2(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"加药完成,请,点击完成按钮");
this.status = 3;
PortUtil.Operate = false;
stop();
}
else
{
if (drawerSetting.Value.single != null && drawerSetting.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)}】");
removeQuantity = this.AfterQuantity[colNo - 1] - this.BeforeQuantity[colNo - 1];
await InvokeAsync(StateHasChanged);
}
next(); // continue iteration
}
}
}
catch (Exception e)
{
logger.Info($"抽屉加药发生错误,{e.Message}");
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 }
);
if (drawerSetting.Value.single != null && drawerSetting.Value.single.Contains(this.drawerNo))
{
}
RestData();
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
// this.BeforeQuantity = new int[9];
// this.AfterQuantity = new int[9];
// currentCol = 0;
// ColNos.Clear();
}
async Task AddFinish()
{
if (removeQuantity <= 0)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = "请输入移入数量", Duration = 4000 });
return;
}
// 保存账册、操作记录
var b = await channelListDao.RemoveDrugToDrawerFinish(SelectedDrawerNo, channelStock, removeQuantity);
if (!b)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(channelStock)}");
}
//重置状态
this.RestData();
// 关闭弹窗
dialogService.Close(true);
}
}

View File

@ -0,0 +1,332 @@
@page "/Box/BoxReplace"
@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 Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">药名:</RadzenText>
<RadzenText Class="rz-text-truncate"><b>@(channelStock.Drug.DrugName)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">规格:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(channelStock.Drug.DrugSpec)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">批次:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(channelStock.ManuNo)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">效期:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(channelStock.EffDate)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">库存:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(channelStock.Quantity)</b></RadzenText>
<RadzenText Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">交换药盒:</RadzenText> *@
<div style="text-align: left;width:15vw">
<div class="rz-text-h6 rz-mb-0">药品名称</div>
@(channelStock.Drug.DrugName)
</div>
<div style="text-align: left;width:6vw">
<div class="rz-text-h6 rz-mb-0">规格</div>
@(channelStock.Drug.DrugSpec)
</div>
<div style="text-align: left;width:8vw;">
<div class="rz-text-h6 rz-mb-0">批次</div>
@(channelStock.ManuNo)
</div>
<div style="text-align: left;width:8vw;">
<div class="rz-text-h6 rz-mb-0">效期</div>
@(channelStock.EffDate)
</div>
<div style="text-align: left;width:4vw;">
<div class="rz-text-h6 rz-mb-0">库存</div>
@(channelStock.Quantity)
</div>
<div class="rz-text-h6 rz-mb-0;width:10vw">
交换药盒
<RadzenDropDownDataGrid AllowVirtualization="true" Name="BoxColorList" TValue="BoxModel" Data="@BoxColorList" Value="BoxColor" Style="width: 8vw;"
ValueChanged="@((args) => OnColorChanged(args))" AllowFiltering="false"
AllowFilteringByAllStringColumns="true" TextProperty="药箱号">
<Template>
@((context as BoxModel).BoxNo == 1 ? "白" : (context as BoxModel).BoxNo == 2 ? "绿" : "非常规")
</Template>
<Columns>
<RadzenDropDownDataGridColumn Property="BoxNo" Title="药箱颜色" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
<RadzenDropDown @bind-Value="SelectedDrawerNo" Data="@DrawerNos" Style="width:10vw" Change="@(args => SelectedDrawerChange(args))" Name="DropDownChangeEvent">
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@(SelectedDrawerNo)</RadzenText>
</RadzenDropDown>
</div>
</RadzenStack>
<RadzenDataGrid @ref="grid" Data="@selectedDrawerData" AllowAlternatingRows="true" LoadData="@LoadData" IsLoading="@isLoading" Count="@count" EmptyText="无数据"
CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args))"
AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
<Columns>
<RadzenDataGridColumn Property="DrawerNo" Title="药盒号">
<Template Context="DrawerNo">
@(DrawerNo.DrawerNo == 99 ? "急诊药盒" : DrawerNo.DrawerNo == 111 ? "恢复室药盒" :
DrawerNo.DrawerNo == 31 ? "胃镜药盒" :
DrawerNo.DrawerNo == 32 ? "导管药盒" :
DrawerNo.DrawerNo == 33 ? "生殖药盒" :
DrawerNo.DrawerNo == 34 ? "妇门药盒" : $"{DrawerNo.DrawerNo}-{(DrawerNo.ColNo == 1 ? '白' : '绿')}")
</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="库存" />
<RadzenDataGridColumn MinWidth="100px" Title="交换数量" Property="AddQuantity">
<EditTemplate Context="cs">
<RadzenNumeric Min="0" Style="display: block" Max=@cs.Quantity 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>
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
<RadzenButton Click="@Save" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
<RadzenButton Click="@Cancel" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
</RadzenStack>
</RadzenStack>
@code {
@inject Radzen.DialogService dialogService;
@inject IChannelListDao channelListDao;
@inject IOptions<SettingConfig> setting;
@inject IOptions<DrawerConfig> drawerSetting;
@inject NotificationService _message
@inject PortUtil PortUtil;
private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog));
bool CompleteIsEnable = true;
bool CancleIsEnable = true;
int status;
bool isLoading;
int count;
[Parameter] public ChannelStock channelStock { get; set; }
private bool CanTakeDrug = true;
// public List<BoxTakeVo> data { get; set; }
public List<ChannelStock> selectedDrawerData { get; set; }
//称重取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//开抽屉前操作标识
List<string> DrawerNoColNoList = new List<string>();
//药盒集合
List<BoxModel> BoxList = new List<BoxModel>();
BoxModel BoxColor = new BoxModel { BoxNo = 1, BoxName = 1 };
string[] AllDrawerNos;
string[] DrawerNos;
string SelectedDrawerNo = "1-1";
//药盒颜色集合
List<BoxModel> BoxColorList = new List<BoxModel>()
{
new BoxModel{BoxNo=1,BoxName=1 },
new BoxModel{BoxNo=2 ,BoxName=1},
new BoxModel{BoxNo=3 ,BoxName=1}
};
protected override async Task OnInitializedAsync()
{
// AllDrawerNos = await channelListDao.GetDrawerNum(channelStock);
// if (AllDrawerNos != null && AllDrawerNos.Count() > 0)
// {
// if (DrawerNos == null || DrawerNos.Length <= 0)
// {
// DrawerNos = new string[] { "无库位" };
// }
// }
AllDrawerNos = await channelListDao.GetDrawerNumForRemove(channelStock);
if (AllDrawerNos != null && AllDrawerNos.Count() > 0)
{
DrawerNos = AllDrawerNos.Where(d => d.EndsWith('白')).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0)
SelectedDrawerNo = DrawerNos[0];
}
else
{
DrawerNos = new string[] { "无库位" };
}
base.OnInitializedAsync();
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
if (DrawerNos != null && !DrawerNos.Contains("无库位") && DrawerNos.Count() > 0)
{
SelectedDrawerNo = DrawerNos[0];
var result = await channelListDao.GetChannelStockByDrug(channelStock, SelectedDrawerNo, args.Top, args.Skip);
selectedDrawerData = result.Desserts;
if (selectedDrawerData != null && selectedDrawerData.Count > 0)
{
if (selectedDrawerData[0].DrawerNo <= 30)
{
if (selectedDrawerData[0].ColNo == 1)
{
BoxColor = BoxColorList[0];
}
else
{
BoxColor = BoxColorList[1];
}
}
else
{
BoxColor = BoxColorList[2];
}
}
count = result.TotalDesserts;
}
isLoading = false;
}
private async Task OnColorChanged(object value)
{
BoxColor = (BoxModel)value;
if (AllDrawerNos != null && AllDrawerNos.Length > 0 && AllDrawerNos[0] != "无库位")
{
if (BoxColor.BoxNo == 3)
{
DrawerNos = AllDrawerNos.Where(d => !(d.EndsWith('白')) && !(d.EndsWith('绿')) && !(d.Contains('-'))).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0 && DrawerNos[0] != "无库位")
{
SelectedDrawerNo = DrawerNos[0];
await SelectedDrawerChange(SelectedDrawerNo);
}
else
{
SelectedDrawerNo = "无库位";
}
await InvokeAsync(StateHasChanged);
}
else
{
if (BoxColor.BoxNo == 1)
{
DrawerNos = AllDrawerNos.Where(d => d.EndsWith('白')).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0 && DrawerNos[0] != "无库位")
{
SelectedDrawerNo = DrawerNos[0];
await SelectedDrawerChange(SelectedDrawerNo);
}
else
{
SelectedDrawerNo = "无库位";
}
await InvokeAsync(StateHasChanged);
}
else if (BoxColor.BoxNo == 2)
{
DrawerNos = AllDrawerNos.Where(d => d.EndsWith('绿')).ToArray();
if (DrawerNos != null && DrawerNos.Length > 0 && DrawerNos[0] != "无库位")
{
SelectedDrawerNo = DrawerNos[0];
await SelectedDrawerChange(SelectedDrawerNo);
}
else
{
SelectedDrawerNo = "无库位";
}
await InvokeAsync(StateHasChanged);
}
// else if (BoxColor.BoxNo == 4)
// {
// DrawerNos = AllDrawerNos.Where(d => !(d.EndsWith('绿')) && !(d.EndsWith('白')) && d.Contains('-')).ToArray();
// if (DrawerNos != null && DrawerNos.Length > 0 && DrawerNos[0] != "无库位")
// {
// SelectedDrawerNo = DrawerNos[0];
// await SelectedDrawerChange(SelectedDrawerNo);
// }
// else
// {
// SelectedDrawerNo = "无库位";
// }
// await InvokeAsync(StateHasChanged);
// }
}
}
}
void Cancel()
{
RestData();
// 关闭弹窗
dialogService.Close(false);
}
async Task Save()
{
if (selectedDrawerData != null && selectedDrawerData.Any(cl => cl.AddQuantity != 0 && cl.DrugId != null && cl.ManuNo != null))
{
if (selectedDrawerData.Where(cs => cs.AddQuantity != 0).Sum(cs => cs.AddQuantity) > channelStock.Quantity)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Warning, Summary = "提示", Detail = $"交换总数量不能大于库存", Duration = 4000 });
return;
}
var b = await channelListDao.BoxReplaceFinish(channelStock, selectedDrawerData.Where(cl => cl.AddQuantity != 0).ToList());
if (!b)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
logger.Error($"药盒药品替换保存数据库失败,数据{JsonConvert.SerializeObject(selectedDrawerData.Where(cl => cl.AddQuantity != 0).ToList())}");
}
else
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"交换完成", Duration = 4000 });
// 关闭弹窗
dialogService.Close(true);
}
//重置状态
this.RestData();
}
else
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Warning, Summary = "提示", Detail = $"无可交换数据或未输入交换数量", Duration = 4000 });
return;
}
}
async Task SelectedDrawerChange(object drawerNo)
{
if (drawerNo == "无库位")
{
return;
}
drawerNo = drawerNo == "急诊药盒" ? "99-1" : drawerNo == "恢复室药盒" ? "111-1" : drawerNo == "胃镜药盒" ? "31-1" : drawerNo == "导管药盒" ? "32-1" : drawerNo == "生殖药盒" ? "33-1" : drawerNo == "妇门药盒" ? "34-1" : drawerNo;
var result = await channelListDao.GetChannelStockByDrug(channelStock, drawerNo.ToString(), 8, 0);
selectedDrawerData = result.Desserts;
}
int currentCol = 0;
RadzenDataGrid<ChannelStock> grid;
void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args)
{
currentCol = args.Data.ColNo;
grid.EditRow(args.Data);
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
// this.BeforeQuantity = new int[9];
// this.AfterQuantity = new int[9];
// currentCol = 0;
// ColNos.Clear();
}
}

View File

@ -0,0 +1,225 @@
@page "/Box/BoxStock"
@using MasaBlazorApp3.Pojo.Config
<RadzenStack Orientation="Orientation.Horizontal" class="col-12 mb-4">
<div class="col-2 row justify-content-center align-items-center text-center">
<div class="row justify-content-around align-items-center" style="height:600px;overflow:auto">
@foreach (var cs in channelStockList)
{
<RadzenButton class="col-12" Style="margin-bottom:5px" Click="@(() => SelectDrawer((cs.DrawerNo.ToString() + "-" + cs.ColNo.ToString())))" Text="@(cs.DrawerNo==99?"急诊室药盒":cs.DrawerNo==111?"恢复室药盒":cs.DrawerNo==31?"胃镜药盒":cs.DrawerNo==32?"导管药盒":cs.DrawerNo==33?"生殖药盒":cs.DrawerNo==34?"妇门药盒":$"{cs.DrawerNo.ToString() + "-" + (cs.ColNo==1?'白':'绿')}")" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo != (cs.DrawerNo.ToString() + "-" + cs.ColNo.ToString()) ? Variant.Outlined : Variant.Flat)" />
}
</div>
</div>
<div class="col-10">
<RadzenDataList @ref="grid" LoadData="@LoadData" WrapItems="true" Count="@count" IsLoading="@isLoading" style="height:600px;overflow:auto"
Data="@_forecasts" PageSize="6" AllowPaging="false">
<Template Context="pd">
<RadzenCard Variant="Variant.Outlined" class="rz-p-0" Style="width: 100%;">
<RadzenRow Gap="0">
<RadzenColumn Size="10">
<div style="text-align: left;">
<div class="rz-text-h6 rz-mb-0">品名/规格/厂家</div>
@(pd._DrugInfo.DrugNameSpec)
</div>
@* <RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd._DrugInfo.ToString())</RadzenText> *@
</RadzenColumn>
@* <RadzenColumn Size="5">
厂家<br />
@(pd._DrugInfo.Manufactory)
</RadzenColumn> *@
@*<RadzenColumn Size="3">
规格<br />
@(pd._DrugInfo.DrugSpec)
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd._DrugInfo.DrugSpec)</RadzenText>
</RadzenColumn> *@
<RadzenColumn Size="1">
<div class="rz-text-h6 rz-mb-0">基数</div>
@(pd.BaseQuantity)
@* <RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd.BaseQuantity)</RadzenText> *@
</RadzenColumn>
<RadzenColumn Size="1">
<div class="rz-text-h6 rz-mb-0">库存</div>
@(pd.channelStocks.Sum(cs => cs.Quantity))
@* <RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd.channelStocks.Sum(cs => cs.Quantity))</RadzenText> *@
</RadzenColumn>
</RadzenRow>
@* <RadzenColumn Size="12" SizeLG="2" class="rz-p-4">
<RadzenButton Text="替换药品" Style="width: 100%" Click="@(() => replaceClick(pd))" />
</RadzenColumn>
<RadzenColumn Size="12" SizeLG="2" class="rz-p-4">
<RadzenButton Text="移出药品" Style="width: 100%" Click="@(()=>removeClick(pd))" />
</RadzenColumn> *@
@if (pd.channelStocks != null && pd.channelStocks.Count > 0)
{
for (int i = 0; i < pd.channelStocks.Count; i++)
{
var manuInfo = pd.channelStocks[i];
var manuNo = 1;
if (i == 0)
{
manuNo = 0;
}
<RadzenRow Gap="0">
<RadzenColumn Size="12">
@if (manuInfo != null && manuInfo.ManuNo != null)
{
<RadzenRow Gap="0">
<RadzenColumn Size="3">
@if (manuNo == 0)
{
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-mb-0">批次</RadzenText>
}
<RadzenText TextStyle="TextStyle.Body2">@(manuInfo.ManuNo)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="3">
@if (manuNo == 0)
{
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-mb-0">效期</RadzenText>
}
<RadzenText TextStyle="TextStyle.Body2">@(manuInfo.EffDate)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="1">
@if (manuNo == 0)
{
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-mb-0">库存</RadzenText>
}
<RadzenText TextStyle="TextStyle.Body2">@(manuInfo.Quantity)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="2">
<RadzenText style="margin-top:5px;"></RadzenText>
<RadzenButton Text="替换药品" Style="margin:1px" Click="@(() => replaceClick(manuInfo))" />
</RadzenColumn>
<RadzenColumn Size="2">
<RadzenText style="margin-top:5px;"></RadzenText>
<RadzenButton Text="移出药品" Click="@(() => removeClick(manuInfo))" />
</RadzenColumn>
</RadzenRow>
}
else
{
<RadzenRow Gap="0">
<RadzenColumn Size="5">
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-mb-0">未绑定批次</RadzenText>
</RadzenColumn>
</RadzenRow>
}
</RadzenColumn>
</RadzenRow>
}
}
</RadzenCard>
</Template>
</RadzenDataList>
</div>
</RadzenStack>
@code {
@inject IOrderInfoDao orderInfoDao;
@inject IChannelListDao channelListDao;
@inject DialogService dialogService;
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> setting;
@inject NotificationService _message
private IEnumerable<PlanDetails>? _forecasts;
bool allowRowSelectOnRowClick = true;
// IEnumerable<DrugManuNo> drugManuNos;
// IList<DrugManuNo> selectedDrugManuNos;
RadzenDataList<PlanDetails> grid;
// RadzenDataGrid<DrugManuNo> gridManuNo;
bool isLoading;
int count;
int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
List<ChannelStock> channelStockList = new();
int status = 0;
string drawerNo = "1-1";
string OrderNo;
DateTime OrderDate;
void SelectDrawer(string strDrawerNoColNo)
{
this.drawerNo = strDrawerNoColNo;
grid.Reload();
}
// void OnCurrentDateChanged(DateTime args)
// {
// OrderDate = new DateTime(args.Year, args.Month, args.Day);
// }
//重置
async Task reloadGrid()
{
OrderNo = "";
OrderDate = DateTime.MinValue;
await grid.Reload();
}
//确认
async Task Confirm()
{
// orderInfoDao.CheckOrderInfo(selectedOrderInfos, drawerNo);
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
var result = await channelListDao.GetBoxDrugInfo(drawerNo, args.Top, args.Skip);
// Update the Data property
_forecasts = result.Desserts;
// Update the count
count = result.TotalDesserts;
isLoading = false;
channelStockList = await orderInfoDao.GetDrawerNum(setting.Value.boxMachineId);
}
//替换按钮
async Task replaceClick(ChannelStock cs)
{
if (cs.Quantity > 0)
{
string message = cs.DrawerNo + "-" + (cs.ColNo == 1 ? "白" : "绿") + " 药盒替换药品详情";
var b = await dialogService.OpenAsync<BoxReplace>(
message,
new Dictionary<string, object>() { { "channelStock", cs } },
new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
await reloadGrid();
}
}
else
{
//库存为0无法操作
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"库存为0无法替换", Duration = 4000 }
);
}
}
//移除按钮
async Task removeClick(ChannelStock cs)
{
if (cs.Quantity > 0)
{
string message = cs.DrawerNo + "-" + (cs.ColNo == 1 ? "白" : "绿") + " 药盒移动药品详情";
var b = await dialogService.OpenAsync<BoxRemoveDialog>(
message,
new Dictionary<string, object>() { { "channelStock", cs } },
new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
await reloadGrid();
}
}
else
{
//库存为0无法操作
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"库存为0没有要移出的药品", Duration = 4000 }
);
}
}
}

View File

@ -0,0 +1,234 @@
@page "/Box/BoxStockAAA"
@using MasaBlazorApp3.Pojo.Config
<RadzenStack Orientation="Orientation.Horizontal" class="col-12 mb-4">
<div class="col-2 row justify-content-center align-items-center text-center">
<div class="row justify-content-around align-items-center" style="height:600px;overflow:auto">
@foreach (var cs in channelStockList)
{
<RadzenButton class="col-12" Style="margin-bottom:5px" Click="@(() => SelectDrawer((cs.DrawerNo.ToString() + "-" + cs.ColNo.ToString())))" Text="@(cs.DrawerNo==99?"急诊室药盒":cs.DrawerNo==111?"恢复室药盒":cs.DrawerNo==31?"胃镜药盒":cs.DrawerNo==32?"导管药盒":cs.DrawerNo==33?"生殖药盒":cs.DrawerNo==34?"妇门药盒":$"{cs.DrawerNo.ToString() + "-" + (cs.ColNo==1?'白':'绿')}")" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo != (cs.DrawerNo.ToString() + "-" + cs.ColNo.ToString()) ? Variant.Outlined : Variant.Flat)" />
}
</div>
</div>
<div class="col-10">
<RadzenDataGrid @ref="grid"
IsLoading="@isLoading"
RowRender="@RowRender"
EmptyText="无数据"
Data="@_forecasts"
AllowColumnResize="true" AllowAlternatingRows="false"
SelectionMode="DataGridSelectionMode.Single"
ExpandMode="DataGridExpandMode.Single">
<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="ManuNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="效期" Property="EffDate">
<Template Context="s">
@{
DateTime dateTime;
bool success = DateTime.TryParse(s.EffDate, out dateTime);
@s.EffDate
}
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="数量" Property="Quantity">
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</Template>
<Columns>
<RadzenDataGridColumn Frozen="true" Width="200px" Title="药品名称" Property="DrugName"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="规格" Property="DrugSpec"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="基数" Property="BoxBaseQuantity">
<Template Context="s">
@s.BoxBaseQuantity
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="总库存" Property="BoxBaseQuantity">
<Template Context="s">
@s.StockQuantity
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</div>
</RadzenStack>
@code {
@inject IOrderInfoDao orderInfoDao;
@inject IChannelListDao channelListDao;
@inject DialogService dialogService;
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> setting;
@inject NotificationService _message
@inject IDrugInfoDao drugInfoDao;
private IEnumerable<DrugInfo>? _forecasts;
bool allowRowSelectOnRowClick = true;
// IEnumerable<DrugManuNo> drugManuNos;
// IList<DrugManuNo> selectedDrugManuNos;
RadzenDataGrid<DrugInfo> grid;
// RadzenDataGrid<DrugManuNo> gridManuNo;
bool isLoading;
int count;
int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
List<ChannelStock> channelStockList = new();
int status = 0;
string drawerNo = "1-1";
string OrderNo;
DateTime OrderDate;
async Task SelectDrawer(string strDrawerNoColNo)
{
this.drawerNo = strDrawerNoColNo;
BoxModel boxModel = new BoxModel();
boxModel.BoxName = 1;
boxModel.BoxNo = 1;
// grid.Reload();
if (drawerNo != null)
{
string[] strArr = drawerNo.Split('-');
boxModel.BoxName = Convert.ToInt32(strArr[0]);
boxModel.BoxNo = Convert.ToInt32(strArr[1]);
}
var result = await drugInfoDao.GetAllDrugAndStockByBox(boxModel);
_forecasts = result;
}
// void OnCurrentDateChanged(DateTime args)
// {
// OrderDate = new DateTime(args.Year, args.Month, args.Day);
// }
//重置
async Task reloadGrid()
{
OrderNo = "";
OrderDate = DateTime.MinValue;
await grid.Reload();
}
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
isLoading = true;
BoxModel boxModel = new BoxModel();
boxModel.BoxName = 1;
boxModel.BoxNo = 1;
isLoading = true;
if (drawerNo != null)
{
string[] strArr = drawerNo.Split('-');
boxModel.BoxName = Convert.ToInt32(strArr[0]);
boxModel.BoxNo = Convert.ToInt32(strArr[1]);
}
var result = await drugInfoDao.GetAllDrugAndStockByBox(boxModel);// await channelListDao.GetBoxDrugInfo(drawerNo, args.Top, args.Skip);
// Update the Data property
_forecasts = result;
// Update the count
//count = result.TotalDesserts;
isLoading = false;
channelStockList = await orderInfoDao.GetDrawerNum(setting.Value.boxMachineId);
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;
}
//确认
async Task Confirm()
{
// orderInfoDao.CheckOrderInfo(selectedOrderInfos, drawerNo);
}
async Task LoadData(LoadDataArgs args)
{
BoxModel boxModel = new BoxModel();
boxModel.BoxName = 1;
boxModel.BoxNo = 1;
isLoading = true;
if (drawerNo != null)
{
string[] strArr = drawerNo.Split(',');
boxModel.BoxName = Convert.ToInt32(strArr[0]);
boxModel.BoxNo = Convert.ToInt32(strArr[1]);
}
var result = await drugInfoDao.GetAllDrugAndStockByBox(boxModel);// await channelListDao.GetBoxDrugInfo(drawerNo, args.Top, args.Skip);
// Update the Data property
_forecasts = result;
// Update the count
//count = result.TotalDesserts;
isLoading = false;
channelStockList = await orderInfoDao.GetDrawerNum(setting.Value.boxMachineId);
}
//替换按钮
async Task replaceClick(ChannelStock cs)
{
if (cs.Quantity > 0)
{
var b = await dialogService.OpenAsync<BoxReplace>(
$"{cs.DrawerNo}号药盒替换药品详情",
new Dictionary<string, object>() { { "channelStock", cs } },
new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
await reloadGrid();
}
}
else
{
//库存为0无法操作
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"库存为0无法替换", Duration = 4000 }
);
}
}
//移除按钮
async Task removeClick(ChannelStock cs)
{
if (cs.Quantity > 0)
{
var b = await dialogService.OpenAsync<BoxRemoveDialog>(
$"{cs.DrawerNo}号药盒替换药品详情",
new Dictionary<string, object>() { { "channelStock", cs } },
new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
await reloadGrid();
}
}
else
{
//库存为0无法操作
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"库存为0没有要移出的药品", Duration = 4000 }
);
}
}
}

View File

@ -0,0 +1,212 @@
@page "/Box/BoxStockAA"
@using MasaBlazorApp3.Pojo.Config
<RadzenStack Orientation="Orientation.Horizontal" class="col-12 mb-4">
<div class="col-2 row justify-content-center align-items-center text-center">
<div class="row justify-content-around align-items-center" style="height:600px;overflow:auto">
@foreach (var cs in channelStockList)
{
<RadzenButton class="col-12" Style="margin-bottom:5px" Click="@(() => SelectDrawer((cs.DrawerNo.ToString() + "-" + cs.ColNo.ToString())))" Text="@(cs.DrawerNo==99?"急诊室药盒":cs.DrawerNo==111?"恢复室药盒":cs.DrawerNo==31?"胃镜药盒":cs.DrawerNo==32?"导管药盒":cs.DrawerNo==33?"生殖药盒":cs.DrawerNo==34?"妇门药盒":$"{cs.DrawerNo.ToString() + "-" + (cs.ColNo==1?'白':'绿')}")" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo != (cs.DrawerNo.ToString() + "-" + cs.ColNo.ToString()) ? Variant.Outlined : Variant.Flat)" />
}
</div>
</div>
<div class="col-10">
<RadzenDataList @ref="grid" LoadData="@LoadData" WrapItems="true" Count="@count" IsLoading="@isLoading" style="height:600px;overflow:auto"
Data="@_forecasts" PageSize="6" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left"
ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
<Template Context="pd">
<RadzenCard Variant="Variant.Outlined" class="rz-p-0" Style="width: 100%;">
<RadzenRow Gap="0">
<RadzenColumn Size="2">
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd._DrugInfo.DrugName)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="5">
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd._DrugInfo.Manufactory)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="3">
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd._DrugInfo.DrugSpec)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="1">
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd.BaseQuantity)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="1">
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-color-on-secondary-lighter">@(pd.channelStocks.Sum(cs => cs.Quantity))</RadzenText>
</RadzenColumn>
</RadzenRow>
@* <RadzenColumn Size="12" SizeLG="2" class="rz-p-4">
<RadzenButton Text="替换药品" Style="width: 100%" Click="@(() => replaceClick(pd))" />
</RadzenColumn>
<RadzenColumn Size="12" SizeLG="2" class="rz-p-4">
<RadzenButton Text="移出药品" Style="width: 100%" Click="@(()=>removeClick(pd))" />
</RadzenColumn> *@
@if (pd.channelStocks != null && pd.channelStocks.Count > 0)
{
for (int i = 0; i < pd.channelStocks.Count; i++)
{
var manuInfo = pd.channelStocks[i];
var manuNo = 1;
if (i == 0)
{
manuNo = 0;
}
<RadzenRow Gap="0">
<RadzenColumn Size="12">
@if (manuInfo != null && manuInfo.ManuNo != null)
{
<RadzenRow Gap="0">
<RadzenColumn Size="3">
@if (manuNo == 0)
{
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-mb-0">批次</RadzenText>
}
<RadzenText TextStyle="TextStyle.Body2">@(manuInfo.ManuNo)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="3">
@if (manuNo == 0)
{
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-mb-0">效期</RadzenText>
}
<RadzenText TextStyle="TextStyle.Body2">@(manuInfo.EffDate)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="1">
@if (manuNo == 0)
{
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-mb-0">库存</RadzenText>
}
<RadzenText TextStyle="TextStyle.Body2">@(manuInfo.Quantity)</RadzenText>
</RadzenColumn>
<RadzenColumn Size="2">
<RadzenText style="margin-top:5px;"></RadzenText>
<RadzenButton Text="替换药品" Style="margin:1px" Click="@(() => replaceClick(manuInfo))" />
</RadzenColumn>
<RadzenColumn Size="2">
<RadzenText style="margin-top:5px;"></RadzenText>
<RadzenButton Text="移出药品" Click="@(() => removeClick(manuInfo))" />
</RadzenColumn>
</RadzenRow>
}
else
{
<RadzenRow Gap="0">
<RadzenColumn Size="5">
<RadzenText TextStyle="TextStyle.H6" TagName="TagName.H5" class="rz-mb-0">未绑定批次</RadzenText>
</RadzenColumn>
</RadzenRow>
}
</RadzenColumn>
</RadzenRow>
}
}
</RadzenCard>
</Template>
</RadzenDataList>
</div>
</RadzenStack>
@code {
@inject IOrderInfoDao orderInfoDao;
@inject IChannelListDao channelListDao;
@inject DialogService dialogService;
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> setting;
@inject NotificationService _message
private IEnumerable<PlanDetails>? _forecasts;
bool allowRowSelectOnRowClick = true;
// IEnumerable<DrugManuNo> drugManuNos;
// IList<DrugManuNo> selectedDrugManuNos;
RadzenDataList<PlanDetails> grid;
// RadzenDataGrid<DrugManuNo> gridManuNo;
bool isLoading;
int count;
int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
List<ChannelStock> channelStockList = new();
int status = 0;
string drawerNo = "1-1";
string OrderNo;
DateTime OrderDate;
void SelectDrawer(string strDrawerNoColNo)
{
this.drawerNo = strDrawerNoColNo;
grid.Reload();
}
// void OnCurrentDateChanged(DateTime args)
// {
// OrderDate = new DateTime(args.Year, args.Month, args.Day);
// }
//重置
async Task reloadGrid()
{
OrderNo = "";
OrderDate = DateTime.MinValue;
await grid.Reload();
}
//确认
async Task Confirm()
{
// orderInfoDao.CheckOrderInfo(selectedOrderInfos, drawerNo);
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
var result = await channelListDao.GetBoxDrugInfo(drawerNo, args.Top, args.Skip);
// Update the Data property
_forecasts = result.Desserts;
// Update the count
count = result.TotalDesserts;
isLoading = false;
channelStockList = await orderInfoDao.GetDrawerNum(setting.Value.boxMachineId);
}
//替换按钮
async Task replaceClick(ChannelStock cs)
{
if (cs.Quantity > 0)
{
var b = await dialogService.OpenAsync<BoxReplace>(
$"{cs.DrawerNo}号药盒替换药品详情",
new Dictionary<string, object>() { { "channelStock", cs } },
new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
await reloadGrid();
}
}
else
{
//库存为0无法操作
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"库存为0无法替换", Duration = 4000 }
);
}
}
//移除按钮
async Task removeClick(ChannelStock cs)
{
if (cs.Quantity > 0)
{
var b = await dialogService.OpenAsync<BoxRemoveDialog>(
$"{cs.DrawerNo}号药盒替换药品详情",
new Dictionary<string, object>() { { "channelStock", cs } },
new DialogOptions() { Width = "85vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
await reloadGrid();
}
}
else
{
//库存为0无法操作
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"库存为0没有要移出的药品", Duration = 4000 }
);
}
}
}

View File

@ -0,0 +1,341 @@
@page "/0"
@using MasaBlazorApp3.Pojo.Config;
@using MasaBlazorApp3.Pojo.Vo;
@using MasaBlazorApp3.Util;
@using Microsoft.Extensions.Options;
@using Newtonsoft.Json;
@using log4net;
<style>
.rz-dialog-content {
padding: 0 !important;
}
</style>
<RadzenRow Gap="0" Style="overflow: hidden;width:100%;height:100%">
<RadzenColumn Size="12" SizeMD="5">
<RadzenCard class="rz-shadow-0 rz-border-radius-0 rz-text-align-center rz-p-12 align-items-center justify-content-center" 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 (userI == 1)
{
<RadzenText TextStyle="TextStyle.H5" class="rz-color-white">
请交班操作人 @FromOperator?.NickName
<p>登录验证</p>
</RadzenText>
}
else if (userI == 2)
{
<RadzenText TextStyle="TextStyle.H5" class="rz-color-white">
请交班复核人 @FromRviewer?.NickName
<p>登录验证</p>
</RadzenText>
}
else
@if (userI == 3)
{
<RadzenText TextStyle="TextStyle.H5" class="rz-color-white">
请接班操作人 @ToOperator?.NickName
<p>登录验证</p>
</RadzenText>
}
else if (userI == 4)
{
<RadzenText TextStyle="TextStyle.H5" class="rz-color-white">
请接班复核人 @ToReviewer?.NickName
<p>登录验证</p>
</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">
<!--@onfocusin="@(() => Util.VirtualKeyboardHelper.ShowVirtualKeyboard())"-->
<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>
@if (userI > 2)
{
<div class="rz-form-row">
<label class="rz-label" for="remark">备注</label>
<div class="rz-form-input-wrapper">
<RadzenTextBox id="remark" @bind-Value="@remarks" Style="width:100%" />
</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>
@code {
@inject Radzen.DialogService dialogService;
@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(LoginDialog));
private int loginMode = 1;
private bool opFirst = true;
[Parameter] public int userI { get; set; }
Pojo.User FromOperator = new Pojo.User();
Pojo.User FromRviewer = new Pojo.User();
Pojo.User ToOperator = new Pojo.User();
Pojo.User ToReviewer = new Pojo.User();
HkcChangeShifts hkcChange = new HkcChangeShifts();
string remarks = string.Empty;
bool isShow;
private Pojo.User loginModel = new();
protected override Task OnInitializedAsync()
{
FingerprintUtil.axCZKEM1.OnAttTransactionEx += axCZKEM1_OnAttTransactionEx;
loginMode = setting.Value.loginMode;
opFirst = setting.Value.opFirst;
//查询当前值班信息
hkcChange = userDao.GetOnDuty();
if (hkcChange != null && !string.IsNullOrEmpty(hkcChange.FromOperator))
{
FromOperator = userDao.GetByUsername(hkcChange.FromOperator);
}
if (hkcChange != null && string.IsNullOrEmpty(hkcChange.FromRviewer))
{
FromRviewer = userDao.GetByUsername(hkcChange.FromRviewer);
}
return base.OnInitializedAsync();
}
private async Task SetUser(Pojo.User user)
{
if (userI == 1)
{
if(FromOperator.Id != user.Id)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"值班操作人有误,请核查当前值班人", Duration = 3000 }
);
return;
}
//交班人操作人登录
if (FromRviewer != null)
{
userI = 2;
}
else
{
userI = 3;
}
}
else if (userI == 2)
{
if (FromOperator != null && FromOperator.Id == user.Id)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"验证重复,请使用其他账号", Duration = 3000 }
);
return;
}
else
{
if(FromRviewer.Id!=user.Id)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"值班审核人有误,请核查当前值班人", Duration = 3000 }
);
return;
}
FromRviewer = user;
userI = 3;
}
}
else if (userI == 3)
{
if (loginMode == 2)
{
if (FromOperator.Id == user.Id || (FromRviewer != null && FromRviewer.Id == user.Id))
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"验证重复,请使用其他账号", Duration = 3000 }
);
return;
}
userI = 4;
ToOperator = user;
}
else
{
if (FromOperator.Id == user.Id || (FromRviewer != null && FromRviewer.Id == user.Id))
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"验证重复,请使用其他账号", Duration = 3000 }
);
return;
}
else
{
ToOperator = user;
//保存交接班信息
HkcChangeShifts hkcChangeNew = new HkcChangeShifts
{
FromOperator = ToOperator.Username,
optDate = DateTime.Now,
ToDate = DateTime.Now,
State = "0", //状态为1表示交接班完成
MachineId = hkcChange.MachineId,
Remarks = remarks
};
hkcChange.ToOperator = ToOperator.Username;
bool bResult = await userDao.UpdateChangeShift(hkcChange, hkcChangeNew);
if (bResult)
{
FingerprintUtil.axCZKEM1.OnAttTransactionEx -= axCZKEM1_OnAttTransactionEx;
logger.Info($"交接班完成,交班人{FromOperator.NickName};{FromRviewer?.NickName},接班人{ToOperator?.NickName};{ToOperator?.NickName}");
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"交接班完成", Duration = 3000 }
);
dialogService.Close(true);
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = "交接班保存数据失败", Duration = 3000 }
);
}
}
}
}
else if (userI == 4)
{
if (FromOperator.Id == user.Id || (FromRviewer != null && FromRviewer.Id == user.Id) || (ToOperator != null && ToOperator.Id == user.Id))
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"验证重复,请使用其他账号", Duration = 3000 }
);
return;
}
ToReviewer = user;
hkcChange.ToReviewer = ToReviewer?.Username;
//保存交接班信息
HkcChangeShifts hkcChangeNew = new HkcChangeShifts
{
FromOperator = ToOperator.Username,
FromRviewer = ToReviewer?.Username,
optDate = DateTime.Now,
State = "0", //状态为1表示交接班完成
MachineId = hkcChange.MachineId,
Remarks = remarks
};
bool bResult = await userDao.UpdateChangeShift(hkcChange, hkcChangeNew);
if (bResult)
{
FingerprintUtil.axCZKEM1.OnAttTransactionEx -= axCZKEM1_OnAttTransactionEx;
logger.Info($"交接班完成,交班人{FromOperator.NickName};{FromRviewer?.NickName},接班人{ToOperator?.NickName};{ToReviewer?.NickName}");
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"交接班完成", Duration = 3000 }
);
dialogService.Close(true);
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = "交接班保存数据失败", Duration = 3000 }
);
}
}
}
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);
loginModel.Username = "";
loginModel.Password = "";
}
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);
InvokeAsync(StateHasChanged);
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"系统中没有ID为【{sEnrollNumber}】的用户", Duration = 4000 }
);
logger.Info($"指纹机验证通过id为【{sEnrollNumber}】,但是华康数据库中无此用户");
}
}
private void Exit()
{
dialogService.Close(false);
}
}

View File

@ -0,0 +1,123 @@
@page "/stock/Change"
<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" @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" @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 Title="日期" Property="optDate">
<Template Context="mr">
@mr.optDate.ToString("yyyy-MM-dd")
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="交班发药人" Property="FromOperator"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="交班审核人" Property="FromRviewer"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="接班发药人" Property="ToOperator"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="接班审核人" Property="ToReviewer"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="接班日期" Property="ToDate">
<Template Context="mr">
@mr.ToDate.ToString("yyyy-MM-dd")
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="当班状态" Property="State">
<Template Context="state">
@if(state.State=="0")
{
<RadzenText>值班中</RadzenText>
}
else
{
<RadzenText>已交班</RadzenText>
}
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</div>
</div>
</div>
@code {
@inject IHkcChangeShiftsDao hkcChangeShiftsDao;
@inject DialogService dialogService;
@inject NavigationManager navigate;
RadzenDataGrid<HkcChangeShifts> grid;
bool isLoading;
int count;
private IEnumerable<HkcChangeShifts>? _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 hkcChangeShiftsDao.GetChangeShiftRecordAsync(start, end,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();
}
}

View File

@ -0,0 +1,522 @@
@page "/Box/CheckAAA"
@using MasaBlazorApp3.Pojo.Config
@using MasaBlazorApp3.Report
@using Microsoft.Extensions.Options
@using Radzen.Blazor.Rendering
@using log4net;
<style>
.my-popup {
display: none;
position: absolute;
overflow: auto;
/* height: 360px; */
width: 900px;
border: var(--rz-panel-border);
background-color: var(--rz-panel-background-color);
box-shadow: var(--rz-panel-shadow);
border-radius: var(--rz-border-radius);
}
.rz-grid-table {
position: relative;
border-collapse: separate;
border-spacing: 0;
}
</style>
<RadzenStack Orientation="Orientation.Horizontal">
@* <div class="col-4 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;overflow:auto">
@foreach (int i in DrawerNos)
{
<RadzenButton class="col-5" Style="margin-bottom:5px" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo != i ? Variant.Outlined : Variant.Flat)" />
}
</div>
</div> *@
@* <div class="col-2 row justify-content-center align-items-center text-center">
<div class="row justify-content-around align-items-center" style="height:600px;overflow:auto">
@foreach (int i in DrawerNos)
{
<RadzenButton class="col-12" Style="margin-bottom:5px" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo != i ? Variant.Outlined : Variant.Flat)" />
}
</div>
</div> *@
<div class="col-12">
<form onsubmit="@(() => {firstLod=0;grid.Reload();})">
<RadzenFieldset Text="查询">
@* <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem"> *@
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="6">
<RadzenLabel Text="麻醉医师" Component="NamesList" Style="width: 20%;" />
<RadzenDropDownDataGrid AllowVirtualization="true" Name="NamesList" TValue="Anaesthetist" Data="@NamesList" @bind-Value="NameInfo"
Style="width:100%; display: block;" AllowFilteringByAllStringColumns="true" TextProperty="Name">
<Columns>
<RadzenDropDownDataGridColumn Property="Name" Title="麻醉医师" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
</RadzenColumn>
<RadzenColumn Size="6">
<RadzenLabel Text="核对药箱" Component="BoxList" />
@* <RadzenDropDownDataGrid AllowVirtualization="true" Name="BoxColorList" TValue="Anaesthetist" Data="@BoxColorList" @bind-Value="BoxColor" Style="width: 100%;"
AllowFilteringByAllStringColumns="true" TextProperty="Name">
<Columns>
<RadzenDropDownDataGridColumn Property="Name" Title="药盒颜色" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid> *@
<RadzenDropDownDataGrid AllowVirtualization="true" Name="BoxList" TValue="BoxModel" Data="@BoxList" @bind-Value="BoxNum" Style="width: 100%;"
AllowFilteringByAllStringColumns="true" TextProperty="药箱号">
<Template>
@((context as BoxModel).BoxName == 99 ? "急诊药盒" : (context as BoxModel).BoxName == 111 ? "恢复室药盒" : (context as BoxModel).BoxName + "-" + ((context as BoxModel).BoxNo == 1 ? "白" : "绿"))
@* @((context as BoxModel).BoxName + "-" + (context as BoxModel).BoxNo) *@
</Template>
<Columns>
<RadzenDropDownDataGridColumn Property="BoxName" Title="药箱号" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
</RadzenColumn>
</RadzenRow>
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="6">
<RadzenLabel Text="处方号" Component="OrderNo" />
<RadzenTextBox @bind-Value="OrderNo" Style="width: 100%;" Name="OrderNo"></RadzenTextBox>
</RadzenColumn>
<RadzenColumn Size="6" Style="margin-top:0.5rem">
<RadzenLabel Text="处方时间" Component="OrderDate" />
<RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentDateChanged" AllowClear @bind-Value="OrderDate" Style="width: 100%;" Name="OrderDate" />
</RadzenColumn>
</RadzenRow>
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="6">
<RadzenLabel Text="患者姓名" Component="PatientName" />
<RadzenTextBox @bind-Value="PatientName" Style="width: 100%;" Name="PatientName"></RadzenTextBox>
</RadzenColumn>
<RadzenColumn Size="6" Style="margin-top:2px">
<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="Confirm" ButtonType="ButtonType.Button" IsBusy="isLoading" Icon="check_circle" Text="确认" />
<RadzenButton Style="margin-top:2px" Icon="download" @ref=button Text="麻醉药品使用登记本导出" Variant="Variant.Outlined" Click="@(args => popup.ToggleAsync(button.Element))" />
<Popup @ref=popup Lazy=true class="my-popup">
<RadzenStack Orientation="Orientation.Vertical" Gap="1rem" class="rz-h-100 rz-p-4">
<RadzenFieldset Text="条件选择">
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="6">
<RadzenLabel Text="处方时间" Component="PortOrderDate" />
</RadzenColumn>
<RadzenColumn Size="6">
<RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentPortDateChanged" @bind-Value="PortOrderDate" Style="width: 100%;" Name="PortOrderDate" />
</RadzenColumn>
</RadzenRow>
<RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
<RadzenButton Icon="download" Text="导出" Variant="Variant.Outlined" Click="StockExport" />
</RadzenRow>
</RadzenStack>
</RadzenFieldset>
</RadzenStack>
</Popup>
</RadzenColumn>
</RadzenRow>
@* </RadzenStack> *@
</RadzenFieldset>
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" Style="margin:0.5rem">
@* <RadzenLabel Text="核对药箱" Component="BoxList" Style="margin:0.5rem" />
<RadzenDropDownDataGrid AllowVirtualization="true" Name="BoxList" TValue="BoxModel" Data="@BoxList" @bind-Value="BoxNum"
AllowFilteringByAllStringColumns="true" TextProperty="药箱号">
<Template>
@((context as BoxModel).BoxName + "-" + (context as BoxModel).BoxNo)
</Template>
<Columns>
<RadzenDropDownDataGridColumn Property="BoxName" Title="药箱号" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid> *@
@* <RadzenButton Size="ButtonSize.Medium" Click="Confirm" ButtonType="ButtonType.Button" IsBusy="isLoading" Icon="check_circle" Text="确认" />
<RadzenButton Icon="download" @ref=button Text="麻醉药品使用登记本导出" Variant="Variant.Outlined" Click="@(args => popup.ToggleAsync(button.Element))" />
<Popup @ref=popup Lazy=true class="my-popup">
<RadzenStack Orientation="Orientation.Vertical" Gap="1rem" class="rz-h-100 rz-p-4">
<RadzenFieldset Text="条件选择">
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="6">
<RadzenLabel Text="处方时间" Component="PortOrderDate" />
</RadzenColumn>
<RadzenColumn Size="6">
<RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentPortDateChanged" @bind-Value="PortOrderDate" Style="width: 100%;" Name="PortOrderDate" />
</RadzenColumn>
</RadzenRow>
<RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
<RadzenButton Icon="download" Text="导出" Variant="Variant.Outlined" Click="StockExport" />
</RadzenRow>
</RadzenStack>
</RadzenFieldset>
</RadzenStack>
</Popup> *@
</RadzenStack>
</form>
<div Style="width:936px;height:50vh;overflow:auto">
<RadzenDataGrid @ref="grid" AllowRowSelectOnRowClick="@allowRowSelectOnRowClick" AllowFiltering="true" LoadData="@LoadData" Style="width:955px;overflow:auto" Groupable="true"
FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
Data="@orderInfos" IsLoading="@isLoading" Count="@count" EmptyText="无数据"
SelectionMode="DataGridSelectionMode.Multiple" @bind-Value=@selectedOrderInfos
CellClick="@((DataGridCellMouseEventArgs<OrderInfo> args) => OnCellClick(args))"
AllowPaging="false">
<Columns>
<RadzenDataGridColumn Sortable="false" Filterable="false" Width="2rem">
@* <HeaderTemplate>
<RadzenCheckBox TabIndex="-1" TriState="false" TValue="bool?" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select all items" } })"
Value="@(selectedOrderInfos == null || selectedOrderInfos?.Any() != true ? false : !orderInfos.All(i => selectedOrderInfos.Contains(i)) ? null : orderInfos.Any(i => selectedOrderInfos.Contains(i)))"
Change="@(args => OnCheckSeleced(args))" />
</HeaderTemplate> *@
<Template Context="data">
<RadzenCheckBox TabIndex="-1" TriState="false" Value="@data.ItemIsChecked" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select item" } })"
TValue="bool" Change="@(args => { if (!allowRowSelectOnRowClick) { grid.SelectRow(data); } })" />
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="anaesthetistName" Title="麻醉医师" Sortable="false" Filterable="false" Width="50px" />
<RadzenDataGridColumn Property="PatientName" Title="姓名" Sortable="false" Filterable="false" Width="50px" />
<RadzenDataGridColumn Property="Sex" Title="性别" Sortable="false" Filterable="false" Width="30px" />
<RadzenDataGridColumn Property="OrderNo" Title="单号" Sortable="false" Filterable="false" Width="70px" />
<RadzenDataGridColumn Property="ChargeDate" Title="处方时间" Sortable="false" Filterable="false" Width="80px" />
<RadzenDataGridColumn Property="DetailInfo.Drug.DrugName" Title="药品名称" FormatString="{0:d}" Sortable="false" Filterable="false" Width="80px" />
@* <Template Context="DetailInfo">
@for (int i = 0; i < DetailList.DetailList.Count; i++)
{
OrderDetail orderDetail = DetailList.DetailList[i]; *@
@* <RadzenText TextStyle="TextStyle.Subtitle2" class="rz-mb-0">@DetailInfo.Drug.DrugName</RadzenText>
}
</Template>
</RadzenDataGridColumn>*@
@* <RadzenDataGridColumn Property="Detail.SetManuNo" Title="药品批次" Sortable="false" Filterable="false" Width="8rem">
<Template Context="DetailList">
@for (int i = 0; i < DetailList.DetailList.Count; i++)
{
OrderDetail orderDetail = DetailList.DetailList[i];
<RadzenText TextStyle="TextStyle.Subtitle2" class="rz-mb-0">@orderDetail.SetManuNo</RadzenText>
}
</Template>
</RadzenDataGridColumn> *@
<RadzenDataGridColumn Title="批次" Property="DetailInfo.SetManuNo" Filterable="false" Width="100px">
@* <Template Context="DetailInfo">
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@DetailInfo.DetailInfo.SetManuNo</RadzenText>
@if (DetailInfo.DetailInfo.SetManuNo != null )
{
<RadzenText TextStyle="TextStyle.Caption">
@DetailInfo.DetailInfo.SetManuNo
</RadzenText>
}
</Template> *@
<EditTemplate Context="DetailInfo">
<RadzenDropDown TValue="DrugManuNo" Name="ManuNo" @bind-Value="DetailInfo.DetailInfo.drugManuNo" Data="DetailInfo.DetailInfo.Drug.Manus" Style="width:100%; display: block;">
<Template>
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
}
else
{
<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>
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
}
else
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
}
</RadzenStack>
</ValueTemplate>
</RadzenDropDown>
<RadzenRequiredValidator Text="请选择批次" Component="ManuNo" Popup="true" />
</EditTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="DetailInfo.Quantity" Title="数量" Filterable="false" Width="50px">
<EditTemplate Context="DetailInfo">
<RadzenNumeric Min="0" Style="display: block" Name="Quantity" @bind-Value=@DetailInfo.DetailInfo.Quantity />
<RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Text="请填写正确的添加数量" Component="Quantity" Popup="true" />
</EditTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="DetailInfo.TotalQuantity" Title="合计" Filterable="false" Width="50px" />
</Columns>
</RadzenDataGrid>
</div>
</div>
</RadzenStack>
@code {
private readonly ILog logger = LogManager.GetLogger(typeof(CheckOrder));
@inject IOrderInfoDao orderInfoDao;
@inject DialogService dialogService;
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> setting;
@inject NotificationService _message;
@inject IReportDataDao reportDataDao;
@inject IOptions<SettingConfig> setting;
bool allowRowSelectOnRowClick = true;
IEnumerable<OrderInfo> orderInfos;
IList<OrderInfo> selectedOrderInfos;
RadzenDataGrid<OrderInfo> grid;
//麻醉师集合
List<Anaesthetist> NamesList = new List<Anaesthetist>();
Anaesthetist NameInfo;
Anaesthetist BoxColor;
//药盒集合
List<BoxModel> BoxList = new List<BoxModel>();
//药盒颜色集合
List<Anaesthetist> BoxColorList = new List<Anaesthetist>();
BoxModel BoxNum;
bool isLoading;
int count;
int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int status = 0;
string OrderNo;
string PatientName;
DateTime? OrderDate = null;
DateTime PortOrderDate = DateTime.Now;
Popup popup;
RadzenButton button;
//第一次加载不执行LoadData方法
int firstLod = 1;
void OnCheckSeleced(object dete)
{
if (orderInfos != null)
{
orderInfos.ToList().ForEach(it => it.ItemIsChecked = true);
}
}
void OnCurrentDateChanged(DateTime args)
{
OrderDate = new DateTime(args.Year, args.Month, args.Day);
}
void OnCurrentPortDateChanged(DateTime args)
{
PortOrderDate = new DateTime(args.Year, args.Month, args.Day);
}
// async Task OnColorChange(object value)
// {
// Anaesthetist v = value as Anaesthetist;
// if (v.Id != BoxColor.Id)
// {
// BoxList = await orderInfoDao.GetOperationNum(BoxColor.Id);// await orderInfoDao.GetDrawerNumByOperationNum(setting.Value.boxMachineId, roomNameList); //roomNameList.Select(it => new BoxModel { BoxName = it, BoxNo = Convert.ToInt32(it.Substring(it.Length - 2, 2)) }).ToList();
// BoxNum = BoxList.FirstOrDefault();
// }
// }
//重置
async Task reloadGrid()
{
OrderNo = "";
OrderDate = DateTime.MinValue;
firstLod = 1;
await grid.Reload();
}
void OnCellClick(DataGridCellMouseEventArgs<OrderInfo> args)
{
if (args.Data.DetailInfo.SetManuNo != null)
{
args.Data.DetailInfo.drugManuNo = args.Data.DetailInfo.Drug.Manus.Where(m => m.ManuNo == args.Data.DetailInfo.SetManuNo).FirstOrDefault();
}
if (args.Data.DetailInfo.drugManuNo == null)
{
args.Data.DetailInfo.drugManuNo = args.Data.DetailInfo.Drug.Manus.FirstOrDefault();
}
args.Data.ItemIsChecked = !args.Data.ItemIsChecked;
grid.EditRow(args.Data);
}
//确认
async Task Confirm()
{
if (selectedOrderInfos == null)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择处方", Duration = 4000 }
);
return;
}
if (BoxNum == null)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择药箱", Duration = 4000 }
);
return;
}
if (selectedOrderInfos.Any(it => it.DetailInfo.drugManuNo == null && (string.IsNullOrEmpty(it.DetailInfo.SetManuNo))))
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择批次信息", Duration = 4000 }
);
return;
}
selectedOrderInfos.Where(oi => oi.DetailInfo.drugManuNo != null && !string.IsNullOrEmpty(oi.DetailInfo.drugManuNo.ManuNo)).ToList().ForEach(oi => oi.DetailInfo.SetManuNo = oi.DetailInfo.drugManuNo.ManuNo);
selectedOrderInfos.Where(oi => !string.IsNullOrEmpty(oi.DetailInfo.SetManuNo)).ToList().ForEach(oi => oi.DetailInfo.drugManuNo = new() { ManuNo = oi.DetailInfo.SetManuNo });
//弹出药品合计信息,确认无误后进行核对,取消则不核对
//弹出确认提示框
// var b = await dialogService.OpenAsync<CheckOrderConfirmDialog>(
// $"核对确认",
// new Dictionary<string, object>() { { "selectedOrderInfos", selectedOrderInfos } },
// new DialogOptions() { Width = "80vw", Resizable = true, Draggable = true, ShowClose = false });
// if (b)
// {
bool bResult = await orderInfoDao.CheckOrderInfo(selectedOrderInfos, BoxNum);
if (bResult)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"处方已核对完成", Duration = 4000 }
);
//await GetInitialDate();
await grid.Reload();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"处方已核对失败", Duration = 4000 }
);
}
// }
}
PageData<OrderInfo> result;
protected override async Task OnInitializedAsync()
{
BoxColorList = setting.Value.boxColor.Split(',').Select(it => new Anaesthetist { Name = it,Id=it=="白"?1:2 }).ToList();
BoxColor = BoxColorList.FirstOrDefault();
NamesList = setting.Value.anaesthetist_name.Split(',').Select(it => new Anaesthetist { Name = it }).ToList();
NameInfo = NamesList.FirstOrDefault();
BoxList = await orderInfoDao.GetOperationNum(0);// await orderInfoDao.GetDrawerNumByOperationNum(setting.Value.boxMachineId, roomNameList); //roomNameList.Select(it => new BoxModel { BoxName = it, BoxNo = Convert.ToInt32(it.Substring(it.Length - 2, 2)) }).ToList();
BoxNum = BoxList.FirstOrDefault();
//await GetInitialDate();
await base.OnInitializedAsync();
}
async Task LoadData(LoadDataArgs args)
{
if (firstLod == 1)
{
return;
}
// BoxList=BoxList.Where(bl => bl.BoxNo == BoxColor.Id).ToList();
// BoxNum = BoxList.FirstOrDefault();
string? anaesthetistName = NameInfo.Name == "未选择" ? null : NameInfo.Name;
string? roomName = BoxNum == null ? "" : setting.Value.roomName + BoxNum.BoxName.ToString().PadLeft(2, '0');
result = await orderInfoDao.GetAllOrderInfo(anaesthetistName, roomName, PatientName, OrderNo, OrderDate, args.Top, args.Skip);
isLoading = true;
orderInfos = result.Desserts;
count = result.TotalDesserts;
// if (result != null)
// {
// isLoading = true;
// orderInfos = result.Desserts;
// // Update the count
// count = result.TotalDesserts;
// logger.Info($"LoadData:{DateTime.Now},{orderInfos.Count()}");
// // Update the Data property
// if (Name != null)
// {
// orderInfos = orderInfos.Where(it => it.anaesthetistName == Name.Name);
// logger.Info($"LoadData:{DateTime.Now},{orderInfos.Count()}Name{Name.Name}");
// count = orderInfos.Count();
// }
// if (OrderDate != null && OrderDate != DateTime.MinValue)
// {
// orderInfos = orderInfos.Where(it => it.ChargeDate.Date >= OrderDate.Value.Date);
// logger.Info($"LoadData:{DateTime.Now},{orderInfos.Count()}");
// // Update the count
// count = orderInfos.Count();
// }
// if (!string.IsNullOrEmpty(OrderNo))
// {
// orderInfos = orderInfos.Where(it => it.OrderNo.Contains(OrderNo));
// logger.Info($"LoadData:{DateTime.Now},{orderInfos.Count()}-OrderNo{OrderNo}");
// // Update the count
// count = orderInfos.Count();
// }
// if (Name != null && OrderDate != null && OrderDate != DateTime.MinValue && !string.IsNullOrEmpty(OrderNo))
// {
// orderInfos = orderInfos.Where(it => it.anaesthetistName == Name.Name && it.ChargeDate.Date == OrderDate.Value.Date && it.OrderNo.Contains(OrderNo));
// logger.Info($"LoadData:{DateTime.Now},{orderInfos.Count()}");
// // Update the count
// count = orderInfos.Count();
// }
// if (BoxNum != null&&BoxNum.BoxName!=99&&BoxNum.BoxName!=111)
// {
// string roomName = setting.Value.roomName + BoxNum.BoxName.ToString().PadLeft(2, '0');
// orderInfos = orderInfos.Where(it => it.RoomName == roomName);
// logger.Info($"LoadData:{DateTime.Now},{orderInfos.Count()}roomName{roomName}");
// count = orderInfos.Count();
// }
// logger.Info($"LoadData结束:{DateTime.Now},{orderInfos.Count()}");
// orderInfos = orderInfos.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
// logger.Info($"LoadData结束:{DateTime.Now},{orderInfos.Count()} -{args.Skip.Value}-{args.Top.Value}");
// await InvokeAsync(StateHasChanged);
// //查找该麻醉师对应的手术室
// //List<string> roomNameList = orderInfos.Select(it => it.RoomName).Distinct().ToList();
// // List<int> roomNameList = orderInfos.Select(it => Convert.ToInt32(it.RoomName.Substring(6, it.RoomName.Length - 6))).Distinct().ToList();
// // BoxList = await orderInfoDao.GetDrawerNumByOperationNum(setting.Value.boxMachineId, roomNameList); //roomNameList.Select(it => new BoxModel { BoxName = it, BoxNo = Convert.ToInt32(it.Substring(it.Length - 2, 2)) }).ToList();
// // BoxNum = BoxList.FirstOrDefault();
isLoading = false;
// }
}
//麻醉药品使用登记本导出
async Task StockExport()
{
if (PortOrderDate == DateTime.MinValue)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择处方时间再导出", Duration = 4000 }
);
return;
}
List<ReportUsageDateInfo> pageData = await reportDataDao.GetOrderInfoData(PortOrderDate);
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("PortOrderDate", pageData);
GridReportUtil.PrintReport("Usage_Temp.grf", parameters);
}
// protected override async Task OnInitializedAsync()
// {
// await base.OnInitializedAsync();
// // orderInfos = dbContext.Employees;
// var result = await orderInfoDao.GetAllOrderInfo(OrderNo, OrderDate, args.Top, args.Skip);
// // Update the Data property
// orderInfos = result.Desserts;
// // Update the count
// count = result.TotalDesserts;
// isLoading = false;
// }
}

View File

@ -0,0 +1,357 @@
@using MasaBlazorApp3.Pojo.Config
@using MasaBlazorApp3.Util
@using MasaBlazorApp3.Pojo.Vo;
@using Microsoft.Extensions.Options
@using log4net;
<RadzenStack>
<div Style="width:100%;height:70vh;overflow:auto">
@* <RadzenListBox AllowClear="true" @bind-Value=@listBoxSelectedcsList Style="width:50vw;overflow:auto" AllowFiltering="false"
Data=@csList>
<Template Context="contextDate">
<RadzenStack Orientation="Orientation.Horizontal">
<RadzenText Style="width:20vw;text-align:left">@contextDate.Drug.DrugName</RadzenText>
<RadzenText Style="width:10vw">@contextDate.ManuNo</RadzenText>
<RadzenStack Gap="10" Style="text-align:right">
<div style="text-align: center;">
@if (contextDate.ReturnDrawerChanneStock != null && contextDate.ReturnDrawerChanneStock.ReturnQuantity>0)
{
<div style="text-align: center;">
还药库位【@contextDate.ReturnDrawerChanneStock?.DrawerNo】还药数【contextDate.ReturnDrawerChanneStock?.ReturnQuantity】< br />
</div>
}
@if (contextDate.OrderList.fore > 0)
{
<div style="text-align: center;">
空瓶库位【@contextDate.EmptyStock】空瓶数【@contextDate.EmptyQuantity】< br />
</div>
}
</div>
</RadzenStack>
<RadzenStack Gap="10" Style="text-align:right">
<div style="text-align: center;">
基数【@contextDate.BaseQuantity】<br />
库存数【@contextDate.Quantity】<br />
用药数【@contextDate.UseQuantity】<br />
处方数【@contextDate.OrderQuantity】<br />
空瓶数【@contextDate.EmptyQuantity】<br />
</div>
</RadzenStack>
</RadzenStack>
</Template>
</RadzenListBox> *@
<RadzenListBox AllowClear="true" @bind-Value=@listBoxSelectedcsList Style="width:100%;overflow:auto" AllowFiltering="false" TValue="ChannelStock"
Data=@csList>
<Template>
<RadzenStack Orientation="Orientation.Horizontal">
<RadzenText Style="width:20vw;text-align:left">@((context as ChannelStock).Drug.ToString())</RadzenText>
<RadzenText Style="width:10vw">@((context as ChannelStock).ManuNo)</RadzenText>
<RadzenStack Gap="10" Style="text-align:right">
<div style="text-align: center;">
@if (((context as ChannelStock).DrawerChanneStockList) != null && ((context as ChannelStock).DrawerChanneStockList.Count) > 0)
{
for (int i = 0; i < (context as ChannelStock).DrawerChanneStockList.Count; i++)
{
<div style="text-align: center;">
还药品库位【@((context as ChannelStock).DrawerChanneStockList[i].Location)】还药数【@((context as ChannelStock).DrawerChanneStockList[i].ReturnQuantity)】
</div>
}
}
@if ((context as ChannelStock).EmptyQuantity > 0)
{
<div style="text-align: center;">
还空瓶库位【@((context as ChannelStock).EmptyStock.Location)】空瓶数【@((context as ChannelStock).EmptyStock.ReturnQuantity)】
</div>
}
</div>
</RadzenStack>
<RadzenStack Gap="10" Style="text-align:right">
<div style="text-align: center;">
基数【@((context as ChannelStock).BaseQuantity)】<br />
@* 总库存【@((context as ChannelStock).TotalQuantity)】<br /> *@
库存数【@((context as ChannelStock).Quantity)】<br />
用药数【@((context as ChannelStock).UseQuantity)】<br />
处方数【@((context as ChannelStock).OrderQuantity)】<br />
空瓶数【@((context as ChannelStock).EmptyQuantity)】<br />
</div>
</RadzenStack>
</RadzenStack>
</Template>
</RadzenListBox>
</div>
<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" /> *@
@if (status < 2)
{
<RadzenButton Click="@OpenDrawer" 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="@Cancel" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
}
</RadzenStack>
</RadzenStack>
@code {
@inject Radzen.DialogService dialogService;
@inject IOptions<DrawerConfig> setting;
@inject PortUtil PortUtil;
@inject NotificationService _message;
@inject IOrderInfoDao orderInfoDao;
[Parameter] public IList<ChannelStock> csList { get; set; }
List<OrderDetail> orderDetailList = new();
ChannelStock listBoxSelectedcsList = new();
private readonly ILog logger = LogManager.GetLogger(typeof(OrderDetailDialog));
int status;
List<OrderTakeVo> data = new();
//计数取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// //取药数量小于库存
// tempData.Add(new OrderTakeVo()
// {
// Drug = detail.Drug,
// OrderDetail = detail,
// ChannelStock = stock,
// StockQuantity = total,
// Quantity = Quantity,
// });
protected override async Task OnInitializedAsync()
{
for (int i = 0; i < csList.Count; i++)
{
if (csList[i].EmptyStock != null && csList[i].EmptyStock.ReturnQuantity > 0)
{
data.Add(new OrderTakeVo()
{
ChannelStock = csList[i].EmptyStock
});
}
if (csList[i].DrawerChanneStockList != null && csList[i].DrawerChanneStockList.Count > 0)
{
for (int j = 0; j < csList[i].DrawerChanneStockList.Count; j++)
{
data.Add(new OrderTakeVo()
{
ChannelStock = csList[i].DrawerChanneStockList[j]
});
}
}
}
base.OnInitializedAsync();
}
// async Task ConfirmOK()
// {
// // 关闭弹窗
// dialogService.Close(true);
// }
async Task OpenDrawer()
{
this.status = 1;
await Task.Delay(200);
// 解析需要打开的抽屉列表
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;
var drawerType = orderTakeVo.ChannelStock.DrawerType;
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.speechSynthesizer.SpeakAsyncCancelAll();
if (drawerType==1)
{
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,环药");
}
else
{
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,环空瓶");
}
orderTakeVo.Status = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
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;
if (options._data == drawerNos.Count - 1)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"抽屉关闭,请,点击完成按钮进行确认");
this.status = 2;
string alertMessage = string.Empty;
//检查是否称重抽屉,核对实际取出数量是否与应取数量一致,不一致则弹出提示
for (int i = 0; i < data.Count; i++)
{
if (data[i].ChannelStock.BoardType.ToString().Contains("2"))
{
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)}】");
WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = orderTakeVo.BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
{
alertMessage += $"{data[i].Drug.DrugName}应取数量【{orderTakeVo.Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
}
}
}
if (!string.IsNullOrEmpty(alertMessage))
{
//弹出确认对话框
alertMessage += "应取数与实际取出数不一致确认要保存吗?";
//弹出确认提示框
var confirm = await dialogService.OpenAsync<ConfirmDialog>(
$"保存确认",
new Dictionary<string, object>() { { "confirmInfo", alertMessage } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
logger.Info(alertMessage);
if (!confirm)
{
RestData();
logger.Info("取消保存");
// 关闭弹窗
dialogService.Close(false);
}
}
stop();
}
else
{
options._data += 1;
next();
}
}
else
{
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))
{
}
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
data.ForEach(it =>
{
it.Status = 0;
it.BeforeQuantity = new int[9];
it.AfterQuantity = new int[9];
});
this.WeightFinnalQuantity = new int[9];
}
void Cancel()
{
RestData();
// 关闭弹窗
dialogService.Close(false);
}
async Task TakeFinish()
{
// 保存账册、操作记录
bool bResult = await orderInfoDao.CheckOrderInfoByChannelStock(csList.ToList(), null);
if (bResult)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"处方已核对完成", Duration = 4000 }
);
// 关闭弹窗
dialogService.Close(true);
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"处方核对失败", Duration = 4000 }
);
}
//重置状态
this.RestData();
}
}

View File

@ -0,0 +1,253 @@
@page "/Box/OrderImport"
@using MasaBlazorApp3.Pojo.Config
@using MasaBlazorApp3.Report
@using Microsoft.Extensions.Options
@using Radzen.Blazor.Rendering
@using log4net;
<style>
.rz-grid-table {
position: relative;
border-collapse: separate;
border-spacing: 0;
}
</style>
<RadzenStack Orientation="Orientation.Horizontal">
<div class="col-12">
<form onsubmit="@(() => {grid.Reload();})">
<RadzenFieldset Text="查询">
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="6">
<RadzenLabel Text="处方号" Component="OrderNo" />
<RadzenTextBox @bind-Value="OrderNo" Style="width: 100%;" Name="OrderNo"></RadzenTextBox>
</RadzenColumn>
<RadzenColumn Size="6" Style="margin-top:0.5rem">
<RadzenLabel Text="处方时间" Component="OrderDate" />
<RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentDateChanged" @bind-Value="OrderDate" Style="width: 100%;" Name="OrderDate" />
</RadzenColumn>
</RadzenRow>
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="6">
<RadzenLabel Text="患者姓名" Component="PatientName" />
<RadzenTextBox @bind-Value="PatientName" Style="width: 100%;" Name="PatientName"></RadzenTextBox>
</RadzenColumn>
<RadzenColumn Size="6" Style="margin-top:4vh">
<RadzenButton Size="ButtonSize.Medium" ButtonType="ButtonType.Submit" IsBusy="isLoading" Icon="search" Text="查询" />
<RadzenButton Size="ButtonSize.Medium" Click="Confirm" ButtonType="ButtonType.Button" ButtonStyle="ButtonStyle.Warning" IsBusy="isLoading" Icon="input" Text="导入" />
<RadzenButton Click="@((args) => dialogService.Close(false))" Variant="Variant.Flat" ButtonStyle="ButtonStyle.Secondary" Text="取消" />
</RadzenColumn>
</RadzenRow>
</RadzenFieldset>
</form>
<div Style="width:75vw;height:50vh;overflow:auto">
<RadzenDataGrid @ref="grid" AllowRowSelectOnRowClick="@allowRowSelectOnRowClick" AllowFiltering="true" LoadData="@LoadData" Style="width:75vw;overflow:auto" Groupable="true"
FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
Data="@orderInfos" IsLoading="@isLoading" Count="@count" EmptyText="无数据"
SelectionMode="DataGridSelectionMode.Multiple"
@bind-Value="@(selectedOrderInfos)"
CellClick="@((DataGridCellMouseEventArgs<OrderInfo> args) => OnCellClick(args))"
AllowPaging="false">
<Columns>
<RadzenDataGridColumn Sortable="false" Filterable="false" Width="4rem">
@* <HeaderTemplate>
<RadzenCheckBox TabIndex="-1" TriState="false" TValue="bool?" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select all items" } })"
Value="@(selectedOrderInfos == null || selectedOrderInfos?.Any() != true ? false : !orderInfos.All(i => selectedOrderInfos.Contains(i)) ? null : orderInfos.Any(i => selectedOrderInfos.Contains(i)))"
Change="@(args => OnCheckSeleced(args))" />
</HeaderTemplate>
<Template Context="data">
<RadzenCheckBox TabIndex="-1" TriState="false" Value="@data.ItemIsChecked" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select item" } })"
TValue="bool" Change="@(args => { if (!allowRowSelectOnRowClick) { grid.SelectRow(data); } })" />
</Template> *@
<HeaderTemplate>
<RadzenCheckBox TabIndex="-1" TriState="false" TValue="bool?" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select all items" } })"
Value="@(selectedOrderInfos == null || selectedOrderInfos?.Any() != true ? false : !orderInfos.All(i => selectedOrderInfos.Contains(i)) ? null : orderInfos.Any(i => selectedOrderInfos.Contains(i)))"
Change="@(args => selectedOrderInfos = args == true ? orderInfos.ToList() : null)" />
</HeaderTemplate>
<Template Context="data">
<RadzenCheckBox TabIndex="-1" TriState="false"
Value="@(selectedOrderInfos != null &&selectedOrderInfos.Contains(data))"
InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select item" } })"
TValue="bool" />
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="anaesthetistName" Title="麻醉医师" Sortable="false" Filterable="false" Width="8vw" />
<RadzenDataGridColumn Property="PatientName" Title="姓名" Sortable="false" Filterable="false" Width="8vw" />
<RadzenDataGridColumn Property="Sex" Title="性别" Sortable="false" Filterable="false" Width="6vw" />
<RadzenDataGridColumn Property="OrderNo" Title="单号" Sortable="false" Filterable="false" Width="13vw" />
@* <RadzenDataGridColumn Property="ChargeDate" Title="处方时间" Sortable="false" Filterable="false" Width="10vw" /> *@
<RadzenDataGridColumn Property="DetailInfo.Drug.DrugName" Title="药品名称" FormatString="{0:d}" Sortable="false" Filterable="false" Width="20vw" />
@* <Template Context="DetailInfo">
@for (int i = 0; i < DetailList.DetailList.Count; i++)
{
OrderDetail orderDetail = DetailList.DetailList[i]; *@
@* <RadzenText TextStyle="TextStyle.Subtitle2" class="rz-mb-0">@DetailInfo.Drug.DrugName</RadzenText>
}
</Template>
</RadzenDataGridColumn>*@
@* <RadzenDataGridColumn Property="Detail.SetManuNo" Title="药品批次" Sortable="false" Filterable="false" Width="8rem">
<Template Context="DetailList">
@for (int i = 0; i < DetailList.DetailList.Count; i++)
{
OrderDetail orderDetail = DetailList.DetailList[i];
<RadzenText TextStyle="TextStyle.Subtitle2" class="rz-mb-0">@orderDetail.SetManuNo</RadzenText>
}
</Template>
</RadzenDataGridColumn> *@
<RadzenDataGridColumn Title="批次" Property="DetailInfo.SetManuNo" Filterable="false" Width="18vw">
<Template Context="DetailInfo">
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@DetailInfo.DetailInfo.SetManuNo</RadzenText>
@if (DetailInfo.DetailInfo.SetManuNo != null)
{
<RadzenText TextStyle="TextStyle.Caption">
@DetailInfo.DetailInfo.SetManuNo
</RadzenText>
}
</Template>
@* <EditTemplate Context="DetailInfo">
<RadzenDropDown TValue="DrugManuNo" Name="ManuNo" @bind-Value="DetailInfo.DetailInfo.drugManuNo" Data="DetailInfo.DetailInfo.Drug.Manus" Style="width:100%; display: block;">
<Template>
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
}
else
{
<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>
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
}
else
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
}
</RadzenStack>
</ValueTemplate>
</RadzenDropDown>
<RadzenRequiredValidator Text="请选择批次" Component="ManuNo" Popup="true" />
</EditTemplate> *@
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="DetailInfo.Quantity" Title="数量" Filterable="false" Width="6vw">
@* <EditTemplate Context="DetailInfo">
<RadzenNumeric Min="0" Style="display: block" Name="Quantity" @bind-Value=@DetailInfo.DetailInfo.Quantity />
<RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Text="请填写正确的添加数量" Component="Quantity" Popup="true" />
</EditTemplate> *@
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</div>
</div>
</RadzenStack>
@code {
private readonly ILog logger = LogManager.GetLogger(typeof(CheckOrder));
@inject IOrderInfoDao orderInfoDao;
@inject DialogService dialogService;
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> setting;
@inject NotificationService _message;
@inject IReportDataDao reportDataDao;
@inject IOptions<SettingConfig> setting;
[Parameter] public BoxModel boxModel { get; set; }
bool allowRowSelectOnRowClick = true;
IEnumerable<OrderInfo> orderInfos;
IList<OrderInfo> selectedOrderInfos = new List<OrderInfo>();
RadzenDataGrid<OrderInfo> grid;
//麻醉师集合
List<Anaesthetist> NamesList = new List<Anaesthetist>();
Anaesthetist NameInfo;
Anaesthetist BoxColor;
//药盒集合
List<BoxModel> BoxList = new List<BoxModel>();
//药盒颜色集合
List<Anaesthetist> BoxColorList = new List<Anaesthetist>();
BoxModel BoxNum;
bool isLoading;
int count;
int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int status = 0;
string OrderNo;
string PatientName;
DateTime OrderDate = DateTime.Now;
DateTime PortOrderDate = DateTime.Now;
Popup popup;
RadzenButton button;
//第一次加载不执行LoadData方法
// int firstLod = 1;
void OnCheckSeleced(object dete)
{
if (orderInfos != null)
{
orderInfos.ToList().ForEach(it => it.ItemIsChecked = true);
}
}
void OnCurrentDateChanged(DateTime args)
{
OrderDate = new DateTime(args.Year, args.Month, args.Day);
}
void OnCellClick(DataGridCellMouseEventArgs<OrderInfo> args)
{
if (args.Data.DetailInfo.SetManuNo != null)
{
args.Data.DetailInfo.drugManuNo = args.Data.DetailInfo.Drug.Manus.Where(m => m.ManuNo == args.Data.DetailInfo.SetManuNo).FirstOrDefault();
}
if (args.Data.DetailInfo.drugManuNo == null)
{
args.Data.DetailInfo.drugManuNo = args.Data.DetailInfo.Drug.Manus.FirstOrDefault();
}
args.Data.ItemIsChecked = !args.Data.ItemIsChecked;
grid.EditRow(args.Data);
}
//确认
async Task Confirm()
{
if (selectedOrderInfos == null || selectedOrderInfos.Count<=0)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择处方", Duration = 4000 }
);
return;
}
// 关闭弹窗selectedOrderInfos
dialogService.Close(selectedOrderInfos);
}
PageData<OrderInfo> result;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}
async Task LoadData(LoadDataArgs args)
{
// if (firstLod == 1)
if (boxModel != null && boxModel.BoxName > 0)
{
//查询除本药箱外的处方信息
result = await orderInfoDao.GetAllOrderInfoForImport(PatientName, OrderNo, OrderDate, boxModel, args.Top, args.Skip);
orderInfos = result.Desserts;
selectedOrderInfos = orderInfos.ToList();
count = result.TotalDesserts;
isLoading = true;
}
isLoading = false;
}
}

View File

@ -0,0 +1,581 @@
@page "/Box/Check"
@using MasaBlazorApp3.Pojo.Config
@using MasaBlazorApp3.Report
@using Microsoft.Extensions.Options
@using Radzen.Blazor.Rendering
@using log4net;
<style>
.my-popup {
display: none;
position: absolute;
overflow: auto;
/* height: 360px; */
width: 900px;
border: var(--rz-panel-border);
background-color: var(--rz-panel-background-color);
box-shadow: var(--rz-panel-shadow);
border-radius: var(--rz-border-radius);
}
.rz-grid-table {
position: relative;
border-collapse: separate;
border-spacing: 0;
}
</style>
@* <RadzenStack Orientation="Orientation.Horizontal"> *@
<div class="col-12" style="margin-bottom:5px;">
@* <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem"> *@
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="12">
<RadzenLabel Text="核对药箱" Component="BoxList" />
<RadzenDropDownDataGrid AllowVirtualization="true" Name="BoxColorList" TValue="BoxModel" Data="@BoxColorList" Value="BoxColor" Style="width: 8vw;"
ValueChanged="@((args) => OnColorChanged(args))" AllowFiltering="false"
AllowFilteringByAllStringColumns="true" TextProperty="药箱号">
<Template>
@((context as BoxModel).BoxNo == 1 ? "白" : (context as BoxModel).BoxNo == 3 ? "非常规" : "绿")
</Template>
<Columns>
<RadzenDropDownDataGridColumn Property="BoxNo" Title="药箱颜色" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
<RadzenDropDownDataGrid AllowVirtualization="true" Name="BoxList" TValue="BoxModel" Data="@BoxList" Value="BoxNum" Style="width: 10vw;"
ValueChanged="@((args) => OnBoxChanged(args))" AllowFilteringByAllStringColumns="true" TextProperty="药箱号">
<Template>
@((context as BoxModel).BoxName == 99 ? "急诊药盒" : (context as BoxModel).BoxName == 111 ? "恢复室药盒" :
(context as BoxModel).BoxName == 31 ? "胃镜药盒" :
(context as BoxModel).BoxName == 32 ? "导管药盒" :
(context as BoxModel).BoxName == 33 ? "生殖药盒" :
(context as BoxModel).BoxName == 34 ? "妇门药盒" : (context as BoxModel).BoxName + "-" + ((context as BoxModel).BoxNo == 1 ? "白" : "绿"))
@* @((context as BoxModel).BoxName + "-" + (context as BoxModel).BoxNo) *@
</Template>
<Columns>
<RadzenDropDownDataGridColumn Property="BoxName" Title="药箱号" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
<RadzenLabel Text="处方时间" Component="OrderDate" />
<RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentDateChanged" @bind-Value="OrderDate" Style="width: 15vw;" Name="OrderDate" />
@* <RadzenButton Size="ButtonSize.Medium" Click="Search" IsBusy="isLoading" Icon="search" Text="查询" /> *@
<RadzenButton Size="ButtonSize.Medium" Click="Confirm" ButtonType="ButtonType.Button" ButtonStyle="ButtonStyle.Success" IsBusy="isLoading" Icon="check_circle" Text="确认" />
<RadzenButton Size="ButtonSize.Medium" Click="AddOrderMethod" ButtonType="ButtonType.Button" IsBusy="isLoading" ButtonStyle="ButtonStyle.Warning" Icon="input" Text="导入" />
<RadzenButton Style="margin-top:2px" Icon="download" @ref=button Text="麻醉药品使用登记本导出" Variant="Variant.Outlined" Click="@(args => popup.ToggleAsync(button.Element))" />
<Popup @ref=popup Lazy=true class="my-popup">
<RadzenStack Orientation="Orientation.Vertical" Gap="1rem" class="rz-h-100 rz-p-4">
<RadzenFieldset Text="条件选择">
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="6">
<RadzenLabel Text="处方时间" Component="PortOrderDate" />
</RadzenColumn>
<RadzenColumn Size="6">
<RadzenDatePicker DateFormat="yyyy-MM-dd" CurrentDateChanged="@OnCurrentPortDateChanged" @bind-Value="PortOrderDate" Style="width: 100%;" Name="PortOrderDate" />
</RadzenColumn>
</RadzenRow>
<RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
<RadzenButton Icon="download" Text="导出" Variant="Variant.Outlined" Click="StockExport" />
</RadzenRow>
</RadzenStack>
</RadzenFieldset>
</RadzenStack>
</Popup>
</RadzenColumn>
</RadzenRow>
</div>
<RadzenStack Orientation="Orientation.Horizontal">
<div Style="width:55vw;overflow:auto">
@* <RadzenDataGrid @ref="grid" AllowRowSelectOnRowClick="@allowRowSelectOnRowClick" AllowFiltering="true" LoadData="@LoadData" Style="width:50vw;overflow:auto"
FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
Data="@csList" IsLoading="@isLoading" Count="@count" EmptyText="无数据"
SelectionMode="DataGridSelectionMode.Multiple" @bind-Value=@selectedcsList
CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnDrugCellClick(args))"
AllowPaging="false">
<Columns>
<RadzenDataGridColumn Property="Drug.DrugName" Title="药品名称" FormatString="{0:d}" Sortable="false" Filterable="false" Width="2vw" />
<RadzenDataGridColumn Title="批次" Property="ManuNo" Filterable="false" Width="2vw">
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="DetailInfo.Quantity" Title="合计" Filterable="false" Width="3vw">
<Template Context="contextDate">
<div style="text-align: center;">
库存量【@contextDate.Quantity】<br />
用药量【@contextDate.UseQuantity】<br />
处方数【@contextDate.OrderQuantity】
</div>
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid> *@
<RadzenListBox AllowClear="true" @bind-Value=@listBoxSelectedcsList Style="width:45vw;height:70vh;overflow:auto" AllowFiltering="false" TValue="ChannelStock"
LoadData=@LoadData Data=@csList>
<Template>
<RadzenStack Orientation="Orientation.Horizontal">
<RadzenText Style="width:15vw;text-align:left">@((context as ChannelStock).Drug.DrugName)</RadzenText>
<RadzenText Style="width:10vw">@((context as ChannelStock).ManuNo)</RadzenText>
<RadzenStack Gap="10" Style="text-align:right">
<div style="text-align: center;">
基数【@((context as ChannelStock).BaseQuantity)】<br />
@* 总库存【@((context as ChannelStock).TotalQuantity)】<br /> *@
库存数【@((context as ChannelStock).Quantity)】<br />
用药数【@((context as ChannelStock).SelectedOrderList.Aggregate(0, (a, b) => a + b.DetailInfo.Quantity))】<br />
处方数【@((context as ChannelStock).SelectedOrderList.Count)】
</div>
</RadzenStack>
</RadzenStack>
</Template>
</RadzenListBox>
</div>
<div Style="width:75vw;overflow:auto;box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3); ">
@if ((listBoxSelectedcsList != null && string.IsNullOrEmpty(listBoxSelectedcsList.ListId) && listBoxSelectedcsList.Quantity > listBoxSelectedcsList.UseQuantity) || (listBoxSelectedcsList.Quantity > listBoxSelectedcsList.BaseQuantity))
{
//ListId为空则是没有在套餐里的药库存量大于使用量时需要把药还到抽屉里
//列出需要还到抽屉里的药品的抽屉库位
@* <RadzenRow AlignItems="AlignItems.Center" Style="margin:1vw;">
<RadzenColumn Size="12">
<RadzenLabel Text="库位" Component="DrawerList" />
<RadzenDropDownDataGrid AllowVirtualization="true" Name="DrawerList" TValue="ChannelStock" @bind-Value="@listBoxSelectedcsList.ReturnDrawerChanneStock" Data="@(listBoxSelectedcsList?.DrawerChanneStockList)"
Style="width:20vw;" AllowFilteringByAllStringColumns="true" TextProperty="Location">
<Columns>
<RadzenDropDownDataGridColumn Property="Location" Title="库位" Sortable="false" />
<RadzenDropDownDataGridColumn Property="Quantity" Title="库存" Sortable="false" />
</Columns>
</RadzenDropDownDataGrid>
<RadzenLabel Text="还药数" Component="ReturnQuantity" />
<RadzenNumeric Min="0" Name="ReturnQuantity" TValue="int" @bind-Value=@listBoxSelectedcsList.ReturnQuantity Style="width:5vw;" />
<RadzenNumericRangeValidator Min="0" Max=@listBoxSelectedcsList.Quantity Text="请填写正确的还药数量" Component="ReturnQuantity" Popup="true" />
</RadzenColumn>
</RadzenRow>
<RadzenRow AlignItems="AlignItems.Center" Style="margin:1vw;">
<RadzenColumn Size="12">*@
@if (listBoxSelectedcsList?.DrawerChanneStockList != null)
{
<RadzenListBox AllowClear="true" @bind-Value=@returnList AllowFiltering="false" TValue="ChannelStock" Style="width:70vw;overflow:auto"
Data=@(listBoxSelectedcsList?.DrawerChanneStockList)>
<Template>
<RadzenStack Orientation="Orientation.Horizontal">
<RadzenText Style="width:20vw;text-align:left">还药库位@((context as ChannelStock).Location)</RadzenText>
<RadzenText Style="width:10vw">还药数@((context as ChannelStock).ReturnQuantity)</RadzenText>
</RadzenStack>
</Template>
</RadzenListBox>
}
@* </RadzenColumn>
</RadzenRow> *@
}
<RadzenDataGrid Style="width:55vw;height:70vh;overflow:auto"
FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
Data="@(listBoxSelectedcsList?.OrderList)" EmptyText="无处方数据"
@bind-Value="@(listBoxSelectedcsList.SelectedOrderList)"
SelectionMode="DataGridSelectionMode.Multiple"
AllowRowSelectOnRowClick="true"
AllowPaging="false">
<Columns>
<RadzenDataGridColumn Sortable="false" Filterable="false" Width="1rem">
@* <HeaderTemplate>
<RadzenCheckBox TabIndex="-1" TriState="false" TValue="bool?" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select all items" } })"
Value="@(listBoxSelectedcsList?.OrderList!=null&&(bool)listBoxSelectedcsList?.OrderList.Any(oi=>oi. ItemIsChecked))"
Change="@(args => ChangeHeaderCheckBox(args))" />
</HeaderTemplate>
<Template Context="data">
<RadzenCheckBox TabIndex="-1" TriState="false" Value="@data.ItemIsChecked" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select item" } })"
TValue="bool" Change="@(args => { data.ItemIsChecked=!data.ItemIsChecked;})" />
</Template> *@
<HeaderTemplate>
<RadzenCheckBox TabIndex="-1" TriState="false" TValue="bool?" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select all items" } })"
Value="@(listBoxSelectedcsList?.SelectedOrderList==null || listBoxSelectedcsList?.SelectedOrderList.Any() !=true? false: !(bool)listBoxSelectedcsList?.OrderList.All(i => (bool)(listBoxSelectedcsList?.SelectedOrderList.Contains(i)))?null:listBoxSelectedcsList?.OrderList.Any(i => (bool)listBoxSelectedcsList?.SelectedOrderList.Contains(i)))"
Change="@(args =>listBoxSelectedcsList.SelectedOrderList = args == true ? listBoxSelectedcsList?.OrderList.ToList():new List<OrderInfo>())" />
</HeaderTemplate>
<Template Context="data">
<RadzenCheckBox TabIndex="-1" TriState="false" Value="@(listBoxSelectedcsList.SelectedOrderList.Contains(data))" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "Select item" } })"
TValue="bool" />
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="OrderNo" Title="处方号" Sortable="false" Filterable="false" Width="5vw" />
<RadzenDataGridColumn Property="anaesthetistName" Title="医师" Sortable="false" Filterable="false" Width="3vw" />
<RadzenDataGridColumn Property="PatientName" Title="患者" Sortable="false" Filterable="false" Width="3vw" />
<RadzenDataGridColumn Property="Sex" Title="性别" Sortable="false" Filterable="false" Width="2vw" />
<RadzenDataGridColumn Property="DetailInfo.Quantity" Title="数量" Sortable="false" Filterable="false" Width="2vw" />
</Columns>
</RadzenDataGrid>
</div>
</RadzenStack>
@* </RadzenStack> *@
@code {
private readonly ILog logger = LogManager.GetLogger(typeof(CheckOrder));
@inject IOrderInfoDao orderInfoDao;
@inject DialogService dialogService;
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> setting;
@inject NotificationService _message;
@inject IReportDataDao reportDataDao;
@inject IOptions<SettingConfig> setting;
//bool allowRowSelectOnRowClick = true;
IEnumerable<ChannelStock> csList;
IList<ChannelStock> selectedcsList;
ChannelStock listBoxSelectedcsList = new();
ChannelStock returnList = new();
IEnumerable<OrderInfo> orderList;
IList<OrderInfo> selectedOrderList;
RadzenListBox<ChannelStock> listBox;
RadzenDataGrid<OrderInfo> gridOrder;
//麻醉师集合
List<Anaesthetist> NamesList = new List<Anaesthetist>();
Anaesthetist NameInfo;
BoxModel BoxColor;
//全部药盒集合
List<BoxModel> AllBoxList = new List<BoxModel>();
//药盒集合
List<BoxModel> BoxList = new List<BoxModel>();
//药盒颜色集合
List<BoxModel> BoxColorList = new List<BoxModel>()
{
new BoxModel{BoxNo=1,BoxName=1 },
new BoxModel{BoxNo=2 ,BoxName=1},
new BoxModel{BoxNo=3 ,BoxName=1}
};
BoxModel BoxNum;
bool isLoading;
int count;
int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int status = 0;
string OrderNo;
string PatientName;
DateTime? OrderDate = DateTime.Now;
DateTime PortOrderDate = DateTime.Now;
Popup popup;
RadzenButton button;
private async Task OnColorChanged(object value)
{
if ((((BoxModel)value).BoxNo) == 3)
{
BoxList = AllBoxList.Where(bl => bl.BoxName > 30).ToList();
BoxNum = BoxList.FirstOrDefault();
await InvokeAsync(StateHasChanged);
}
else
{
BoxList = AllBoxList.Where(bl => bl.BoxNo == ((BoxModel)value).BoxNo && bl.BoxName <= 30).ToList();
BoxNum = BoxList.FirstOrDefault();
}
await LoadData(null);
}
//药箱选中修改
private async Task OnBoxChanged(object value)
{
// BoxList = BoxList.Where(bl => bl.BoxNo == ((BoxModel)value).BoxNo && bl.BoxName == ((BoxModel)value).BoxName).ToList();
BoxNum = (BoxModel)value;
await LoadData(null);
}
bool? boolHeader = true;
//全选/反选
void ChangeHeaderCheckBox(bool? args)
{
if (args != null)
{
boolHeader = args;
listBoxSelectedcsList?.OrderList.ToList().ForEach(it => it.ItemIsChecked = (bool)args);
}
}
void OnCheckSeleced(object dete)
{
//listBoxSelectedcsList?.OrderList.ToList().Where(it => it.OrderNo == (OrderInfo as (dete).))(oi => oi.ItemIsChecked = true));
}
//日期修改
async Task OnCurrentDateChanged(DateTime args)
{
OrderDate = new DateTime(args.Year, args.Month, args.Day);
await LoadData(null);
}
void OnCurrentPortDateChanged(DateTime args)
{
PortOrderDate = new DateTime(args.Year, args.Month, args.Day);
}
void OnDrugCellClick(DataGridCellMouseEventArgs<ChannelStock> args)
{
}
void OnCellClick(DataGridCellMouseEventArgs<OrderInfo> args)
{
if (args.Data.DetailInfo.SetManuNo != null)
{
args.Data.DetailInfo.drugManuNo = args.Data.DetailInfo.Drug.Manus.Where(m => m.ManuNo == args.Data.DetailInfo.SetManuNo).FirstOrDefault();
}
if (args.Data.DetailInfo.drugManuNo == null)
{
args.Data.DetailInfo.drugManuNo = args.Data.DetailInfo.Drug.Manus.FirstOrDefault();
}
args.Data.ItemIsChecked = !args.Data.ItemIsChecked;
// gridOrder.EditRow(args.Data);
}
//查询
async Task Search()
{
await LoadData(null);
}
//确认
async Task Confirm()
{
csList = csList.ToList();
List<ChannelStock> checkChannelStock = new();
string errMessage = string.Empty;
foreach (var item in csList)
{
if (item.SelectedOrderList.Aggregate(0, (a, b) => a + b.DetailInfo.Quantity)>item.Quantity)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"用药数不可大于库存数,请仔细核对!", Duration = 4000 }
);
return;
}
int i = 0;
if (item.OrderList != null && item.SelectedOrderList.Count > 0)
{
item.UseQuantity = item.SelectedOrderList.Sum(oi => oi.DetailInfo.Quantity);
item.OrderQuantity = item.SelectedOrderList.Count;
// checkChannelStock.Add(item);
i = 1;
}
if (item.DrawerChanneStockList != null && item.DrawerChanneStockList.Any(d => d.ReturnQuantity > 0))
{
//还药数量:使用量==库存还0 :库存>基数? (库存数-使用数)>基数? 还 库存数-使用数0
item.ReturnQuantity =
(item.UseQuantity == item.Quantity) ? 0 :
(item.Quantity <= item.BaseQuantity) ? 0 :
((item.Quantity - item.UseQuantity) > item.BaseQuantity) ?
(item.Quantity - item.UseQuantity - item.BaseQuantity) : 0;
//还药库位
if (item.ReturnQuantity > 0)
{
//药品未在套餐中绑定需要把药还到对应抽屉
List<ChannelStock> allDrugStock = await orderInfoDao.GetStockByDRrug(item.DrugId, item.ManuNo, 1);// await _connection.ChannelStock.Where(cs => cs.MachineId == _setting.machineId && cs.DrawerType == 1 && cs.DrugId == csList[i].DrugId && cs.ManuNo == csList[i].ManuNo).OrderBy(cs => cs.Quantity).ToListAsync();
if (allDrugStock != null && allDrugStock.Count > 0)
{
item.DrawerChanneStockList = new();
int iReturnQuantity = item.Quantity - item.UseQuantity - item.BaseQuantity;
for (int j = 0; j < allDrugStock.Count; j++)
{
if (allDrugStock[j].BoardType.ToString().Contains("2") && allDrugStock[j].Quantity >= 25)
continue;
if (allDrugStock[j].BoardType.ToString().Contains("2") && allDrugStock[j].Quantity + item.Quantity - item.UseQuantity > 25)
{
if (iReturnQuantity <= allDrugStock.Sum(it => it.Quantity))
{
for (int q = 0; iReturnQuantity > 0; q++)
{
allDrugStock[j].ReturnQuantity = 25 - allDrugStock[q].Quantity;
item.DrawerChanneStockList.Add(allDrugStock[q]);
iReturnQuantity = iReturnQuantity - allDrugStock[q].ReturnQuantity;
if (iReturnQuantity <= 0)
break;
}
}
else
{
//库位不足,有药品无库位可放
allDrugStock[j].ReturnQuantity = iReturnQuantity;
item.DrawerChanneStockList.Add(allDrugStock[j]);
logger.Info($"还药品【{item.Drug.DrugName}】库位不足,有药品无库位可放");
errMessage += $"库位不足,药品【{item.Drug.DrugName}】无库位可放";
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = errMessage, Duration = 4000 }
);
break; ;
}
}
else
{
allDrugStock[j].ReturnQuantity = iReturnQuantity;
item.DrawerChanneStockList.Add(allDrugStock[j]);
break;
}
}
}
}
// checkChannelStock.Add(item);
i = 1;
}
//还空瓶数
item.EmptyQuantity = item.SelectedOrderList.Sum(oi => oi.DetailInfo.Quantity);
if (item.EmptyQuantity > 0)
{
//还空瓶库位
//查询还空瓶库位
//checkChannelStock[i].EmptyStock;
List<ChannelStock> allDrugStock = await orderInfoDao.GetStockByDRrug(item.DrugId, item.ManuNo, 2);// await _connection.ChannelStock.Where(cs => cs.MachineId == _setting.machineId && cs.DrawerType == 1 && cs.DrugId == csList[i].DrugId && cs.ManuNo == csList[i].ManuNo).OrderBy(cs => cs.Quantity).ToListAsync();
if (allDrugStock.Count > 0)
{
item.EmptyStock = allDrugStock.FirstOrDefault();
item.EmptyStock.ReturnQuantity = item.EmptyQuantity;
i = 1;
}
// checkChannelStock.Add(item);
}
if (i == 1)
{
checkChannelStock.Add(item);
}
}
if (errMessage.Length > 0)
{
return;
}
if (checkChannelStock == null || checkChannelStock.Count <= 0)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"无可操作的数据", Duration = 4000 }
);
return;
}
// //弹出确认提示框
var b = await dialogService.OpenAsync<CheckOrderConfirmDialog>(
$"核对确认",
new Dictionary<string, object>() { { "csList", checkChannelStock } },
new DialogOptions() { Width = "90vw", Resizable = true, Draggable = true, ShowClose = false });
// if (b)
// {
// bool bResult = await orderInfoDao.CheckOrderInfoByChannelStock(csList.ToList(), BoxNum);
// if (bResult)
// {
// _message.Notify(
// new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"处方已核对完成", Duration = 4000 }
// );
// await LoadData(null);
// }
// else
// {
// _message.Notify(
// new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"处方已核对失败", Duration = 4000 }
// );
// }
// }
if (b)
{
LoadData(null);
}
}
//导处方
async Task AddOrderMethod()
{
var b = await dialogService.OpenAsync<CheckOrderImportDialog>(
$"导入处方信息",
new Dictionary<string, object>() { { "boxModel", BoxNum } },
new DialogOptions() { Width = "80vw", Resizable = true, Draggable = true, ShowClose = false });
if (b != null)
{
try
{
List<OrderInfo> importOrderInfo = b;
if (importOrderInfo.Count > 0)
{
string errorMessage = string.Empty;
for (int i = 0; i < importOrderInfo.Count; i++)
{
if (!(bool)listBoxSelectedcsList?.OrderList.Contains(importOrderInfo[i]))
{
if (csList.Where(c => c.DrugId == importOrderInfo[i].DetailInfo.DrugId && c.ManuNo == importOrderInfo[i].DetailInfo.SetManuNo).FirstOrDefault() == null)
{
errorMessage += $"处方{importOrderInfo[i].OrderNo}导入失败,药品{importOrderInfo[i].DetailInfo.Drug.DrugName}不存在或批次{importOrderInfo[i].DetailInfo.SetManuNo}不存在";
}
else
{
csList.Where(c => c.DrugId == importOrderInfo[i].DetailInfo.DrugId && c.ManuNo == importOrderInfo[i].DetailInfo.SetManuNo).FirstOrDefault()?.SelectedOrderList.Add(importOrderInfo[i]);
//csList.Where(c => c.DrugId == importOrderInfo[i].DetailInfo.DrugId && c.ManuNo == importOrderInfo[i].DetailInfo.SetManuNo).FirstOrDefault()?.OrderList.Add(importOrderInfo[i]);
}
}
csList = csList;
}
if (!string.IsNullOrEmpty(errorMessage))
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = errorMessage, Duration = 4000 }
);
return;
}
else
{
StateHasChanged(); // 刷新UI
}
}
}
catch (Exception)
{
}
}
}
PageData<ChannelStock> result;
protected override async Task OnInitializedAsync()
{
BoxColor = BoxColorList.FirstOrDefault();
AllBoxList = await orderInfoDao.GetOperationNum(0);
BoxList = AllBoxList.Where(bl => bl.BoxNo == BoxColor.BoxNo && bl.BoxName <= 30).ToList();
BoxNum = AllBoxList.FirstOrDefault();
await base.OnInitializedAsync();
}
async Task LoadData(LoadDataArgs args)
{
string? roomName = BoxNum == null ? "" : setting.Value.roomName + BoxNum.BoxName.ToString().PadLeft(2, '0');
result = await orderInfoDao.GetAllOrderInfoDrugByBox(BoxNum, roomName, OrderDate);
isLoading = true;
csList = result.Desserts;
if (csList != null && csList.Count() > 0)
{
listBoxSelectedcsList = csList.ElementAt(0);
}
count = result.TotalDesserts;
isLoading = false;
StateHasChanged(); // 刷新UI
}
//麻醉药品使用登记本导出
async Task StockExport()
{
if (PortOrderDate == DateTime.MinValue)
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择处方时间再导出", Duration = 4000 }
);
return;
}
// PageData<ReportUsageDateInfo> pageParentData = await reportDataDao.GetOrderInfoParentData(PortOrderDate);
// PageData<ReportUsageDateInfo> pageData = await reportDataDao.GetOrderInfoData(PortOrderDate);
List<ReportUsageParentDateInfo> pageParentData = await reportDataDao.GetOrderInfoParentData(PortOrderDate);
List<ReportUsageDateInfo> pageData = await reportDataDao.GetOrderInfoData(PortOrderDate);
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("parent", pageParentData);
parameters.Add("child", pageData);
GridReportUtil.PrintReport("use_book.grf", parameters);
}
// protected override async Task OnInitializedAsync()
// {
// await base.OnInitializedAsync();
// // orderInfos = dbContext.Employees;
// var result = await orderInfoDao.GetAllOrderInfo(OrderNo, OrderDate, args.Top, args.Skip);
// // Update the Data property
// orderInfos = result.Desserts;
// // Update the count
// count = result.TotalDesserts;
// isLoading = false;
// }
}

View File

@ -0,0 +1,28 @@

<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);
}
}

View File

@ -0,0 +1,77 @@
@page "/Box/CheckDDD"
@using Radzen.Blazor
@using System.ComponentModel
<style>
.total-footer {
font-weight: 600;
color: var(--rz-secondary);
padding: 8px 12px;
background-color: var(--rz-base-100);
border-top: 2px solid var(--rz-border-default);
}
</style>
@* <RadzenDataGrid @ref="grid" Data="@summaryData" TItem="dynamic"
AllowPaging="true" PageSize="5">
<Columns>
<RadzenDataGridColumn Title="商品品类" Property="Category" Width="200px" />
<RadzenDataGridColumn Title="销售总量" TextAlign="TextAlign.Right">
<Template Context="group">
<span class="font-bold">@group.TotalQuantity.ToString("N0")</span>
</Template>
<FooterTemplate>
<div class="total-footer">
全品类合计: @orders.Sum(o => o.Quantity).ToString("N0")
</div>
</FooterTemplate>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid> *@
@code {
RadzenDataGrid<dynamic> grid;
List<Order> orders = new();
IEnumerable<dynamic> summaryData;
protected override void OnInitialized()
{
// 模拟数据
orders = new List<Order> {
new Order { Category = "电子产品", Quantity = 15 },
new Order { Category = "电子产品", Quantity = 8 },
new Order { Category = "家居用品", Quantity = 23 }
};
CalculateSummary();
}
void CalculateSummary()
{
summaryData = orders
.GroupBy(o => o.Category)
.Select(g => new
{
Category = g.Key,
TotalQuantity = g.Sum(x => x.Quantity)
}).ToList();
}
public class Order : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Category { get; set; }
private int _quantity;
public int Quantity
{
get => _quantity;
set
{
_quantity = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(Quantity)));
}
}
}
}

View File

@ -0,0 +1,545 @@
@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">
@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)
{
if (setting.Value.returnDrawer != null && setting.Value.returnDrawer.Contains(i))
{
<RadzenButton class="col-5" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="true" Shade="Shade.Light" Variant="@(drawerNo != i ? Variant.Outlined : Variant.Flat)" Style="background-color: #d3d3d3;" />
}
else
{
<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" Style="width:66vw; overflow:auto"
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="@AddFinish" />
}
@if (status > 0 && status <= 3)
{
<RadzenButton Visible="@CancleIsEnable" Variant="Variant.Flat" Text="取消" Click="@Cancel" Style="width: 120px" />
}
</RadzenRow>
</HeaderTemplate>
<Columns>
<RadzenDataGridColumn Width="4vw" Title="库位" Property="ColNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Width="15vw" 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 Width="15vw" Title="批次" Property="ManuNo">
<Template Context="channel">
@* <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText> *@
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.ManuNo</RadzenText>
@* @if (channel.drugManuNo != null && channel.drugManuNo.EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">
@channel.drugManuNo.EffDate.ToString().Substring(0, 10)
</RadzenText>
}
else
{ *@
<RadzenText TextStyle="TextStyle.Caption">
@channel.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>
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
}
else
{
<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>
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
}
else
{
<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="库存" Width="10vw" 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="15vw" Title="加药数量" Property="AddQuantity">
<HeaderTemplate>
<div style="text-align: center;">
加药<br>数量
</div>
</HeaderTemplate>
<EditTemplate Context="cs">
@if (cs.BoardType.ToString().Contains("2") || cs.BoardType.ToString().Contains("3"))
{
@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;
await Task.Delay(200);
PortUtil.DrawerNo = this.drawerNo;
// 根据抽屉类型来决定打开前是否需要查询数量
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 < 6; i++)
{
int beforeQuantity = await PortUtil.CheckQuantityForSingleForErZhong(i + 1);
BeforeQuantity[i] = beforeQuantity;
logger.Info($"BeforeQuantity:{(i+1)}-{beforeQuantity}数量{string.Join(",", BeforeQuantity)}");
await Task.Delay(200);
}
}
var b = await PortUtil.OpenDrawerStatusForErZhong(this.drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatusForErZhong(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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.weigh != null && setting.Value.weigh.Contains(this.drawerNo))
{
if (currentCol > 0)
{
//开药盒前先查数
// int beforeQuantity = await PortUtil.CheckQuantityForSingleForErZhong(currentCol);
// BeforeQuantity[currentCol - 1] = beforeQuantity;
// logger.Info($"BeforeQuantity:{currentCol}-{beforeQuantity}数量{string.Join(",", BeforeQuantity)}");
// await Task.Delay(200);
ColNos.Add(currentCol);
}
}
//药盒抽屉,开药盒
if (setting.Value.box != null && setting.Value.box.Contains(this.drawerNo))
{
//药盒抽屉,开药盒
if (currentCol > 0)
{
await PortUtil.OpenBoxByColNoForErZhong(currentCol);
}
currentCol = 0;
}
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.Where(cl => ColNos.Contains(cl.ColNo)).ToList().ForEach(cl =>
{
cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1];
});
await InvokeAsync(StateHasChanged);
}
// 判断是否为称重抽屉
if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo))
{
//开抽屉后查数
for (int i = 0; i < ColNos.Count; i++)
{
int afterQuantity = await PortUtil.CheckQuantityForSingleForErZhong(ColNos[i]);
AfterQuantity[ColNos[i] - 1] = afterQuantity;
logger.Info($"AfterQuantity:{ColNos[i]}-{string.Join(",", AfterQuantity)}数量{string.Join(", ", BeforeQuantity)}");
}
channels.Where(cl => ColNos.Contains(cl.ColNo)).ToList().ForEach(cl =>
{
cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1];
});
await InvokeAsync(StateHasChanged);
}
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))
{
}
RestData();
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
this.BeforeQuantity = new int[9];
this.AfterQuantity = new int[9];
currentCol = 0;
ColNos.Clear();
}
//关闭抽屉后获取称重稳定数量
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.Where(cl => ColNos.Contains(cl.ColNo)).ToList().ForEach(cl =>
{
cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1];
});
CompleteIsEnable = true;
CancleIsEnable = true;
logger.Info("对比成功停止循环");
await InvokeAsync(StateHasChanged);
}
else
{
finallyQuantity.RemoveAt(0);
next();
}
}
else
{
if (finallyQuantity.Count >= 9)
{
CancleIsEnable = true;
}
else
{
CancleIsEnable = false;
}
CompleteIsEnable = false;
PortUtil.DrawerNo = drawerNo;
PortUtil.ColNoLst = ColNos;
int[] quantity = await PortUtil.CheckQuantityByAddrForMultiForErZhong();
AfterQuantity = quantity;
int[] Quantitys = new int[BeforeQuantity.Length];
for (int i = 0; i < BeforeQuantity.Length; i++)
{
Quantitys[i] = AfterQuantity[i] - BeforeQuantity[i];
}
finallyQuantity.Add(Quantitys);
logger.Info($"Quantity{string.Join(",", Quantitys)}");
channels.Where(cl => ColNos.Contains(cl.ColNo)).ToList().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, null, null);
if (!b)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(channels)}");
}
else
{
// 判断是否为标签抽屉
if (setting.Value != null && setting.Value.label != null && setting.Value.label.Contains(this.drawerNo))
{
//写标签数量
List<ChannelStock>? AddChannels = channels.Where(it => it.AddQuantity > 0).ToList();
for (int i = 0; i < AddChannels.Count; i++)
{
await PortUtil.WriteQuantityMethodForErZhong(AddChannels[i].Quantity + AddChannels[i].AddQuantity, AddChannels[i].DrawerNo, AddChannels[i].ColNo);
await Task.Delay(20);
}
// channels.Where(it => it.AddQuantity > 0).ToList().ForEach(async it =>
// {
// await PortUtil.WriteQuantityMethodForErZhong(it.Quantity + it.AddQuantity, it.DrawerNo, it.ColNo);
// await Task.Delay(20);
// });
}
ColNos.Clear();
}
}
//重置状态
this.RestData();
// 重新查询库存
await grid.Reload();
}
void Cancel()
{
RestData();
}
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);
// }
// }
if (setting.Value.box.Contains(args.Data.DrawerNo) && status != 2)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync("请先点取药按钮打开抽屉");
}
currentCol = args.Data.ColNo;
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();
}
}

View File

@ -0,0 +1,833 @@
@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">
@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" Style="width:66vw; overflow:auto"
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)
{
if (setting.Value.returnDrawer != null && setting.Value.returnDrawer.Contains(drawerNo))
{
<RadzenButton IsBusy="@(status > 0)" BusyText="取空瓶中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="取空瓶" Click="@OpenDrawer" />
}
else
{
<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="4vw" Title="库位" Property="ColNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Width="15vw" 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 Width="15vw" 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="库存" Width="10vw" 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="15vw" Title="取药数量" Property="TakeQuantity">
<HeaderTemplate>
<div style="text-align: center;">
取药<br>数量
</div>
</HeaderTemplate>
<EditTemplate Context="channel">
@if (channel.BoardType.ToString().Contains("2") || channel.BoardType.ToString().Contains("3"))
{
@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;
@inject IOrderInfoDao orderInfoDao;
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>();
int currentCol = 0;
bool CompleteIsEnable = true;
bool CancleIsEnable = true;
// BoxModel BoxNum;
// BoxModel BoxColor;
// //全部药盒集合
// List<BoxModel> AllBoxList = new List<BoxModel>();
// //药盒集合
// List<BoxModel> BoxList = new List<BoxModel>();
// //药盒颜色集合
// List<BoxModel> BoxColorList = new List<BoxModel>()
// {
// new BoxModel{BoxNo=1,BoxName=1 },
// new BoxModel{BoxNo=2 ,BoxName=1},
// new BoxModel{BoxNo=3 ,BoxName=1}
// };
private readonly ILog logger = LogManager.GetLogger(typeof(DrawerTake));
protected override async Task OnInitializedAsync()
{
// List<ChannelStock> Stocks = new List<ChannelStock>()
// {
// new ChannelStock()
// {
// Id="DM_CHANNEL_1",
// MachineId="DM1",
// DrawerNo=1,
// ColNo=1,
// DrugId="MZ02MDZLI1",
// Quantity=12,
// TotalQuantity=0,
// DrawerType=1,
// BoardType=653,
// ManuNo="RT12111",
// EffDate="2050-08-31",
// Drug=new DrugInfo()
// {
// DrugId="MZ02MDZLI1",
// DrugName="咪达唑仑注射液(2ml:10mg)甲普基",
// DrugType="西药",
// DrugSpec="10mg",
// Manufactory="江苏恩华",
// PyCode="MDZLZSYL",
// PackH="1",
// Manus=new List<DrugManuNo>()
// {
// new DrugManuNo()
// {
// Id="d801f058-4dbe-4f8e-badd-fb8c794c40f7",
// DrugId="MZ02MDZLI1",
// ManuNo="M25060154",
// //EffDate="2055-08-29T00:00:00",
// Quantity=0
// },
// new DrugManuNo()
// {
// Id="476578d1-cb47-48f2-9945-0dcfea357d55",
// DrugId="MZ02MDZLI1",
// ManuNo="RT12111",
// //EffDate="2055-08-29T00:00:00",
// Quantity=0
// }
// }
// },
// TakeQuantity=1,
// AddQuantity=0,
// ReturnQuantity=0,
// Dmnguid="476578d1-cb47-48f2-9945-0dcfea357d55",
// drugManuNo=new DrugManuNo()
// {
// Id="476578d1-cb47-48f2-9945-0dcfea357d55",
// DrugId="MZ02MDZLI1",
// ManuNo="RT12111",
// Quantity=0
// },
// CanReturnQuantity=0,
// CheckQuantity=0,
// BiaoDingStatus=0,
// BaseQuantity=0,
// NeedQuantity=0,
// AddToQuantity=0,
// BoxState=1,
// EmptyQuantity=0,
// UseQuantity=0,
// OrderQuantity=0,
// },
// new ChannelStock()
// {
// Id="DM_CHANNEL_2",
// MachineId="DM1",
// DrawerNo=1,
// ColNo=2,
// DrugId="TG01BTFNI2",
// Quantity=1,
// TotalQuantity=0,
// DrawerType=1,
// BoardType=653,
// ManuNo="DD123456",
// EffDate="2033-08-31",
// Drug=new DrugInfo()
// {
// DrugId="TG01BTFNI2",
// DrugName="酒石酸布托啡诺注射液(2ml:4mg)乙控",
// DrugType="西药",
// DrugSpec="2ml:4mg",
// Manufactory="苏恒瑞",
// PyCode="JSSBTFNZ",
// PackH="1",
// Manus=new List<DrugManuNo>()
// {
// new DrugManuNo()
// {
// Id="915ce96a-3c79-4e63-968e-b62017d0413e",
// DrugId="TG01BTFNI2",
// ManuNo="DD123456",
// //EffDate="2055-08-29T00:00:00",
// Quantity=0
// }
// }
// },
// TakeQuantity=2,
// AddQuantity=0,
// ReturnQuantity=0,
// Dmnguid="915ce96a-3c79-4e63-968e-b62017d0413e",
// drugManuNo=new DrugManuNo()
// {
// Id="915ce96a-3c79-4e63-968e-b62017d0413e",
// DrugId="TG01BTFNI2",
// ManuNo="DD123456",
// Quantity=0
// },
// CanReturnQuantity=0,
// CheckQuantity=0,
// BiaoDingStatus=0,
// BaseQuantity=0,
// NeedQuantity=0,
// AddToQuantity=0,
// BoxState=1,
// EmptyQuantity=0,
// UseQuantity=0,
// OrderQuantity=0,
// },
// new ChannelStock()
// {
// Id="DM_CHANNEL_3",
// MachineId="DM1",
// DrawerNo=1,
// ColNo=3,
// DrugId="TG01DZXII1",
// Quantity=7,
// TotalQuantity=0,
// DrawerType=1,
// BoardType=653,
// ManuNo="AA789456",
// EffDate="2040-08-31",
// Drug=new DrugInfo()
// {
// DrugId="TG01DZXII1",
// DrugName="地佐辛注射液(1ml:5mg)控",
// DrugType="西药",
// DrugSpec="1ml:5mg",
// Manufactory="扬子江",
// PyCode="DZXZSYML",
// PackH=null,
// Manus=new List<DrugManuNo>()
// {
// new DrugManuNo()
// {
// Id="0a9c1ccb-4b0e-4e94-a0ac-2f9a747ec6a2",
// DrugId="TG01DZXII1",
// ManuNo="AA789456",
// //EffDate="2055-08-29T00:00:00",
// Quantity=0
// }
// }
// },
// TakeQuantity=3,
// AddQuantity=0,
// ReturnQuantity=0,
// Dmnguid="915ce96a-3c79-4e63-968e-b62017d0413e",
// drugManuNo=new DrugManuNo()
// {
// Id="0a9c1ccb-4b0e-4e94-a0ac-2f9a747ec6a2",
// DrugId="TG01DZXII1",
// ManuNo="AA789456",
// Quantity=0
// },
// CanReturnQuantity=0,
// CheckQuantity=0,
// BiaoDingStatus=0,
// BaseQuantity=0,
// NeedQuantity=0,
// AddToQuantity=0,
// BoxState=1,
// EmptyQuantity=0,
// UseQuantity=0,
// OrderQuantity=0,
// },
// new ChannelStock()
// {
// Id="DM_CHANNEL_4",
// MachineId="DM1",
// DrawerNo=1,
// ColNo=4,
// DrugId="TG01DZXII1",
// Quantity=9,
// TotalQuantity=0,
// DrawerType=1,
// BoardType=653,
// ManuNo="AA789456",
// EffDate="2040-08-31",
// Drug=new DrugInfo()
// {
// DrugId="TG01DZXII1",
// DrugName="地佐辛注射液(1ml:5mg)控",
// DrugType="西药",
// DrugSpec="1ml:5mg",
// Manufactory="扬子江",
// PyCode="DZXZSYML",
// PackH=null,
// Manus=new List<DrugManuNo>()
// {
// new DrugManuNo()
// {
// Id="0a9c1ccb-4b0e-4e94-a0ac-2f9a747ec6a2",
// DrugId="TG01DZXII1",
// ManuNo="AA789456",
// //EffDate="2055-08-29T00:00:00",
// Quantity=0
// }
// }
// },
// TakeQuantity=3,
// AddQuantity=0,
// ReturnQuantity=0,
// Dmnguid="915ce96a-3c79-4e63-968e-b62017d0413e",
// drugManuNo=new DrugManuNo()
// {
// Id="0a9c1ccb-4b0e-4e94-a0ac-2f9a747ec6a2",
// DrugId="TG01DZXII1",
// ManuNo="AA789456",
// Quantity=0
// },
// CanReturnQuantity=0,
// CheckQuantity=0,
// BiaoDingStatus=0,
// BaseQuantity=0,
// NeedQuantity=0,
// AddToQuantity=0,
// BoxState=1,
// EmptyQuantity=0,
// UseQuantity=0,
// OrderQuantity=0,
// },
// new ChannelStock()
// {
// },
// new ChannelStock()
// {
// },
// new ChannelStock()
// {
// },
// };
// channelListDao.DrawerOperationFinish(Stocks, 2, null, null);
// BoxColor = BoxColorList.FirstOrDefault();
// AllBoxList = await orderInfoDao.GetOperationNum(0);
// BoxList = AllBoxList.Where(bl => bl.BoxNo == BoxColor.BoxNo && bl.BoxName <= 30).ToList();
// BoxNum = AllBoxList.FirstOrDefault();
await base.OnInitializedAsync();
}
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
// var result = await channelListDao.GetChannelStockByDrawerNo(drawerNo, 1);
var result = await channelListDao.GetChannelStockByDrawerNoWithDrawers(drawerNo, 1);
DrawerNos = result.DrawerArray;
// Update the Data property
channels = result.ChannelStocks;
// Update the count
count = result.ChannelStocks.Count;
isLoading = false;
}
// private async Task OnColorChanged(object value)
// {
// if ((((BoxModel)value).BoxNo) == 3)
// {
// BoxList = AllBoxList.Where(bl => bl.BoxName > 30).ToList();
// BoxNum = BoxList.FirstOrDefault();
// await InvokeAsync(StateHasChanged);
// }
// else
// {
// BoxList = AllBoxList.Where(bl => bl.BoxNo == ((BoxModel)value).BoxNo && bl.BoxName <= 30).ToList();
// BoxNum = BoxList.FirstOrDefault();
// }
// }
//药箱选中修改
// private async Task OnBoxChanged(object value)
// {
// // BoxList = BoxList.Where(bl => bl.BoxNo == ((BoxModel)value).BoxNo && bl.BoxName == ((BoxModel)value).BoxName).ToList();
// BoxNum = (BoxModel)value;
// }
async Task OpenDrawer()
{
this.status = 1;
await Task.Delay(200);
PortUtil.DrawerNo = this.drawerNo;
// 根据抽屉类型来决定打开前是否需要查询数量
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 < 6; i++)
{
int beforeQuantity = await PortUtil.CheckQuantityForSingleForErZhong(i + 1);
BeforeQuantity[i] = beforeQuantity;
logger.Info($"BeforeQuantity:{(i + 1)}-{beforeQuantity}数量{string.Join(",", BeforeQuantity)}");
await Task.Delay(200);
}
}
var b = await PortUtil.OpenDrawerStatusForErZhong(this.drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
if (setting.Value.returnDrawer != null && setting.Value.returnDrawer.Contains(drawerNo))
{
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取空瓶");
}
else
{
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)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatusForErZhong(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
if (setting.Value.returnDrawer != null && setting.Value.returnDrawer.Contains(drawerNo))
{
PortUtil.SpeakAsync($"取空瓶完成,请核对或录入正确的取出数量");
}
else
{
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.box != null && setting.Value.box.Contains(this.drawerNo))
{
// 判断是否为称重抽屉
if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo))
{
// //开抽屉前先查数
if (currentCol > 0)
{
// int beforeQuantity = await PortUtil.CheckQuantityForSingleForErZhong(currentCol);
// BeforeQuantity[currentCol - 1] = beforeQuantity;
// logger.Info($"BeforeQuantity:{currentCol}-{beforeQuantity}数量{string.Join(",", BeforeQuantity)}");
// await Task.Delay(200);
ColNos.Add(currentCol);
}
}
//药盒抽屉,开药盒
if (currentCol > 0)
{
await PortUtil.OpenBoxByColNoForErZhong(currentCol);
}
currentCol = 0;
}
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)}】");
if (!BeforeQuantity.SequenceEqual(AfterQuantity))
{
channels.Where(cl => ColNos.Contains(cl.ColNo)).ToList().ForEach(cl =>
{
cl.TakeQuantity = this.BeforeQuantity[cl.ColNo - 1] - this.AfterQuantity[cl.ColNo - 1];
});
await InvokeAsync(StateHasChanged);
}
}
// 判断是否为称重抽屉
if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo))
{
//开抽屉后查数
for (int i = 0; i < ColNos.Count; i++)
{
int afterQuantity = await PortUtil.CheckQuantityForSingleForErZhong(ColNos[i]);
AfterQuantity[ColNos[i] - 1] = afterQuantity;
logger.Info($"AfterQuantity:{ColNos[i]}-{afterQuantity}数量{string.Join(",", AfterQuantity)}");
}
if (!BeforeQuantity.SequenceEqual(AfterQuantity))
{
channels.Where(cl => ColNos.Contains(cl.ColNo)).ToList().ForEach(cl =>
{
cl.TakeQuantity = this.BeforeQuantity[cl.ColNo - 1] - this.AfterQuantity[cl.ColNo - 1];
});
await InvokeAsync(StateHasChanged);
}
}
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))
{
}
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.Where(cl => ColNos.Contains(cl.ColNo)).ToList().ForEach(cl =>
{
cl.TakeQuantity = this.BeforeQuantity[cl.ColNo - 1] - this.AfterQuantity[cl.ColNo - 1];
});
await InvokeAsync(StateHasChanged);
}
else
{
finallyQuantity.RemoveAt(0);
CancleIsEnable = true;
next();
}
}
else
{
if (finallyQuantity.Count >= 9)
{
CancleIsEnable = true;
}
else
{
CancleIsEnable = false;
}
CompleteIsEnable = false;
PortUtil.DrawerNo = drawerNo;
PortUtil.ColNoLst = ColNos;
int[] quantity = await PortUtil.CheckQuantityByAddrForMultiForErZhong();
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)}");
if (!BeforeQuantity.SequenceEqual(AfterQuantity))
{
channels.Where(cl => ColNos.Contains(cl.ColNo)).ToList().ForEach(cl =>
{
cl.TakeQuantity = this.BeforeQuantity[cl.ColNo - 1] - this.AfterQuantity[cl.ColNo - 1];
});
await InvokeAsync(StateHasChanged);
}
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()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
this.BeforeQuantity = new int[9];
this.AfterQuantity = new int[9];
ColNos.Clear();
currentCol = 0;
// InvokeAsync(StateHasChanged);
}
async Task TakeFinish()
{
if (channels.Any(cl => cl.TakeQuantity != 0))
{
CheckInfo<ChannelList> checkInfo = null;
// if(BoxNum!=null&&BoxNum.BoxNo!=0)
// {
// //查询本次加药的药盒里是否有绑该药,有则正常入库,无则提示无绑定不可添加
// checkInfo = await channelListDao.CheckBoxDrugInfo(BoxNum, channels.Where(cl => cl.TakeQuantity != 0).ToList());
// if (!string.IsNullOrEmpty(checkInfo.StrInfo))
// {
// _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"该药盒中未绑定该批次药品无法添加", Duration = 4000 });
// logger.Error($"该药盒中未绑定该批次药品无法添加,数据{JsonConvert.SerializeObject(channels)}");
// return;
// }
// }
// if (setting.Value.returnDrawer != null && setting.Value.returnDrawer.Contains(drawerNo))
// {
// BoxNum = null;
// }
// 保存账册、操作记录
var b = await channelListDao.DrawerOperationFinish(channels.Where(cl => cl.TakeQuantity != 0).ToList(), 2, null, null);
if (!b)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
logger.Error($"抽屉取药保存数据库失败,数据{JsonConvert.SerializeObject(channels)}");
}
else
{
// 判断是否为标签抽屉
if (setting.Value.label != null && setting.Value.label.Contains(this.drawerNo))
{
//写标签数量
List<ChannelStock> takeChannelStocks = channels.Where(it => it.TakeQuantity > 0).ToList();
for (int i = 0; i < takeChannelStocks.Count; i++)
{
await PortUtil.WriteQuantityMethodForErZhong(takeChannelStocks[i].Quantity - takeChannelStocks[i].TakeQuantity, takeChannelStocks[i].DrawerNo, takeChannelStocks[i].ColNo);
await Task.Delay(20);
}
// channels.Where(it => it.TakeQuantity > 0).ToList().ForEach(async it =>
// {
// await PortUtil.WriteQuantityMethodForErZhong(it.Quantity - it.TakeQuantity, it.DrawerNo, it.ColNo);
// });
}
}
}
//重置状态
this.RestData();
// 重新查询库存
await grid.Reload();
}
void Cancel()
{
RestData();
}
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);
// }
if (setting.Value.box.Contains(args.Data.DrawerNo) && status != 2)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync("请先点取药按钮打开抽屉");
}
currentCol = args.Data.ColNo;
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();
}
}

View File

@ -0,0 +1,350 @@
@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" style="height:55vh;overflow:auto;">
<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="5" PagerHorizontalAlign="HorizontalAlign.Left" ColumnWidth="100px" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
<Columns>
<RadzenDataGridColumn 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="150px" 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 Title="导出使用报表" Property="PackH">
<EditTemplate Context="drugInfo">
<RadzenTextBox Name="PackH" @bind-Value="drugInfo.PackH" Style="width:100%;display:block;" />
</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)
{
<div class="col-6 mb-4" style="height:55vh;width:550px;overflow:auto;">
<RadzenDataGrid @ref="ManusGrid" EmptyText="无数据" ColumnWidth="100px" Style="width:445px"
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" Width="25px" Visible=false>
<Template Context="data">
@(SelectedDrugs.FirstOrDefault()?.Manus.IndexOf(data) + 1)
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="批次" Property="ManuNo" Width="150px">
<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" Width="150px">
<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="操作" Width="160px" 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>
<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<ConfirmDialog>(
$"删除确认",
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)
{
drugManuNo.Id = string.IsNullOrEmpty(drugManuNo.Id) ? Guid.NewGuid().ToString() : drugManuNo.Id;
await ManusGrid.UpdateRow(drugManuNo);
}
void CancelEdit(DrugManuNo drugManuNo)
{
Reset(drugManuNo);
// SelectedDrugs.FirstOrDefault().Manus.Remove(drugManuNo);
SelectedDrugs.FirstOrDefault().Manus.RemoveAll(mn=>string.IsNullOrEmpty(mn.Id));
ManusGrid.CancelEditRow(drugManuNo);
ManusGrid.Reload();
}
async Task DeleteRow(DrugManuNo drugManuNo)
{
Reset(drugManuNo);
if (SelectedDrugs.FirstOrDefault().Manus.Contains(drugManuNo))
{
//弹出确认提示框
var b = await dialogService.OpenAsync<ConfirmDialog>(
$"确认删除",
new Dictionary<string, object>() { { "confirmInfo", "确认要删除批次:" + drugManuNo.ManuNo + "吗?" } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
SelectedDrugs.FirstOrDefault().Manus.Remove(drugManuNo);
// 数据库删除
drugManuNoDao.DeleteDrugManuNo(drugManuNo.Id);
await ManusGrid.Reload();
}
}
else
{
ManusGrid.CancelEditRow(drugManuNo);
await ManusGrid.Reload();
}
}
void OnUpdateRow(DrugManuNo dm)
{
dm.Id = string.IsNullOrEmpty(dm.Id) ? Guid.NewGuid().ToString() : dm.Id;
Reset(dm);
// 数据库更新
drugManuNoDao.UpdateDrugManuNo(dm);
ManusGrid.Reload();
}
void OnCreateRow(DrugManuNo dm)
{
// 数据库添加批次
drugManuNoDao.AddDrugManuNo(dm);
manuNoToInsert.Remove(dm);
ManusGrid.Reload();
}
}

View File

@ -0,0 +1,136 @@
@page "/EditPasswordDialog"
@using MasaBlazorApp3.Pojo.Config;
@using MasaBlazorApp3.Pojo.Vo;
@using MasaBlazorApp3.Util;
@using Microsoft.Extensions.Options;
@using Newtonsoft.Json;
@using log4net;
<style>
.rz-dialog-content {
padding: 0 !important;
}
</style>
<RadzenRow Gap="0" Style="overflow: hidden;width:100%;height:100%">
@* <RadzenColumn Size="12" SizeMD="5">
<RadzenCard class="rz-shadow-0 rz-border-radius-0 rz-text-align-center rz-p-12 align-items-center justify-content-center" 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 (userI == 1)
{
<RadzenText TextStyle="TextStyle.H5" class="rz-color-white">
操作人 @globalStateService.Operator?.NickName
<p>正在修改密码</p>
</RadzenText>
}
else if (userI == 2)
{
<RadzenText TextStyle="TextStyle.H5" class="rz-color-white">
复核人 @globalStateService.Reviewer?.NickName
<p>正在修改密码</p>
</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="oldPassword">原密码</label>
<div class="rz-form-input-wrapper">
<RadzenPassword id="oldPassword" Name="oldPassword" @bind-Value="@loginModel.OldPassword" Style="width:100%" />
<RadzenRequiredValidator Component="oldPassword" 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>
@code {
@inject NotificationService _message
@inject GlobalStateService globalStateService;
@inject IUserDao userDao;
@inject Radzen.DialogService dialogService;
private Pojo.User loginModel = new();
private readonly ILog logger = LogManager.GetLogger(typeof(LoginDialog));
[Parameter] public int userI { get; set; }
private void Submit(Pojo.User user)
{
if (userI == 1)
{
user.Username = globalStateService.Operator.Username;
}
else if (userI == 2)
{
user.Username = globalStateService.Reviewer.Username;
}
else
{
return;
}
Pojo.User u = userDao.GetByUsername(loginModel.Username);
if (u != null)
{
if (Util.MD5.GetMD5Hash(loginModel.OldPassword).ToLower().Equals(u.Password))
{
u.Password = loginModel.Password;
bool iRet=userDao.UpdateUserPassword(u);
if (iRet)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"修改完成,退出后登录请使用新密码", Duration = 4000 });
logger.Error($"{loginModel.Username}修改密码失败,数据{JsonConvert.SerializeObject(u)}");
// 关闭弹窗
dialogService.Close(false);
}
else
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"修改失败", Duration = 4000 });
logger.Error($"{loginModel.Username}修改密码失败,数据{JsonConvert.SerializeObject(u)}");
// 关闭弹窗
dialogService.Close(false);
}
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"原密码错误", Duration = 4000 }
);
logger.Info($"用户【{u.Username}】修改密码,原密码输入错误");
}
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"无此用户", Duration = 4000 }
);
logger.Info($"修改密码没有用户:【{loginModel.Username}】");
}
}
private void Exit()
{
dialogService.Close(false);
}
}

View File

@ -0,0 +1,70 @@
@page "/user/finger/{userId}"
@page "/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;
}
}

View File

@ -0,0 +1,119 @@
@page "/manage/setting/Fridge"
@using MasaBlazorApp3.Util
@using Newtonsoft.Json.Linq
@using log4net
@layout SettingLayout
<div class="main">
<div class="top-row px-4">
<RadzenButton Icon="account_circle" Style="margin-left: auto;" Click="@SaveMethod">
<ChildContent>
保存设置
</ChildContent>
</RadzenButton>
</div>
<div class="content px-4">
<RadzenCard class="rz-my-6">
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Start" Wrap="FlexWrap.Wrap">
<RadzenStack Orientation="Orientation.Vertical" Gap="4px">
冰箱温度区间
<RadzenTextBox Placeholder="2-8" Value="@temperatureRange" Change="@(args=>temperatureRange=args)"></RadzenTextBox>
</RadzenStack>
<RadzenStack Orientation="Orientation.Vertical" Gap="4px">
冰箱状态
<RadzenRadioButtonList Value=@fridgeStateValue TValue="int" Change=@(args => fridgeStateValue = args)>
<Items>
<RadzenRadioButtonListItem Text="开" Value="0" />
<RadzenRadioButtonListItem Text="关" Value="1" />
</Items>
</RadzenRadioButtonList>
</RadzenStack>
<RadzenStack Orientation="Orientation.Vertical" Gap="4px">
报警状态
<RadzenRadioButtonList Value="@alertStateValue" TValue="int" Change="@(args=>alertStateValue=args)">
<Items>
<RadzenRadioButtonListItem Text="开" Value="0"/>
<RadzenRadioButtonListItem Text="关" Value="1"/>
</Items>
</RadzenRadioButtonList>
</RadzenStack>
</RadzenStack>
</RadzenCard>
</div>
</div>
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.fridgeConfig> setting;
@inject PortUtil port;
@inject NotificationService _message
@code {
private readonly ILog logger = LogManager.GetLogger(typeof(LoginDialog));
int fridgeStateValue = 1;
int alertStateValue = 1;
string temperatureRange = "2-8";
protected override void OnInitialized()
{
fridgeStateValue = setting.Value.fridgeState;
alertStateValue = setting.Value.alertState;
temperatureRange = setting.Value.temperatureRange;
base.OnInitialized();
}
//保存
async Task SaveMethod()
{
// 获取当前工作目录
string currentDirectory = Directory.GetCurrentDirectory();
// setting.Value.fridgeState = fridgeStateValue;
// setting.Value.alertState = alertStateValue;
// setting.Value.temperatureRange = temperatureRange;
string filePath =Path.Combine(currentDirectory, "appsettings.json");
string jsonString= File.ReadAllText(filePath);
var jsonNode = JObject.Parse(jsonString);
jsonNode["fridge"]["temperatureRange"] = temperatureRange;
jsonNode["fridge"]["fridgeState"]= fridgeStateValue;
jsonNode["fridge"]["alertState"] = alertStateValue;
var options = new JsonSerializerOptions { WriteIndented = true };
File.WriteAllText(filePath, jsonNode.ToString(Newtonsoft.Json.Formatting.Indented));
if (fridgeStateValue==0)
{
await port.FridegOpen(1);
}
else
{
await port.FridgeOff(1);
}
if (alertStateValue==0)
{
await port.FridgeAlarmOn(1);
}
else
{
await port.FridgeAlarmOff(1);
}
string[] newRange = temperatureRange.Split('-');
if(newRange.Length>=2)
{
string[] range= setting.Value.temperatureRange.Split('-');
bool bMix = float.TryParse(newRange[0], out float Min);
bool bMax = float.TryParse(newRange[1], out float Max);
if (bMix && bMax)
{
if (range == null || range[0] == null||(range != null && range[0] != null && range[0] != newRange[0]))
{
//设定冰箱温度最小值
await port.FridgeMinSetting(Min, 1);
}
if (range == null || range[0] == null || (range != null && range[1] != null && range[1] != newRange[1]))
{
//设定冰箱温度最大值
await port.FridgeMaxSetting(Max, 1);
}
}
}
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"保存成功", Duration = 4000 }
);
logger.Info($"修改冰箱设置");
}
}

View File

@ -0,0 +1,414 @@
@page "/"
@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="6">
@if (globalStateService.Operator != null)
{
//<RadzenText Style="" class="rz-color-white" TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">操作人:@globalStateService.Operator.NickName</RadzenText>
//<RadzenText onclick="@(() => { EditPassword(1); })" Style="" class="rz-color-white" TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">操作人:@globalStateService.Operator.NickName</RadzenText>
<RadzenProfileMenu prefix="" Click="MenuClick" Style="background-color:transparent;z-index:99">
<Template>
<RadzenText Style="" class="rz-color-white" TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">操作人:@globalStateService.Operator.NickName</RadzenText>
</Template>
<ChildContent>
<RadzenProfileMenuItem Text="录入指纹" Value="11" Icon="fingerprint"></RadzenProfileMenuItem>
<RadzenProfileMenuItem Text="录入签名" Value="21" Icon="line_weight"></RadzenProfileMenuItem>
<RadzenProfileMenuItem Text="修改密码" Value="31" Icon="password"></RadzenProfileMenuItem>
</ChildContent>
</RadzenProfileMenu>
}
@if (globalStateService.Reviewer != null)
{
//<RadzenText Style="" class="rz-color-white" TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">复核人:@globalStateService.Reviewer.NickName</RadzenText>
//<RadzenText onclick="@(() => { EditPassword(2); })" Style="" class="rz-color-white" TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">复核人:@globalStateService.Reviewer.NickName</RadzenText>
<RadzenProfileMenu prefix="" Click="MenuClick" Style="background-color:transparent">
<Template>
<RadzenText Style="" class="rz-color-white" TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">复核人:@globalStateService.Reviewer.NickName</RadzenText>
</Template>
<ChildContent>
<RadzenProfileMenuItem Text="录入指纹" Value="12" Icon="fingerprint"></RadzenProfileMenuItem>
<RadzenProfileMenuItem Text="录入签名" Value="22" Icon="line_weight"></RadzenProfileMenuItem>
<RadzenProfileMenuItem Text="修改密码" Value="32" Icon="password"></RadzenProfileMenuItem>
</ChildContent>
</RadzenProfileMenu>
}
</RadzenColumn>
<RadzenColumn Size="3">
<div @onclick="@(() => { changeShifts(); })">
<RadzenIcon Icon="compare_arrows" Style="font-size:3rem;cursor: pointer;" class="rz-ripple" IconColor="white" />
<div>交接班</div>
</div>
<div style="clear:both"></div>
</RadzenColumn>
<RadzenColumn Size="2">
<RadzenIcon Icon="exit_to_app" Style="font-size:3rem;cursor: pointer;margin-left:-60px" 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 (globalStateService.Operator != null)
{
@if (!globalStateService.Operator.role.permissionIds.Any(id => id - 10 < 10))
{
<div class="mask">
<RadzenImage Path="images/no_auth.png" />
</div>
}
}
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal" Style="height: 50%;width:100%">
<RadzenStack class="home-menu rz-background-color-success-light rz-text-white rz-ripple" JustifyContent="JustifyContent.Center" @onclick="@(() => jump2Page(2))" Style="height: 100%;width:50%">
<RadzenText class="rz-color-white" TextStyle="TextStyle.H2" TextAlign="TextAlign.Center">入库</RadzenText>
@if (globalStateService.Operator != null)
{
@if (!globalStateService.Operator.role.permissionIds.Any(id => id - 20 > 0 && id - 20 < 10))
{
<div class="mask">
<RadzenImage Path="images/no_auth.png" />
</div>
}
}
</RadzenStack>
<RadzenStack class="home-menu rz-background-color-danger-lighter rz-text-white rz-ripple" JustifyContent="JustifyContent.Center" @onclick="@(() => jump2Page(6))" Style="height: 100%;width:50%">
<RadzenText class="rz-color-white" Style="margin-top:10px;margin-bottom:-10px" TextStyle="TextStyle.H2" TextAlign="TextAlign.Center">药盒</RadzenText>
<RadzenText class="rz-color-white" Style="margin-top:-10px;margin-bottom:10px" TextStyle="TextStyle.H2" TextAlign="TextAlign.Center">管理</RadzenText>
@if (globalStateService.Operator != null)
{
@if (!globalStateService.Operator.role.permissionIds.Any(id => id - 60 > 0 && id - 60 < 10))
{
<div class="mask">
<RadzenImage Path="images/no_auth.png" />
</div>
}
}
</RadzenStack>
</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 (globalStateService.Operator != null)
{
@if (!globalStateService.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 (globalStateService.Operator != null)
{
@if (!globalStateService.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 (globalStateService.Operator != null)
{
@if (!globalStateService.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 Radzen.DialogService dialogService;
@inject NotificationService _message
@inject NavigationManager na;
@inject TooltipService tooltipService
private List<Premission> userPremissions { get; set; } = new();
@inject GlobalStateService globalStateService;
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()
{
// 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 && (DateTime.Now-_portUtil.mouseClickTime).TotalSeconds > setting.Value.autoOutLog)
{
logger.Info($"设备{setting.Value.autoOutLog}内无人操作,用户【{globalStateService.Operator?.NickName}】自动退出登录,_portUtil.Operate:{_portUtil.Operate},totalSecond:{(DateTime.Now - _portUtil.dateTime).TotalSeconds},lastInputTime:{CheckComputerFreeState.GetLastInputTime()},autoOutLog:{setting.Value.autoOutLog}");
globalStateService.Operator.NickName = string.Empty;
globalStateService.Operator = null;
if (globalStateService.Reviewer != null)
{
globalStateService.Reviewer.NickName = string.Empty;
globalStateService.Reviewer = null;
}
await InvokeAsync(StateHasChanged);
stop();
}
else
{
logger.Info($"{setting.Value.autoOutLog}未自动退出{(DateTime.Now - _portUtil.dateTime).TotalSeconds}-{(DateTime.Now - _portUtil.mouseClickTime).TotalSeconds}");
next();
}
}
else
{
next();
}
}
catch (Exception ex)
{
logger.Info($"检查是否自动退出循环异常:{ex.Message}");
next();
}
}
});
}
base.OnInitialized();
}
public void Dispose()
{
timer?.Dispose();
}
async void init()
{
var b = await dialogService.OpenAsync<InitPage>(
$"调拨入库详情",
new Dictionary<string, object>() { },
new DialogOptions() { ShowTitle = false, Style = "min-height:auto;min-width:auto;width:auto", CloseDialogOnEsc = false, Resizable = true, Draggable = true, ShowClose = false }
);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
base.OnAfterRender(firstRender);
if (firstRender && !globalStateService.isInit)
{
this.init();
}
}
async void jump2Page(int parentId)
{
bool a = true;
if ((setting.Value.loginMode == 2 && (globalStateService.Operator == null || globalStateService.Reviewer == null))
|| setting.Value.loginMode == 1 && globalStateService.Operator == null)
{
a = await dialogService.OpenAsync<LoginDialog>(
"",
null,
new DialogOptions() { Width = "55vw", Resizable = false, Draggable = false, ShowClose = false, ShowTitle = false });
}
// bool a = globalStateService.Operator != null;
// if (!a)
// {
// a = await dialogService.OpenAsync<LoginDialog>(
// "",
// null,
// new DialogOptions() { Width = "55vw", Resizable = false, Draggable = false, ShowClose = false, ShowTitle = false });
// }
if (a)
{
List<int> childrenIds = globalStateService.Operator.role.permissionIds.Where(id => id - (parentId * 10) > 0 && id - (parentId * 10) < 10).ToList();
if (childrenIds.Count > 0)
{
currentPage = false;
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);
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"没有权限不能访问", Duration = 3000 }
);
await InvokeAsync(StateHasChanged);
}
}
}
void logout()
{
if (globalStateService.Operator != null)
{
globalStateService.Operator = null;
globalStateService.Reviewer = null;
}
else
{
Environment.Exit(0);
}
}
//修改密码
async void EditPassword(int i)
{
//修改复核人
await dialogService.OpenAsync<EditPasswordDialog>(
"",
new Dictionary<string, object>() { { "userI", i } },
new DialogOptions() { Width = "55vw", Resizable = false, Draggable = false, ShowClose = false, ShowTitle = false });
}
async void MenuClick(RadzenProfileMenuItem item)
{
string strValue = item.Value.Substring(0, 1);
Pojo.User user = new Pojo.User();
switch (strValue)
{
case "1":
int userId = 0;
if (item.Value == "11")
{
user = globalStateService.Operator;
}
else
{
user = globalStateService.Reviewer;
}
await dialogService.OpenAsync<FingerRegDialog>(
$"录入指纹-{user.Username}",
new Dictionary<string, object>() { { "userId", user.Id } },
new DialogOptions() { Width = "55vw", Resizable = true, Draggable = false, ShowClose = false }
);
break;
case "2":
if (item.Value == "21")
{
user = globalStateService.Operator;
}
else
{
user = globalStateService.Reviewer;
}
await dialogService.OpenAsync<SignatureDialog>(
$"签名-{user.NickName}",
new Dictionary<string, object>() { { "user", user } },
new DialogOptions() { Width = "55vw", Resizable = true, Draggable = false, ShowClose = true }
);
break;
case "3":
if (item.Value == "31")
{
user = globalStateService.Operator;
}
else
{
user = globalStateService.Reviewer;
}
int userI = Convert.ToInt32(item.Value.Substring(1, 1));
await dialogService.OpenAsync<EditPasswordDialog>(
$"修改密码-{user.Username}",
new Dictionary<string, object>() { { "userI", userI } },
new DialogOptions() { Width = "55vw", Resizable = false, Draggable = false, ShowClose = false, ShowTitle = true }
);
break;
}
}
//交接班
async void changeShifts()
{
//修改复核人
await dialogService.OpenAsync<ChangeShifts>(
"",
new Dictionary<string, object>() { { "userI", 1 } },
new DialogOptions() { Width = "55vw", Resizable = false, Draggable = false, ShowClose = false, ShowTitle = false });
}
}

View File

@ -0,0 +1,237 @@
@page "/login"
@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;
PortUtil.mouseClickTime = DateTime.Now;
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;
PortUtil.mouseClickTime = DateTime.Now;
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;
PortUtil.mouseClickTime = DateTime.Now;
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);
}
}

View File

@ -0,0 +1,160 @@
@page "/init"
@using MasaBlazorApp3.Pojo.Config;
@using MasaBlazorApp3.Pojo.Vo;
@using MasaBlazorApp3.Util;
@using Microsoft.Extensions.Options;
@using Newtonsoft.Json;
@using log4net;
<RadzenStack AlignItems="AlignItems.Center" Gap="2rem" class="rz-p-12">
<RadzenImage Path="images/community.svg" Style="width: 200px;" AlternateText="community" />
<RadzenText TextStyle="TextStyle.H6">加载程序必要连接中,请稍等。。。</RadzenText>
<RadzenText TextStyle="TextStyle.H6">@msg</RadzenText>
<RadzenText TextStyle="TextStyle.H6">@errMsg</RadzenText>
</RadzenStack>
@code {
@inject Radzen.DialogService dialogService;
@inject IOptions<DrawerConfig> setting;
@inject NotificationService _message;
@inject PortUtil PortUtil;
@inject FingerprintUtil FingerprintUtil;
@inject GlobalStateService globalStateService;
@inject IOptions<PortConfig> portSetting;
string msg;
string errMsg;
private readonly ILog logger = LogManager.GetLogger(typeof(InitPage));
protected override async Task OnInitializedAsync()
{
base.OnInitializedAsync();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
base.OnAfterRender(firstRender);
if (firstRender)
{
await Task.Delay(15);
msg = "开始连接指纹模块";
InvokeAsync(StateHasChanged);
try
{
bool flag = await FingerprintUtil.ConnectionMain();
if (flag)
{
msg = "指纹模块连接成功";
}
else
{
msg = "指纹模块连接失败";
}
InvokeAsync(StateHasChanged);
}
catch (Exception e)
{
msg = "指纹模块连接失败";
errMsg += "【指纹模块连接失败】";
logger.Info($"指纹模块连接失败【{e.Message}】");
InvokeAsync(StateHasChanged);
}
await Task.Delay(500);
// msg = "开始连接抽屉串口";
// InvokeAsync(StateHasChanged);
// try
// {
// PortUtil.drawerSerial.Open();
// logger.Info($"抽屉串口打开结果【{PortUtil.drawerSerial.IsOpen}】");
// msg = "抽屉串口连接成功";
// InvokeAsync(StateHasChanged);
// }
// catch (Exception e)
// {
// msg = "抽屉串口连接失败";
// errMsg += "【抽屉串口连接失败】";
// logger.Info($"抽屉串口连接失败【{e.Message}】");
// InvokeAsync(StateHasChanged);
// }
// await Task.Delay(500);
msg = "开始连接CanBus模块";
InvokeAsync(StateHasChanged);
try
{
PortUtil.canBusSerial.Open();
logger.Info($"CanBus模块打开结果【{PortUtil.canBusSerial.IsOpen}】");
msg = "CanBus模块连接成功";
InvokeAsync(StateHasChanged);
}
catch (Exception e)
{
msg = "CanBus模块连接失败";
errMsg += "【CanBus模块连接失败】";
logger.Info($"模块连接失败【{e.Message}】");
InvokeAsync(StateHasChanged);
}
await Task.Delay(500);
// msg = "开始连接第二个CanBus模块";
// InvokeAsync(StateHasChanged);
// try
// {
// PortUtil.canBusSerialTwo.Open();
// logger.Info($"第二个CanBus模块打开结果【{PortUtil.canBusSerialTwo.IsOpen}】");
// msg = "CanBus模块连接成功";
// InvokeAsync(StateHasChanged);
// }
// catch (Exception e)
// {
// msg = "第二个CanBus模块连接失败";
// logger.Info($"模块连接失败【{e.Message}】");
// errMsg += "【第二个CanBus模块连接失败】";
// InvokeAsync(StateHasChanged);
// }
// await Task.Delay(500);
msg = "开始连接条码扫描模块";
InvokeAsync(StateHasChanged);
try
{
PortUtil.scanCodeSerial.Open();
logger.Info($"条码扫描模块打开结果【{PortUtil.scanCodeSerial.IsOpen}】");
msg = "条码扫描模块连接成功";
InvokeAsync(StateHasChanged);
}
catch (Exception e)
{
msg = "条码扫描模块连接失败";
errMsg += "【条码扫描模块连接失败】";
logger.Info($"条码扫描模块打开结果【{e.Message}】");
InvokeAsync(StateHasChanged);
}
// if (portSetting.Value.fridgePortExist)
// {
// try
// {
// PortUtil.fridgeSerial.Open();
// logger.Info($"冰箱串口打开结果【{PortUtil.fridgeSerial.IsOpen}】");
// msg = "冰箱串口连接成功";
// InvokeAsync(StateHasChanged);
// }
// catch (Exception e)
// {
// msg = "冰箱串口打开失败";
// errMsg += "【冰箱串口打开失败】";
// logger.Info($"冰箱串口打开失败【{e.Message}】");
// InvokeAsync(StateHasChanged);
// }
// }
globalStateService.isInit = true;
dialogService.Close();
}
}
}

View File

@ -0,0 +1,122 @@
@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">
<Template Context="InPharmacyId">
@(InPharmacyId.InPharmacyId == "0623" ? "麻醉科" : InPharmacyId.InPharmacyId)
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="出库药房" Property="OutPharmacyId">
<Template Context="OutPharmacyId">
@(OutPharmacyId.OutPharmacyId == "070103" ? "药剂科" : OutPharmacyId.OutPharmacyId)
</Template>
</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.Now;
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();
}
}
}

View File

@ -0,0 +1,489 @@
@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" Width="6vw">
<Template Context="s">
@s.DrawerNo - @s.ColNo
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="库存" Property="Quantity" Width="6vw"></RadzenDataGridColumn>
@* <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="效期" Property="EffDate"></RadzenDataGridColumn> *@
<RadzenDataGridColumn Title="批次" Property="ManuNo" Filterable="false" Width="25vw">
<Template Context="ManuNo">
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@ManuNo.ManuNo</RadzenText>
@if (ManuNo.Quantity > 0)
{
<RadzenText TextStyle="TextStyle.Caption">
@ManuNo.ManuNo
</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>
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
}
else
{
<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>
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
{
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
}
else
{
<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="AddQuantity" Width="6vw">
<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>
<Template Context="cstock">
@($"{cstock.AddQuantity}{cstock.Drug.SmallUnit}")
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</Template>
<Columns>
<RadzenDataGridColumn Property="Drug.DrugName" Title="药品" Width="25vw" />
<RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" Width="6vw" />
<RadzenDataGridColumn Property="Invoice.DrugManuNo" Title="批次" Width="10vw">
<Template Context="ManuNo">
@(ManuNo.Invoice.DrugManuNo == "X" ? "无" : ManuNo.Invoice.DrugManuNo)
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="Invoice.EffDate" Title="效期" Width="6vw" />
<RadzenDataGridColumn Property="Quantity" Title="单据数量" Width="6vw">
<Template Context="invoice">
@($"{invoice.Quantity}{invoice.Invoice.Units}")
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="StockQuantity" Title="总库存" Width="6vw" />
</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; }
//称重取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// 当前操作的库位号列表
public List<int> ColNos { get; set; } = new List<int>();
int currentCol = 0;
//开抽屉前操作标识
private List<string> _flagList = new List<string>();
async Task StartAdd()
{
if (data.Any(it => it.Quantity != it.ChannelStocks.Sum(cs => cs.AddQuantity)))
{
for (int i = 0; i < data.Count; i++)
{
if (data[i].Quantity != data[i].ChannelStocks.Sum(cs => cs.AddQuantity))
{
if (data[i].Drug != null && data[i].Drug.SmallUnit != data[i].Invoice.Units && data[i].Quantity * data[i].Drug.ConvertRatio != data[i].ChannelStocks.Sum(cs => cs.AddQuantity))
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请填写正确的入库数量!", Duration = 4000 }
);
}
}
}
}
else
{
await OpenDrawer();
}
}
async Task CancelOpera()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
status = 0;
dialogService.Close(false);
}
async Task OpenDrawer()
{
this.status = 1;
await Task.Delay(200);
// 解析需要打开的抽屉列表
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];
for (int j = 0; j < data[index].ChannelStocks.Count; j++)
{
// _flagList.Add(flag);
//单支-查数
if (data[index].ChannelStocks[j].BoardType.ToString().Contains("2"))
{
byte[] quantity = await PortUtil.CheckQuantityByDrawer(data[index].ChannelStocks[j].DrawerNo);
data[index].BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
logger.Info($"单支抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", data[index].BeforeQuantity)}】");
await PortUtil.NoLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast<int>().ToArray());
}
//称重-查数
if (data[index].ChannelStocks[j].BoardType.ToString().Contains("6"))
{
PortUtil.DrawerNo = data[index].ChannelStocks[j].DrawerNo;// drawerNo;
PortUtil.ColNoLst.Add(data[index].ChannelStocks[j].ColNo);
data[index].BeforeQuantity[data[index].ChannelStocks[j].ColNo - 1] = await PortUtil.CheckQuantityForSingleForErZhong(data[index].ChannelStocks[j].ColNo);
logger.Info($"称重抽屉【{data[index].ChannelStocks[j].DrawerNo}】,开抽屉前检测数量【{string.Join(",", data[index].BeforeQuantity)}】");
await Task.Delay(200);
}
//药盒-开药盒
if (data[index].ChannelStocks[j].BoardType.ToString().Contains("3"))
{
PortUtil.DrawerNo = data[index].ChannelStocks[j].DrawerNo;
await PortUtil.OpenBoxByColNoForErZhong(data[index].ChannelStocks[j].ColNo);
await Task.Delay(200);
}
}
var b = await PortUtil.OpenDrawerStatusForErZhong(drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,加药");
options._data = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
RestData();
stop();
}
}
// 检测状态
else if (options._data == 1)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatusForErZhong(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
options._data = 0;
if (setting.Value.single.Contains(drawerNo))
{
}
if (index == drawerNos.Count - 1)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"加药完成,请,点击完成按钮进行确认");
this.status = 2;
string alertMessage = string.Empty;
bool cancelFlag = false;
for (int i = 0; i < data.Count; i++)
{
for (int j = 0; j < data[i].ChannelStocks.Count; j++)
{
string flag = "关" + data[i].ChannelStocks[j].DrawerNo.ToString() + data[i].ChannelStocks[j].ColNo.ToString();
if (!_flagList.Contains(flag))
{
_flagList.Add(flag);
//关闭抽屉后获取称重数量
PortUtil.DrawerNo = data[i].ChannelStocks[j].DrawerNo;// drawerNo;
// 判断是否为称重抽屉
//单支-查数
if (data[i].ChannelStocks[j].BoardType.ToString().Contains("6"))
{
PortUtil.ColNoLst = this.ColNos;
AfterQuantity[data[i].ChannelStocks[j].ColNo - 1] = await PortUtil.CheckQuantityForSingleForErZhong(data[i].ChannelStocks[j].ColNo);
logger.Info($"称重抽屉,关抽屉后检测数量【{string.Join(",", AfterQuantity)}】");
WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStocks[j].ColNo - 1] - AfterQuantity[data[i].ChannelStocks[j].ColNo - 1];
if (data[i].ChannelStocks[j].Quantity != WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1])
{
//称重自动计数数量与实际要取数量不一致弹出提示,确认后保存数据
alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1]}】";
}
}
//单支-查数
if (data[i].ChannelStocks[j].BoardType.ToString().Contains("2"))
{
byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo);
AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
logger.Info($"单支抽屉,关抽屉后检测数量【{string.Join(",", AfterQuantity)}】");
WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStocks[j].ColNo - 1] - AfterQuantity[data[i].ChannelStocks[j].ColNo - 1];
if (data[i].ChannelStocks[j].Quantity != WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1])
{
alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].ChannelStocks[j].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1]}】";
}
}
if (!string.IsNullOrEmpty(alertMessage))
{
//弹出确认对话框
alertMessage += "应取数与实际取出数不一致确认要保存吗?";
//弹出确认提示框
var confirm = await dialogService.OpenAsync<ConfirmDialog>
(
$"保存确认",
new Dictionary<string, object>
() { { "confirmInfo", alertMessage } },
new DialogOptions()
{ Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
if (!confirm)
{
RestData();
logger.Info("取消保存");
cancelFlag = true;
// 关闭弹窗
dialogService.Close(false);
break;
}
else
{
logger.Info(alertMessage);
}
alertMessage = string.Empty;
}
}
}
if (cancelFlag)
{
break;
}
}
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))
{
}
}
});
}
void RestData()
{
this.status = 0;
_flagList.Clear();
this.ColNos.Clear();
}
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);
}
}

View File

@ -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();
}
}
}

View File

@ -0,0 +1,452 @@
@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>
<Template Context="cstock">
@($"{cstock.TakeQuantity}{cstock.Drug.SmallUnit}")
</Template>
</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="单据数量" Width="6vw">
<Template Context="invoice">
@($"{invoice.Quantity}{invoice.Invoice.Units}")
</Template>
</RadzenDataGridColumn>
<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; }
//称重取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// 当前操作的库位号列表
public List<int> ColNos { get; set; } = new List<int>();
int currentCol = 0;
//开抽屉前操作标识
private List<string> _flagList = new List<string>();
int[] BeforeQuantity = new int[9];
int[] AfterQuantity = new int[9];
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()
{
RestData();
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;
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];
for (int j = 0; j < data[index].ChannelStocks.Count; j++)
{
//单支-查数
if (data[index].ChannelStocks[j].BoardType.ToString().Contains("2"))
{
byte[] quantity = await PortUtil.CheckQuantityByDrawer(data[index].ChannelStocks[j].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());
}
//称重-查数
if (data[index].ChannelStocks[j].BoardType.ToString().Contains("6"))
{
PortUtil.DrawerNo = data[index].ChannelStocks[j].DrawerNo;// drawerNo;
PortUtil.ColNoLst.Add(data[index].ChannelStocks[j].ColNo);
data[j].BeforeQuantity[data[index].ChannelStocks[j].ColNo - 1] = await PortUtil.CheckQuantityForSingleForErZhong(data[index].ChannelStocks[j].ColNo);
logger.Info($"称重抽屉【{data[index].ChannelStocks[j].DrawerNo}】,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】");
await Task.Delay(200);
}
//药盒-开药盒
if (data[index].ChannelStocks[j].BoardType.ToString().Contains("3"))
{
PortUtil.DrawerNo = data[index].ChannelStocks[j].DrawerNo;
await PortUtil.OpenBoxByColNoForErZhong(data[index].ChannelStocks[j].ColNo);
await Task.Delay(200);
}
}
// // 判断是否为单支抽屉
// if (setting.Value.single != null && 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());
// }
// // 称重抽屉关上则查数
// if (setting.Value.weigh != null && setting.Value.weigh.Contains(drawerNo))
// {
// for (int i = 0; i < data.Count; i++)
// {
// for (int j = 0; j < data[i].ChannelStocks.Count; j++)
// {
// if (data[i].ChannelStocks[j].BoardType.ToString().Contains("6"))
// {
// PortUtil.DrawerNo = drawerNo;
// PortUtil.ColNoLst.Add(data[i].ChannelStocks[j].ColNo);
// BeforeQuantity[data[i].ChannelStocks[j].ColNo - 1] = await PortUtil.CheckQuantityForSingle(data[i].ChannelStocks[j].ColNo);
// logger.Info($"称重抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】");
// await Task.Delay(200);
// }
// }
// }
// }
var b = await PortUtil.OpenDrawerStatusForErZhong(drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药");
options._data = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
RestData();
stop();
}
}
// 检测状态
else if (options._data == 1)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatusForErZhong(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
options._data = 0;
if (setting.Value.single.Contains(drawerNo))
{
}
if (index == drawerNos.Count - 1)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认");
this.status = 2;
string alertMessage = string.Empty;
bool cancelFlag = false;
for (int i = 0; i < data.Count; i++)
{
for (int j = 0; j < data[i].ChannelStocks.Count; j++)
{
string flag = "关" + data[i].ChannelStocks[j].DrawerNo.ToString() + data[i].ChannelStocks[j].ColNo.ToString();
if (!_flagList.Contains(flag))
{
_flagList.Add(flag);
// 判断是否为称重抽屉
if (data[i].ChannelStocks[j].BoardType.ToString().Contains("6"))
{
//关闭抽屉后获取称重数量
PortUtil.DrawerNo = data[i].ChannelStocks[j].DrawerNo;// drawerNo;
PortUtil.ColNoLst = this.ColNos;
AfterQuantity[data[i].ChannelStocks[j].ColNo - 1] = await PortUtil.CheckQuantityForSingleForErZhong(data[i].ChannelStocks[j].ColNo);
logger.Info($"称重抽屉,关抽屉后检测数量【{string.Join(",", AfterQuantity)}】");
WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStocks[j].ColNo - 1] - AfterQuantity[data[i].ChannelStocks[j].ColNo - 1];
if (data[i].ChannelStocks[j].Quantity != WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1])
{
//称重自动计数数量与实际要取数量不一致弹出提示,确认后保存数据
alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1]}】";
}
}
if (data[i].ChannelStocks[j].BoardType.ToString().Contains("2"))
{
byte[] quantity = await PortUtil.CheckQuantityByDrawer(data[i].ChannelStocks[j].DrawerNo);
AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
logger.Info($"单支抽屉,关抽屉后检测数量【{string.Join(",", AfterQuantity)}】");
WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1] = BeforeQuantity[data[i].ChannelStocks[j].ColNo - 1] - AfterQuantity[data[i].ChannelStocks[j].ColNo - 1];
if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1])
{
alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].ChannelStocks[j].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1]}】";
}
}
if (!string.IsNullOrEmpty(alertMessage))
{
//弹出确认对话框
alertMessage += "应取数与实际取出数不一致确认要保存吗?";
//弹出确认提示框
var confirm = await dialogService.OpenAsync<ConfirmDialog>(
$"保存确认",
new Dictionary<string, object>() { { "confirmInfo", alertMessage } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
logger.Info(alertMessage);
if (!confirm)
{
RestData();
logger.Info("取消保存");
cancelFlag = true;
// 关闭弹窗
dialogService.Close(false);
break;
}
else
{
logger.Info(alertMessage);
}
alertMessage = string.Empty;
}
}
}
if (cancelFlag)
{
break;
}
}
stop();
}
else
{
index += 1;
next();
}
}
else
{
if (setting.Value.single != null && 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]}】");
});
});
}
//是药盒抽屉开药盒
if (setting.Value.box != null && setting.Value.box.Contains(drawerNo) && currentCol != null)
{
PortUtil.DrawerNo = drawerNo;
await PortUtil.OpenBoxByColNoForErZhong(currentCol);
ColNos.Add(currentCol);
currentCol = 0;
await Task.Delay(200);
}
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))
{
}
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
this.BeforeQuantity = new int[9];
this.AfterQuantity = new int[9];
currentCol = 0;
ColNos.Clear();
_flagList.Clear();
}
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)
{
currentCol = args.Data.ColNo;
Grid.EditRow(args.Data);
}
}

View File

@ -0,0 +1,247 @@
@page "/loginDialog"
@using MasaBlazorApp3.Pojo.Config;
@using MasaBlazorApp3.Pojo.Vo;
@using MasaBlazorApp3.Util;
@using Microsoft.Extensions.Options;
@using Newtonsoft.Json;
@using log4net;
<style>
.rz-dialog-content {
padding: 0 !important;
}
</style>
<RadzenRow Gap="0" Style="overflow: hidden;width:100%;height:100%">
<RadzenColumn Size="12" SizeMD="5">
<RadzenCard class="rz-shadow-0 rz-border-radius-0 rz-text-align-center rz-p-12 align-items-center justify-content-center" 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">
<!--@onfocusin="@(() => Util.VirtualKeyboardHelper.ShowVirtualKeyboard())"-->
<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>
@code {
@inject Radzen.DialogService dialogService;
@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;
@inject IOptions<DrawerConfig> drawerSetting;
private readonly ILog logger = LogManager.GetLogger(typeof(LoginDialog));
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 async Task 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;
logger.Info($"双人登录模式:操作人【{globalStateService.Operator.NickName}】复核人【{user.NickName}】登录");
PortUtil.mouseClickTime = DateTime.Now;
dialogService.Close(true);
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"验证重复,请使用其他账号", Duration = 3000 }
);
}
}
else
{
// 此时为第一人登录
globalStateService.Operator = user;
InvokeAsync(StateHasChanged);
}
}
// 操作人为第二人登录
else
{
// 判断复核人是否已经登录,已经登录说明此时为第二人登录
if (globalStateService.Reviewer != null)
{
// 判断是否还是复核人的验证
if (globalStateService.Reviewer.Id != user.Id)
{
FingerprintUtil.axCZKEM1.OnAttTransactionEx -= axCZKEM1_OnAttTransactionEx;
globalStateService.Operator = user;
logger.Info($"双人登录模式:操作人【{user.NickName}】复核人【{globalStateService.Reviewer.NickName}】登录");
PortUtil.mouseClickTime = DateTime.Now;
dialogService.Close(true);
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"验证重复,请使用其他账号", Duration = 3000 }
);
}
}
else
{
// 此时为第一人登录
globalStateService.Reviewer = user;
InvokeAsync(StateHasChanged);
}
}
}
else
{
FingerprintUtil.axCZKEM1.OnAttTransactionEx -= axCZKEM1_OnAttTransactionEx;
globalStateService.Operator = user;
PortUtil.mouseClickTime = DateTime.Now;
logger.Info($"单人登录模式:用户【{user.NickName}】登录");
dialogService.Close(true);
}
//查询所有标签抽屉,设置标签灯为常亮
int[] labels = drawerSetting.Value.label;
for (int i = 0; i < labels.Length; i++)
{
await PortUtil.setLighting(labels[i]);
}
}
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);
loginModel.Username = "";
loginModel.Password = "";
}
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 async void Exit()
{
//查询所有标签抽屉,设置标签灯为灭灯
int[] labels = drawerSetting.Value.label;
for (int i = 0; i < labels.Length; i++)
{
await PortUtil.setOffLight(labels[i]);
}
if (globalStateService.Operator != null)
{
globalStateService.Operator = null;
globalStateService.Reviewer = null;
}
dialogService.Close(false);
}
}

View File

@ -0,0 +1,74 @@
@page "/manage/setting/login"
@page "/manage/setting"
@using Newtonsoft.Json.Linq
@using log4net
@layout SettingLayout
<div class="main">
<div class="top-row px-4">
<RadzenButton Icon="account_circle" Style="margin-left: auto;" Click="@SaveMethod">
<ChildContent>
保存设置
</ChildContent>
</RadzenButton>
</div>
<div class="content px-4">
<RadzenCard class="rz-my-6">
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Start" Wrap="FlexWrap.Wrap">
<RadzenStack Orientation="Orientation.Vertical" Gap="4px">
登录模式
<RadzenRadioButtonList Value=@loginValue TValue="int" Change=@(args => loginValue = args)>
<Items>
<RadzenRadioButtonListItem Text="单人登录" Value="1" />
<RadzenRadioButtonListItem Text="双人登录" Value="2" />
</Items>
</RadzenRadioButtonList>
</RadzenStack>
@* <RadzenStack Orientation="Orientation.Vertical" Gap="4px">
优先登录
<RadzenRadioButtonList Value=@preValue TValue="int" Change=@(args => preValue = args)>
<Items>
<RadzenRadioButtonListItem Text="操作人" Value="1" />
<RadzenRadioButtonListItem Text="审核人" Value="2" />
</Items>
</RadzenRadioButtonList>
</RadzenStack> *@
</RadzenStack>
</RadzenCard>
</div>
</div>
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.setting> setting;
@inject Microsoft.Extensions.Options.IOptions<Pojo.Config.SettingConfig> setting;
@inject NotificationService _message
@code {
private readonly ILog logger = LogManager.GetLogger(typeof(LoginDialog));
int loginValue = 1;
// int preValue = 1;
protected override void OnInitialized()
{
loginValue = setting.Value.loginMode;
base.OnInitialized();
}
//保存
async Task SaveMethod()
{
// 获取当前工作目录
string currentDirectory = Directory.GetCurrentDirectory();
// setting.Value.fridgeState = fridgeStateValue;
// setting.Value.alertState = alertStateValue;
// setting.Value.temperatureRange = temperatureRange;
string filePath = Path.Combine(currentDirectory, "appsettings.json");
string jsonString = File.ReadAllText(filePath);
var jsonNode = JObject.Parse(jsonString);
jsonNode["setting"]["loginMode"] = loginValue;
var options = new JsonSerializerOptions { WriteIndented = true };
File.WriteAllText(filePath, jsonNode.ToString(Newtonsoft.Json.Formatting.Indented));
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"保存成功", Duration = 4000 }
);
logger.Info($"修改用户登录设置");
}
}

View File

@ -0,0 +1,134 @@
@page "/take/record/{type}"
@page "/add/record/{type}"
@page "/return/record1/{type}"
@page "/return/record2/{type}"
@page "/stock/record/{type}"
@using MasaBlazorApp3.Report
<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" @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" @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>
@* <RadzenRow AlignItems="AlignItems.Center">
<RadzenButton Icon="download" Text="库存导出" Variant="Variant.Outlined" Click="StockExport" />
<RadzenButton Icon="download" Text="专用账册导出" Variant="Variant.Outlined" Click="AccountBookExport" />
</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();
}
//库存导出
void StockExport()
{
}
//专用账册导出
void AccountBookExport()
{
// string drugId = drugName != null ? drugName.Split('/').Last().Trim():"";
// GridReportUtil gridReportUtil = new GridReportUtil();
GridReportUtil.PrintReport("stock_template.grf", null);
}
}

View File

@ -0,0 +1,343 @@
@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="@Cancel" 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; }
//称重取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//开抽屉前操作标识
List<string> DrawerNoColNoList = new List<string>();
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;
await Task.Delay(200);
// 解析需要打开的抽屉列表
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());
}
for (int i = 0; i < data.Count; i++)
{
if (!DrawerNoColNoList.Contains(data[i].ChannelStock.DrawerNo.ToString() + data[i].ChannelStock.ColNo))
{
if (data[i].ChannelStock.BoardType.ToString().Contains("6"))
{
PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;
PortUtil.ColNoLst.Add(data[i].ChannelStock.ColNo);
data[i].BeforeQuantity[data[i].ChannelStock.ColNo - 1] = await PortUtil.CheckQuantityForSingleForErZhong(data[i].ChannelStock.ColNo);
logger.Info($"称重抽屉,开抽屉前检测数量【{string.Join(",", orderTakeVo.BeforeQuantity)}】");
await Task.Delay(200);
}
//是药盒抽屉开药盒
if (data[i].ChannelStock.BoardType.ToString().Contains("3"))
{
PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;
await PortUtil.OpenBoxByColNoForErZhong(data[i].ChannelStock.ColNo);
await Task.Delay(200);
}
DrawerNoColNoList.Add(data[i].ChannelStock.DrawerNo.ToString() + data[i].ChannelStock.ColNo);
}
}
var b = await PortUtil.OpenDrawerStatusForErZhong(drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药");
orderTakeVo.Status = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
RestData();
stop();
}
}
// 检测状态
else if (orderTakeVo.Status == 1)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatusForErZhong(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
data.ForEach(cl =>
{
if (cl.ChannelStock.DrawerNo == drawerNo)
{
cl.GetQuantity = cl.Quantity;
}
});
orderTakeVo.Status = 2;
if (options._data == drawerNos.Count - 1)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认");
this.status = 2;
string alertMessage = string.Empty;
//检查是否称重抽屉,核对实际取出数量是否与应取数量一致,不一致则弹出提示
for (int i = 0; i < data.Count; i++)
{
if (data[i].ChannelStock.BoardType.ToString().Contains("6"))
{
PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;// drawerNo;
PortUtil.ColNoLst.Add(data[i].ChannelStock.ColNo);
orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1] = await PortUtil.CheckQuantityForSingleForErZhong(data[i].ChannelStock.ColNo);
logger.Info($"称重抽屉,关抽屉后检测数量【{string.Join(",", orderTakeVo.AfterQuantity)}】");
WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
{
//称重自动计数数量与实际要取数量不一致弹出提示,确认后保存数据
alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
}
await Task.Delay(200);
}
if (data[i].ChannelStock.BoardType.ToString().Contains("2"))
{
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)}】");
WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = orderTakeVo.BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
{
alertMessage += $"{data[i].Drug.DrugName}应取数量【{orderTakeVo.Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
}
}
}
if (!string.IsNullOrEmpty(alertMessage))
{
//弹出确认对话框
alertMessage += "应取数与实际取出数不一致确认要保存吗?";
//弹出确认提示框
var confirm = await dialogService.OpenAsync<ConfirmDialog>(
$"保存确认",
new Dictionary<string, object>() { { "confirmInfo", alertMessage } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
logger.Info(alertMessage);
if (!confirm)
{
RestData();
logger.Info("取消保存");
// 关闭弹窗
dialogService.Close(false);
}
}
stop();
}
else
{
options._data += 1;
next();
}
}
else
{
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))
{
}
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
data.ForEach(it =>
{
it.Status = 0;
it.BeforeQuantity = new int[9];
it.AfterQuantity = new int[9];
});
this.WeightFinnalQuantity = new int[9];
DrawerNoColNoList.Clear();
}
void Cancel()
{
RestData();
// 关闭弹窗
dialogService.Close(false);
}
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();
}
}

View File

@ -0,0 +1,289 @@
@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="@Cancel" 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.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,放置退回药品");
options._data = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"处方退药抽屉【{drawerNo}】打开失败");
RestData();
stop();
}
}
// 检测状态
else if (options._data == 1)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatus2(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
options._data = 0;
if (setting.Value.single.Contains(drawerNo))
{
}
if (index == drawerNos.Count - 1)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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))
{
}
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
}
void Cancel()
{
RestData();
// 关闭弹窗
dialogService.Close(false);
}
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);
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -0,0 +1,483 @@
@page "/Box/Plan"
<style>
.rz-custom-header {
width: 100%;
}
</style>
<div class="container-fluid">
<div class="row">
<div class="col-12 mb-4">
<RadzenFieldset>
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="12" Style="margin-top:12px">
<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="@InsertPlanRow" Text="新增套餐" />
</RadzenColumn>
</RadzenRow>
</RadzenStack>
</RadzenFieldset>
</div>
<div class="col-4 mb-4">
<RadzenDataGrid @ref="grid"
LoadData="@LoadData"
@bind-Value="@SelectedPlan"
IsLoading="@isLoading"
Count="@count"
EmptyText="无数据"
Data="@_forecasts"
AllowColumnResize="true" AllowAlternatingRows="false"
SelectionMode="DataGridSelectionMode.Single" RowUpdate="@((Plan di) => { OnUpdatePlanRow(di); })" RowCreate="@((Plan di) => { OnCreatePlanRow(di); })"
AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ColumnWidth="100px" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
<Columns>
<RadzenDataGridColumn Frozen="true" Title="套餐名称" Property="Name">
<EditTemplate Context="planInfo">
<RadzenTextBox Name="Name" @bind-Value="planInfo.Name" Style="width:100%; display: block;" />
<RadzenRequiredValidator Text="请填写套餐名称" Component="Name" Popup="true" />
</EditTemplate>
</RadzenDataGridColumn>
@* <RadzenDataGridColumn Width="200px" Title="套餐描述" Property="Description">
<EditTemplate Context="planInfo">
<RadzenTextBox Name="Description" @bind-Value="planInfo.Description" Style="width:100%;display:block;" />
<RadzenRequiredValidator Text="请填写套餐描述" Component="Description" Popup="true" />
</EditTemplate>
</RadzenDataGridColumn> *@
<RadzenDataGridColumn Context="planInfo" Title="操作" Filterable="false" Sortable="false" TextAlign="TextAlign.Left" Frozen="true" FrozenPosition="FrozenColumnPosition.Right" Width="5rem">
<Template Context="planInfo">
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@(args => EditPlanRow(planInfo))" @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 => DeletePlanRow(planInfo))" @onclick:stopPropagation="true">
</RadzenButton>
</Template>
<EditTemplate Context="planInfo">
<RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => SavePlanRow(planInfo))" aria-label="Save">
</RadzenButton>
<RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@((args) => CancelPlanEdit(planInfo))" 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 => DeletePlanRow(planInfo))" aria-label="Delete">
</RadzenButton>
</EditTemplate>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</div>
<div class="col-8 mb-4">
<RadzenDataGrid @ref="PlanDetailsGrid" EmptyText="无数据"
Data="@(SelectedPlan?.FirstOrDefault()?._PlanDetails)"
RowUpdate="@((PlanDetails pd) => { OnUpdateRow(pd); })"
RowCreate="@((PlanDetails pd) => { OnCreateRow(pd); })"
KeyProperty="Id"
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" Width="3rem">
<Template Context="data">
@(SelectedPlan.FirstOrDefault()?._PlanDetails.IndexOf(data) + 1)
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="药品" Property="_DrugInfo.DrugName" Width="15rem">
<Template Context="data">
<RadzenText TextStyle="TextStyle.Body1"><b>@(data._DrugInfo?.DrugName)</b></RadzenText>
<RadzenText TextStyle="TextStyle.Body1"><b>@(data._DrugInfo?.DrugSpec)</b></RadzenText>
</Template>
<EditTemplate Context="planDetails">
<RadzenDropDownDataGrid AllowVirtualization="true" Name="drugName" TValue="DrugInfo" @bind-Value="planDetails._DrugInfo" Data="@drugInfos"
Style="width:100%; display: block;" AllowFilteringByAllStringColumns="true" TextProperty="DrugName">
<Columns>
<RadzenDropDownDataGridColumn Property="DrugId" Title="药品编码" />
<RadzenDropDownDataGridColumn Property="DrugName" Title="名称" />
<RadzenDropDownDataGridColumn Property="DrugSpec" Title="规格" />
</Columns>
</RadzenDropDownDataGrid>
<RadzenCustomValidator Component="drugName" Validator="@(() => (planDetails._DrugInfo.DrugId != null))" Text="请选择药品" Popup=true />
<RadzenCustomValidator Component="drugName" Validator="@(() => ValidatroDrug(planDetails))" Text="套餐中已包含该药品" Popup=true />
</EditTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="基数" Property="BaseQuantity" Width="7rem">
<EditTemplate Context="planDetails">
<RadzenNumeric Name="BaseQuantity" @bind-Value="planDetails.BaseQuantity" Style="width:100%; display: block;" />
<RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Text="请填写正确的添加数量" Component="BaseQuantity" Popup="true" />
</EditTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="操作" Filterable="false" Sortable="false" TextAlign="TextAlign.Left" Frozen="true" FrozenPosition="FrozenColumnPosition.Right" Width="9rem">
<Template Context="planDetails">
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@(args => EditRow(planDetails))" @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(planDetails))" @onclick:stopPropagation="true">
</RadzenButton>
</Template>
<EditTemplate Context="planDetails">
<RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => InsertRow(planDetails))" aria-label="Save">
</RadzenButton>
<RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@((args) => CancelEdit(planDetails))" 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(planDetails))" 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 IPlanDao planDao;
@inject DialogService dialogService;
@inject NotificationService _message
@inject GlobalStateService globalStateService;
RadzenDataGrid<Plan> grid;
RadzenDataGrid<PlanDetails> PlanDetailsGrid;
bool isLoading;
int count;
private IEnumerable<Plan>? _forecasts;
IList<Plan>? SelectedPlan { get; set; } = new List<Plan>();
List<PlanDetails> SelectedPlanDetails = new List<PlanDetails>();
List<DrugInfo> drugInfos;
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
var result = await planDao.GetAllPlanInfo();
// Update the Data property
_forecasts = result.Desserts;
count = result.TotalDesserts;
SelectedPlan = new List<Plan>() { _forecasts.FirstOrDefault() };
isLoading = false;
drugInfos = result.Other;
}
// async Task LoadDetailDate(LoadDataArgs args)
// {
// // SelectedPlan = new List<Plan>() { await planDao.GetPlanById(SelectedPlan.FirstOrDefault().Id) };
// }
async Task reloadGrid()
{
await grid.Reload();
}
void OnUpdatePlanRow(Plan dl)
{
// Reset(dl);
// 数据库更新
planDao.UpdatePlanInfo(dl);
grid.Reload();
}
async Task OnCreatePlanRow(Plan dl)
{
// 数据库添加套餐
bool bFlag = await planDao.InsertPlanInfo(dl);
if (!bFlag)
{
SelectedPlan.Remove(dl);
}
grid.Reload();
}
//新增套餐
async Task InsertPlanRow()
{
var planInfo = new Plan();
if (_forecasts.Count() <= 0)
{
_forecasts = new List<Plan>
{
new Plan()
};
await grid.InsertRow(_forecasts.FirstOrDefault());
}
else
{
await grid.InsertRow(planInfo);
}
}
//修改套餐
async Task EditPlanRow(Plan planInfo)
{
await grid.EditRow(planInfo);
}
//删除套餐
async Task DeletePlanRow(Plan planInfo)
{
if (planInfo.Id > 0)
{
//弹出确认提示框
var b = await dialogService.OpenAsync<ConfirmDialog>(
$"删除确认",
new Dictionary<string, object>() { { "confirmInfo", "确认要删除套餐:" + planInfo.Name + "吗?" } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
if (b)
{
//查询要删除的套餐下是否有绑定,且绑定有库存
if (!(await planDao.CheckPlanBind(planInfo.Id)))
{
_message.Notify
(
new NotificationMessage
{
Severity = NotificationSeverity.Error,
Summary = "提示",
Detail = $"该套餐还有库存绑定且有库存,请先清库存",
Duration = 4000
}
);
return;
}
// 数据库删除
if (await planDao.DeletePlanInfo(planInfo.Id))
{
_message.Notify
(
new NotificationMessage
{
Severity = NotificationSeverity.Success,
Summary = "提示",
Detail = $"删除成功",
Duration = 4000
}
);
}
else
{
_message.Notify
(
new NotificationMessage
{
Severity = NotificationSeverity.Error,
Summary = "提示",
Detail = "删除失败",
Duration = 4000
}
);
}
}
await grid.Reload();
}
else
{
grid.CancelEditRow(planInfo);
await grid.Reload();
}
}
//保存套餐信息
async Task SavePlanRow(Plan planInfo)
{
await grid.UpdateRow(planInfo);
}
async Task CancelPlanEdit(Plan planInfo)
{
grid.CancelEditRow(planInfo);
await grid.Reload();
await PlanDetailsGrid.Reload();
}
void Reset(PlanDetails pd)
{
SelectedPlanDetails.Remove(pd);
}
//修改药品
async Task EditRow(PlanDetails planDetail)
{
// planDetail.DrugId = null;
await PlanDetailsGrid.EditRow(planDetail);
}
//保存修改药品
async Task InsertRow(PlanDetails planDetail)
{
await PlanDetailsGrid.UpdateRow(planDetail);
}
//取消修改药品
async Task CancelEdit(PlanDetails planDetail)
{
PlanDetailsGrid.CancelEditRow(planDetail);
SelectedPlan.FirstOrDefault()._PlanDetails.RemoveAll(pd => pd.Id == 0);
await PlanDetailsGrid.Reload();
}
//删除药品
async Task DeleteRow(PlanDetails planDetail)
{
// Reset(planDetail);
if (planDetail.Id > 0)
{
//弹出确认提示框
var b = await dialogService.OpenAsync<ConfirmDialog>(
$"确认删除",
new Dictionary<string, object>() { { "confirmInfo", "确认要删除药品:" + planDetail._DrugInfo.DrugName + "吗?" } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false }
);
if (b)
{
//查询要删除的药品是否有绑定且库存大于0
if (!(await planDao.CheckPlanDetailBind(planDetail)))
{
_message.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Error,
Summary = "提示",
Detail = "该药品有绑定且库存不为0请先清库存",
Duration = 4000
});
return;
}
// 数据库删除
if (await planDao.DeletePlanDetail(planDetail))
{
_message.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Success,
Summary = "提示",
Detail = "删除成功",
Duration = 4000
}
);
SelectedPlan.FirstOrDefault()._PlanDetails.Remove(planDetail);
}
else
{
_message.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Error,
Summary = "提示",
Detail = "删除失败",
Duration = 4000
}
);
}
await PlanDetailsGrid.Reload();
}
}
else
{
PlanDetailsGrid.CancelEditRow(planDetail);
}
SelectedPlan.FirstOrDefault()._PlanDetails.RemoveAll(pd => pd.Id == 0);
}
async void OnUpdateRow(PlanDetails planDetail)
{
// Reset(planDetail);
SelectedPlanDetails.Add(planDetail);
// 数据库更新
if (await planDao.UpdatePlanDetail(planDetail))
{
_message.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Success,
Summary = "提示",
Detail = "修改成功",
Duration = 4000
}
);
}
else
{
_message.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Error,
Summary = "提示",
Detail = "修改失败",
Duration = 4000
}
);
}
await PlanDetailsGrid.Reload();
}
//保存套餐下添加的药品
async void OnCreateRow(PlanDetails planDetail)
{
if (SelectedPlan.FirstOrDefault() != null)
{
planDetail.PlanId = SelectedPlan.FirstOrDefault().Id;
planDetail.DrugId = planDetail.DrugId == null ? planDetail._DrugInfo.DrugId : planDetail.DrugId;
planDetail.UseState = 1;
planDetail.OperatorUser = globalStateService.Operator?.Username;
planDetail.ReviewerUser = globalStateService.Reviewer?.Username;
if (await planDao.AddPlanDetail(planDetail))
{
_message.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Success,
Summary = "提示",
Detail = "保存成功",
Duration = 4000
}
);
}
else
{
_message.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Error,
Summary = "提示",
Detail = "保存失败",
Duration = 4000
}
);
}
}
// await grid.Reload();
await PlanDetailsGrid.Reload();
}
//新增药品
async Task InsertRow()
{
//查询要删除的套餐下是否有绑定,且绑定有库存
if (SelectedPlan.FirstOrDefault()!=null)
{
if (!(await planDao.CheckPlanBind((int)SelectedPlan.FirstOrDefault().Id)))
{
_message.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Error,
Summary = "提示",
Detail = "该药品有绑定且库存不为0请先清库存",
Duration = 4000
});
return;
}
}
var detail = new Pojo.PlanDetails()
{
PlanId = SelectedPlan.FirstOrDefault().Id
};
SelectedPlan.FirstOrDefault()._PlanDetails.Add(detail);
await PlanDetailsGrid.InsertRow(detail);
}
//验证药品是否已存在套餐中
bool ValidatroDrug(PlanDetails planDetail)
{
if (planDetail.PlanId == 0)
{
//新增的
planDetail.PlanId = SelectedPlan.FirstOrDefault().Id;
}
return planDao.CheckDrugById(planDetail);
}
}

View File

@ -0,0 +1,191 @@
@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" @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" @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" style="height:50vh;overflow:auto">
<RadzenDataGrid @ref="grid" Style="height:48vh;"
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 Width="60px" Title="药盒" Property="OperationTime">
<Template Context="mr">
@if (mr.BoxDrawer > 0)
{
if (mr.DrawerNo == 99)
{
<b class="rz-pr-3">@($"急诊药盒")</b>
}
else if (mr.DrawerNo == 111)
{
<b class="rz-pr-3">@($"恢复室药盒")</b>
}
else
{
<b class="rz-pr-3">@($"{mr.DrawerNo}-{(mr.ColNo == 1 ? '白' : '绿')}")</b>
}
}
else
{
<b class="rz-pr-3">无</b>
}
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="批次" Property="ManuNo" Width="123px">
<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">
<HeaderTemplate>
<div style="text-align: center;">
借出<br>数量
</div>
</HeaderTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="已还药品" Property="ReturnQuantity1">
<HeaderTemplate>
<div style="text-align: center;">
已还<br>药品
</div>
</HeaderTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="已还空瓶" Property="ReturnQuantity2">
<HeaderTemplate>
<div style="text-align: center;">
已还<br>空瓶
</div>
</HeaderTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="本次归还" Property="CurrentReturnQuantity" Width="90px">
<HeaderTemplate>
<div style="text-align: center;">
本次<br>归还
</div>
</HeaderTemplate>
<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);
}
}

View File

@ -0,0 +1,325 @@
@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="还药总数">
<HeaderTemplate>
<div style="text-align: center;">
还药<br>总数
</div>
</HeaderTemplate>
</RadzenDataGridColumn>
<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()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
status = 0;
dialogService.Close(false);
}
async Task OpenDrawer()
{
this.status = 1;
await Task.Delay(200);
// 解析需要打开的抽屉列表
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)}】");
var colNo = data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo));
await PortUtil.NoLightOnByCol(drawerNo, colNo.SelectMany(x => x).ToArray());
}
var b = await PortUtil.OpenDrawerStatus(drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,加药");
options._data = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
RestData();
stop();
}
}
// 检测状态
else if (options._data == 1)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatus2(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
options._data = 0;
if (setting.Value.single.Contains(drawerNo))
{
}
if (index == drawerNos.Count - 1)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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]}】");
// });
cl.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).ToList().ForEach(cs =>
{
cl.ReturnQuantity = 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))
{
}
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);
}
}

View File

@ -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();
}
}
}

View File

@ -0,0 +1,311 @@
@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>
<div Style="height:50vh;overflow:auto;">
<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="false" 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>
</div>
<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()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
status = 0;
dialogService.Close(false);
}
async Task OpenDrawer()
{
this.status = 1;
await Task.Delay(200);
// 解析需要打开的抽屉列表
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.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请放入空瓶");
options._data = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
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.speechSynthesizer.SpeakAsyncCancelAll();
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))
{
}
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();
}
}

View File

@ -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" @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" @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();
}
}

View File

@ -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<ConfirmDialog>(
$"删除确认",
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);
}
}

View File

@ -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" CurrentDateChanged="@OnCurrentDateChanged"
ShowSeconds="true"
@bind-Value="orderInfo.ChargeDate" 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.ChargeDate = new DateTime(args.Year, args.Month, args.Day, args.Hour, args.Minute, args.Second);
}
}

View File

@ -0,0 +1,334 @@
@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) => CancelOpera())" 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;
//开抽屉前操作标识
List<string> DrawerNoColNoList = new List<string>();
public List<OrderTakeVo> data { get; set; }
//称重取药数量
int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
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());
}
for (int i = 0; i < data.Count; i++)
{
if (!DrawerNoColNoList.Contains(data[i].ChannelStock.DrawerNo.ToString() + data[i].ChannelStock.ColNo))
{
if (data[i].ChannelStock.BoardType.ToString().Contains("6"))
{
PortUtil.DrawerNo = data[i].ChannelStock.DrawerNo;
PortUtil.ColNoLst.Add(data[i].ChannelStock.ColNo);
data[i].BeforeQuantity[data[i].ChannelStock.ColNo - 1] = await PortUtil.CheckQuantityForSingleForErZhong(data[i].ChannelStock.ColNo);
logger.Info($"称重抽屉,开抽屉前检测数量【{string.Join(",", data[i].BeforeQuantity)}】");
await Task.Delay(200);
}
//是药盒抽屉开药盒
if (data[i].ChannelStock.BoardType.ToString().Contains("3"))
{
PortUtil.DrawerNo = drawerNo;
await PortUtil.OpenBoxByColNoForErZhong(data[i].ChannelStock.ColNo);
await Task.Delay(200);
}
DrawerNoColNoList.Add(data[i].ChannelStock.DrawerNo.ToString() + data[i].ChannelStock.ColNo);
}
}
var b = await PortUtil.OpenDrawerStatusForErZhong(drawerNo);
if (b)
{
PortUtil.Operate = true;
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药");
orderTakeVo.Status = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
RestData();
stop();
}
}
// 检测状态
else if (orderTakeVo.Status == 1)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatusForErZhong(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
data.ForEach(cl =>
{
if (cl.ChannelStock.DrawerNo == drawerNo)
{
cl.GetQuantity = cl.Quantity;
}
});
PortUtil.Operate = false;
orderTakeVo.Status = 2;
if (options._data == drawerNos.Count - 1)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认");
this.status = 2;
string alertMessage = string.Empty;
//检查是否称重抽屉,核对实际取出数量是否与应取数量一致,不一致则弹出提示
for (int i = 0; i < data.Count; i++)
{
if (data[i].ChannelStock.BoardType.ToString().Contains("6"))
{
PortUtil.DrawerNo = drawerNo;
PortUtil.ColNoLst.Add(data[i].ChannelStock.ColNo);
orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1] = await PortUtil.CheckQuantityForSingle(data[i].ChannelStock.ColNo);
logger.Info($"称重抽屉,关抽屉后检测数量【{string.Join(",", orderTakeVo.AfterQuantity)}】");
WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = orderTakeVo.BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
{
//称重自动计数数量与实际要取数量不一致弹出提示,确认后保存数据
alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
}
await Task.Delay(200);
}
if (data[i].ChannelStock.BoardType.ToString().Contains("2"))
{
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)}】");
WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStock.ColNo - 1] - orderTakeVo.AfterQuantity[data[i].ChannelStock.ColNo - 1];
if (data[i].Quantity != WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1])
{
alertMessage += $"{data[i].Drug.DrugName}应取数量【{orderTakeVo.Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStock.ColNo - 1]}】";
}
}
}
if (!string.IsNullOrEmpty(alertMessage))
{
//弹出确认对话框
alertMessage += "应取数与实际取出数不一致确认要保存吗?";
//弹出确认提示框
var confirm = await dialogService.OpenAsync<ConfirmDialog>(
$"保存确认",
new Dictionary<string, object>() { { "confirmInfo", alertMessage } },
new DialogOptions() { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
logger.Info(alertMessage);
if (!confirm)
{
RestData();
logger.Info("取消保存");
// 关闭弹窗
dialogService.Close(false);
}
}
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))
{
}
stop();
}
});
}
async Task CancelOpera()
{
RestData();
dialogService.Close(false);
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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();
}
}

View File

@ -0,0 +1,67 @@
@page "/signature/{user}"
@page "/signature"
@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);
}
}
}

View File

@ -0,0 +1,293 @@
@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:260px; display: block;" AllowFilteringByAllStringColumns="true" TextProperty="DrugName">
<Columns>
<RadzenDropDownDataGridColumn Property="DrugId" Title="药品编码" Sortable="false" />
<RadzenDropDownDataGridColumn Property="DrugName" Title="名称" Sortable="false" />
<RadzenDropDownDataGridColumn Property="DrugSpec" Title="规格" Sortable="false" />
</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="批次" Sortable="false" />
<RadzenDropDownDataGridColumn Property="EffDate" Title="效期" Sortable="false">
<Template Context="data">
@data.EffDate.ToString("yyyy-MM-dd")
</Template>
</RadzenDropDownDataGridColumn>
</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
{
}
}
}
}

View File

@ -0,0 +1,320 @@
@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)
{
if (setting.Value.returnDrawer != null && setting.Value.returnDrawer.Contains(i))
{
<RadzenButton class="col-5" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="true" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" Style="background-color: #d3d3d3;" />
}
else
{
<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.ToString().Contains("2") || cs.BoardType.ToString().Contains("3"))
{
@cs.CheckQuantity
}
else
{
<RadzenNumeric Style="display: block" Name="CheckQuantity" @bind-Value=@cs.CheckQuantity>
<RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="1" Max="100" Text="请填写正确的取出数量" Component="CheckQuantity" />
</RadzenNumeric>
}
</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;
await Task.Delay(200);
// 根据抽屉类型来决定打开前是否需要查询数量
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.OpenDrawerStatusForErZhong(this.drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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.CheckDrawerStatusForErZhong(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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];
});
await InvokeAsync(StateHasChanged);
}
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))
{
}
RestData();
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
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.Success, Summary = "提示", Detail = $"盘点完成", Duration = 4000 });
logger.Info($"盘点完成");
}
}
//重置状态
this.RestData();
// 重新查询库存
await grid.Reload();
}
void Cancel()
{
RestData();
}
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();
}
}

View File

@ -0,0 +1,285 @@
@page "/stock/list"
@using MasaBlazorApp3.Report
@using Radzen.Blazor.Rendering
<style>
@@keyframes shake {
0% {
opacity: 1;
color: red;
}
25% {
opacity: 1;
color: orange;
}
50% {
opacity: 0;
color: yellow;
}
75% {
opacity: 1;
color: crimson;
}
100% {
opacity: 1;
color: red;
}
}
.rz-custom-header {
width: 100%;
}
.shaky-text {
animation: shake 2s infinite ease-in-out;
/* 你可以根据需要调整动画的持续时间和迭代次数 */
transition: color 0.5s linear,opacity 0.5s linear;
}
.my-popup {
display: none;
position: absolute;
overflow: auto;
/* height: 360px; */
width: 900px;
border: var(--rz-panel-border);
background-color: var(--rz-panel-background-color);
box-shadow: var(--rz-panel-shadow);
border-radius: var(--rz-border-radius);
}
</style>
<div class="col-12 mb-4">
@* <form onsubmit="@(() => grid.Reload())">
<RadzenFieldset Text="报表导出">
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
<RadzenButton @ref=button Icon="download" Text="专用账册导出" Variant="Variant.Outlined" Click="@(args => popup2.ToggleAsync(button.Element))" />
<Popup @ref=popup2 Lazy=true class="my-popup">
<RadzenStack Orientation="Orientation.Vertical" Gap="1rem" class="rz-h-100 rz-p-4">
<RadzenFieldset Text="条件选择">
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="4">
<RadzenLabel Text="开始" Component="Start" />
<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" />
<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="5">
<RadzenLabel Text="药品名称" Component="drug" />
<RadzenLabel Text="拼音码" Component="drug" />
<RadzenLabel Text="编码" Component="drug" />
</RadzenColumn>
<RadzenColumn Size="6">
<RadzenAutoComplete Name="drug" Multiline="true" @bind-Value=@drugName Data=@drugInfo TextProperty="@nameof(DrugInfo.DrugNameSpecManufactory)"
Style="width: 100%;" InputAttributes="@(new Dictionary<string, object>() { { "aria-label", "drugInfo" } })" />
</RadzenColumn>
</RadzenRow>
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn>
<RadzenButton Click="reloadGrid" Icon="refresh" Text="重置" ButtonStyle="ButtonStyle.Warning" />
</RadzenColumn>
</RadzenRow>
<RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
<RadzenButton Icon="download" Text="导出" Variant="Variant.Outlined" Click="AccountBookExport" />
</RadzenRow>
</RadzenStack>
</RadzenFieldset>
</RadzenStack>
</Popup>
</RadzenRow>
</RadzenStack>
</RadzenFieldset>
</form> *@
</div>
<div class="col-12 mb-4">
<RadzenDataGrid @ref="grid"
IsLoading="@isLoading"
RowRender="@RowRender"
EmptyText="无数据"
Data="@_forecasts"
AllowColumnResize="true" AllowAlternatingRows="false"
SelectionMode="DataGridSelectionMode.Single"
ExpandMode="DataGridExpandMode.Single">
@* <HeaderTemplate>
<RadzenRow JustifyContent="JustifyContent.End" AlignItems="AlignItems.Center">
<RadzenButton Icon="download" Text="库存导出" Variant="Variant.Outlined" Click="StockExport" />
<RadzenButton Icon="download" Text="专用账册导出" Variant="Variant.Outlined" Click="AccountBookExport" />
</RadzenRow>
</HeaderTemplate> *@
<Template Context="di">
<RadzenDataGrid Data="@di.Stocks" EmptyText="无数据">
<Columns>
<RadzenDataGridColumn Title="库位" Property="DrawerNo">
<Template Context="s">
@if (s.MachineId == "DM5")
{
switch (s.DrawerNo)
{
case 99:
@("急诊药盒")
break;
case 111:
@("恢复室药盒")
break;
case 31:
@("胃镜药盒")
break;
case 32:
@("导管药盒")
break;
case 33:
@("生殖药盒")
break;
case 34:
@("妇门药盒")
break;
default:
@* @($"{s.DrawerNo}-{(s.ColNo == 1 ? '白' : '绿')}") *@
@("常规神外药盒")
break;
}
}
else
{
@($"{s.DrawerNo}-{s.ColNo}")
}
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="数量" Property="Quantity">
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="效期" Property="EffDate">
<Template Context="s">
@{
DateTime dateTime;
bool success = DateTime.TryParse(s.EffDate, out dateTime);
// if (success && dateTime <= DateTime.Now.AddMonths(3))
// {
// @s.EffDate
// <p class="shaky-text">近效期药品!</p>
// }
// else
//{
@s.EffDate
//}
}
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</Template>
<Columns>
<RadzenDataGridColumn Frozen="true" Width="200px" Title="药品名称" Property="DrugName"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="规格" Property="DrugSpec"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="总库存" Property="StockQuantity">
<Template Context="s">
@* @if (s.StockQuantity < 10)
{
@s.StockQuantity
<p class="shaky-text">库存预警!</p>
}
else
{ *@
@s.StockQuantity
@* } *@
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</div>
@code {
@inject IDrugInfoDao drugInfoDao;
@inject DialogService dialogService;
@inject IReportDataDao reportDataDao;
RadzenDataGrid<DrugInfo> grid;
bool isLoading;
int count;
private IEnumerable<DrugInfo>? _forecasts;
DateTime? start;
DateTime? end;
string drugName;
RadzenButton button;
Popup popup2;
IEnumerable<DrugInfo> drugInfo;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
isLoading = true;
var result = await drugInfoDao.GetAllDrugAndStock();
// Update the Data property
_forecasts = result;
drugInfo = await drugInfoDao.GetAllDrug();
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;
}
// //库存导出
// async Task StockExport()
// {
// PageData<ReportStockDateInfo> pageData = await reportDataDao.GetStockExportData(drugName);
// GridReportUtil.PrintReport("stock_template.grf", pageData);
// }
//专用账册导出
async Task AccountBookExport()
{
// string drugId = drugName != null ? drugName.Split('/').Last().Trim():"";
// GridReportUtil gridReportUtil = new GridReportUtil();
PageData<ReportAccountDateInfo> pageData = await reportDataDao.GetAccountExportData(start, end, drugName);
GridReportUtil.PrintReport("account_book_temp.grf", pageData);
}
//重置
async Task reloadGrid()
{
start = DateTime.MinValue;
end = DateTime.MinValue;
drugName = string.Empty;
await grid.Reload();
}
}

View File

@ -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;
});
}
}

View File

@ -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<ConfirmDialog>(
$"删除确认",
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<ConfirmDialog>(
$"密码重置确认",
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();
}
}

View File

@ -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日总结6转结)
///</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; }
}
}

View File

@ -0,0 +1,153 @@
using LinqToDB.Mapping;
namespace MasaBlazorApp3.Pojo
{
[Table("account_book_g2")]
public class AccountBookG2
{
/// <summary>
/// 主键
/// </summary>
[Column("id", IsPrimaryKey = true)]
public int Id { get; set; }
/// <summary>
/// 药品id
/// </summary>
[Column("drug_id")]
public string DrugId { get; set; }
/// <summary>
/// 1领入2发出3日结4总结5转结
/// </summary>
[Column("type")]
public int Type { get; set; }
/// <summary>
/// 科室
/// </summary>
[Column("department")]
public string Department { get; set; }
/// <summary>
/// 设备内记录凭证
/// </summary>
[Column("invoice_no")]
public string InvoiceNo { get; set; }
/// <summary>
/// 处方号或凭证号
/// </summary>
[Column("order_no")]
public string OrderNo { get; set; }
/// <summary>
/// 批次
/// </summary>
[Column("manu_no")]
public string ManuNo { get; set; }
/// <summary>
/// 效期
/// </summary>
[Column("eff_date")]
public string EffDate { get; set; }
/// <summary>
/// 上日结存
/// </summary>
[Column("yesterday_quantity")]
public int YQuantity { get; set; }
/// <summary>
/// 收入
/// </summary>
[Column("add_quantity")]
public int AddQuantity { get; set; }
/// <summary>
/// 发出
/// </summary>
[Column("out_quantity")]
public int OutQuantity { get; set; }
/// <summary>
/// 批次结存
/// </summary>
[Column("manu_stock")]
public int ManuStock { get; set; }
/// <summary>
/// 总结存
/// </summary>
[Column("total_stock")]
public int TotalStock { get; set; }
/// <summary>
/// 发药领药人id
/// </summary>
[Column("user_id1")]
public int? UserId1 { get; set; }
/// <summary>
/// 复核人id
/// </summary>
[Column("user_id2")]
public int? UserId2 { get; set; }
/// <summary>
/// 设备id
/// </summary>
[Column("machine_id")]
public string MachineId { get; set; }
/// <summary>
/// 日期
/// </summary>
[Column("create_date")]
public string CreateDate { get; set; }
/// <summary>
/// 插入更新时间(当前时间戳)
/// </summary>
[Column("create_time")]
public DateTime CreateTime { get; set; }
/// <summary>
/// 药品名称
/// </summary>
[Column(IsColumn = false)]
public string DrugName { get; set; }
/// <summary>
/// 规格
/// </summary>
[Column(IsColumn = false)]
public string DrugSpec { get; set; }
/// <summary>
/// 厂家
/// </summary>
[Column(IsColumn = false)]
public string Manufactory { get; set; }
/// <summary>
/// 发药人
/// </summary>
[Column(IsColumn = false)]
public string OperatorName { get; set; }
/// <summary>
/// 复核人
/// </summary>
[Column(IsColumn = false)]
public string ReviewerName { get; set; }
/// <summary>
/// 手术间
/// </summary>
[Column("shoushuJian")]
public string ShoushuJian { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MasaBlazorApp3.Pojo
{
public class Anaesthetist
{
public int Id { get; set; }
public string Name { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MasaBlazorApp3.Pojo
{
public class BoxModel
{
//库位号
public int BoxNo { get; set; }
//药箱号
public int BoxName { get; set; }
public string {
get => BoxName + "-" + BoxNo;
}
}
}

View File

@ -0,0 +1,62 @@
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();
//关联药品中的套餐信息表
[Association(ThisKey = nameof(DrugId), OtherKey = nameof(Plan.Id))]
public Plan PlanInfo { get; set; } = new();
//手术室药盒中的库存总数
[Column("stock_quantity")]
public int TotalQuantity { get; set; }
[Association(ThisKey = nameof(DrugId), OtherKey = nameof(PlanDetails.PlanId))]
public List<PlanDetails> _PlanDetails { get; set; } = new();
//手术室药盒中的库存总数
[Column(IsColumn = false)]
public bool IsChecked{get;set;} = false;
//手术室药盒中的库存总数
[Column(IsColumn = false)]
public bool BoxDisabled {get;set;} = false;
}
}

View File

@ -0,0 +1,127 @@
using LinqToDB.Mapping;
using Mysqlx.Crud;
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(IsColumn =false)]
public int TotalQuantity { get; set; }
//药盒DrawerType为非1时表示不在库
[Column("drawer_type")]
public int DrawerType { get; set; }
/// <summary>
/// 1物理隔板;2单支计数;3管控药盒;4储物箱;5智能显示;6称重计数;63称重计数药盒;653称重计数药盒智能显示;
/// </summary>
[Column("board_type")]
public int BoardType { get; set; }
[Column("manu_no")]
public string ManuNo { get; set; }
[Column("eff_date")]
public string EffDate { get; set; }
[LinqToDB.Mapping.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; } = 0;
[Column("dmnguid")]
public string Dmnguid { get; set; }
[LinqToDB.Mapping.Association(ThisKey = nameof(Dmnguid), OtherKey = nameof(DrugManuNo.Id))]
public DrugManuNo? drugManuNo { get; set; }
[Association(ThisKey = nameof(DrugId), OtherKey = nameof(DrugManuNo.DrugId))]
public List<DrugManuNo> drugManuNoList { get; set; }=new List<DrugManuNo>();
[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;
}
[Column("Pos_No")]
public int BiaoDingStatus { get; set; }
//手术室药盒中的药品基数
[Column("Check_Quantity")]
public int BaseQuantity { get; set; }
//手术室药盒中某药品全部批次的需要加药数
[Column("col_no2")]
public int NeedQuantity { get; set; }
//手术室药盒中某药品全部批次的已取药待入库数
[Column("col_no1")]
public int AddToQuantity { get; set; }
//手术室药盒中药品补药状态(1需补药2已补药待入库0满库状态)
[Column("state")]
public int BoxState { get; set; }
[Column("fill_time")]
public DateTime FillTime { get; set; }
//药盒中药品对应的处方信息
[Column(IsColumn =false)]
public List<OrderInfo> OrderList { get; set; }
//药盒中药品对应的选中的处方信息
[Column(IsColumn =false)]
public IList<OrderInfo> SelectedOrderList { get; set; }
//还空瓶库位
[Column(IsColumn = false)]
public ChannelStock EmptyStock { get; set; }
//还空瓶数
[Column(IsColumn = false)]
public int EmptyQuantity { get; set; } = 0;
//用药数
[Column(IsColumn =false)]
public int UseQuantity { get; set; }
//处方数
[Column(IsColumn =false)]
public int OrderQuantity { get; set; }
//药盒中未绑套餐的药所在抽屉库位
[Column(IsColumn =false)]
public List<ChannelStock> DrawerChanneStockList { get; set; }
//药盒中未绑套餐的药所在抽屉库位
[Column(IsColumn = false)]
public ChannelStock ReturnDrawerChanneStock { get; set; }
//调拨出、入库时药品单位是否与药品表中的小单位相同(库存中存小单位的数量,单位不一致需要转换)
public bool UnitEquals{get; set; }=true;
}
}

View File

@ -0,0 +1,18 @@
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; }
public int[] returnDrawer { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More