添加SharpPromise引用并修改开抽屉循环

This commit is contained in:
maqiao 2024-08-30 17:25:07 +08:00
parent c9de968c55
commit 776a1ddce2
9 changed files with 483 additions and 9 deletions

View File

@ -36,7 +36,7 @@
<!-- 抽屉串口使用的协议232或者485 --> <!-- 抽屉串口使用的协议232或者485 -->
<add key="DrawerProtocol" value="485" /> <add key="DrawerProtocol" value="485" />
<!-- 抽屉串口的串口号 --> <!-- 抽屉串口的串口号 -->
<add key="DrawerPortPath" value="COM1" /> <add key="DrawerPortPath" value="COM3" />
<!-- can总线串口的串口号 --> <!-- can总线串口的串口号 -->
<add key="CanBusPortPath" value="COM3" /> <add key="CanBusPortPath" value="COM3" />
<!-- 条码枪串口的串口号 --> <!-- 条码枪串口的串口号 -->

View File

@ -0,0 +1,127 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<PackageIcon></PackageIcon>
<Product>毒麻管理程序</Product>
<ApplicationIcon>Images\favicon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<None Remove="Images\body-bg.jpg" />
<None Remove="Images\box-16.jpg" />
<None Remove="Images\box.png" />
<None Remove="Images\favicon.ico" />
<None Remove="Images\finger-bg-r.png" />
<None Remove="Images\logo.png" />
<None Remove="Images\TbExit.png" />
<None Remove="Images\TbJiay.png" />
<None Remove="Images\TbKuc.png" />
<None Remove="Images\TbQyao.png" />
<None Remove="Images\TbSet.png" />
<None Remove="Images\TbTuiy.png" />
</ItemGroup>
<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>
<Content Include="Images\favicon.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Images\body-bg.jpg" />
<Resource Include="Images\box-16.jpg" />
<Resource Include="Images\box.png" />
<Resource Include="Images\favicon.ico" />
<Resource Include="Images\finger-bg-r.png" />
<Resource Include="Images\logo.png" />
<Resource Include="Images\TbExit.png" />
<Resource Include="Images\TbJiay.png" />
<Resource Include="Images\TbKuc.png" />
<Resource Include="Images\TbQyao.png" />
<Resource Include="Images\TbSet.png" />
<Resource Include="Images\TbTuiy.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="MaterialDesignThemes" Version="4.8.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageReference Include="Prism.Unity" Version="8.1.97" />
<PackageReference Include="SharpPromise" Version="1.7.0" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.67" />
<PackageReference Include="SuperSimpleTcp" Version="3.0.10" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
<PackageReference Include="System.Management" Version="7.0.1" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="System.Speech" Version="7.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Update="App.xaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</ApplicationDefinition>
</ItemGroup>
<ItemGroup>
<None Update="App.config">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="log4net.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ReportTemp\account_book_temp.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_add.grf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ReportTemp\machine_log_take.grf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ReportTemp\stock_template.grf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Page Update="Views\Dialog\InvoiceTakeDialog.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
</Page>
</ItemGroup>
<ItemGroup>
<Folder Include="HIKVISION\" />
</ItemGroup>
</Project>

View File

@ -70,6 +70,7 @@
<PackageReference Include="MaterialDesignThemes" Version="4.8.0" /> <PackageReference Include="MaterialDesignThemes" Version="4.8.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" /> <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageReference Include="Prism.Unity" Version="8.1.97" /> <PackageReference Include="Prism.Unity" Version="8.1.97" />
<PackageReference Include="SharpPromise" Version="1.7.0" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.67" /> <PackageReference Include="SqlSugarCore" Version="5.1.4.67" />
<PackageReference Include="SuperSimpleTcp" Version="3.0.10" /> <PackageReference Include="SuperSimpleTcp" Version="3.0.10" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" /> <PackageReference Include="System.Drawing.Common" Version="7.0.0" />

View File

@ -185,5 +185,8 @@ namespace DM_Weight.Models
[Navigate(NavigateType.ManyToOne, nameof(Chnguid))] [Navigate(NavigateType.ManyToOne, nameof(Chnguid))]
public ChannelList ChannelLst { get => _channelList; set => SetProperty(ref _channelList, value); } public ChannelList ChannelLst { get => _channelList; set => SetProperty(ref _channelList, value); }
[SugarColumn(IsIgnore = true)]
public int DrawerState { get; set; } = 0;
} }
} }

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DM_Weight.Models
{
public class OrderTakeVo
{
public DrugInfo Drug { get; set; }
public OrderDetail OrderDetail { get; set; }
public ChannelStock ChannelStock { get; set; }
public int StockQuantity { get; set; }
public int Quantity { get; set; }
public int GetQuantity { get; set; } = 0;
public int Status { get; set; } = 0;
public int[] BeforeQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public int[] AfterQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public int AddQuantity { get; set; } = 0;
}
}

View File

@ -71,7 +71,7 @@ namespace DM_Weight.Port
private int[] AfterQuantity { get; set; } = new int[] { }; private int[] AfterQuantity { get; set; } = new int[] { };
// 整体流程状态 // 整体流程状态
private int statue { get; set; } = 0; public int statue { get; set; } = 0;
// 是否正在操作中 // 是否正在操作中
@ -696,7 +696,7 @@ namespace DM_Weight.Port
return await GetBufferByPort(drawerSerial, 11); return await GetBufferByPort(drawerSerial, 11);
} }
private bool DrawerState(int[] r) public bool DrawerState(int[] r)
{ {
int index = DrawerNo > 8 ? DrawerNo - 7 : DrawerNo + 1; int index = DrawerNo > 8 ? DrawerNo - 7 : DrawerNo + 1;
return r[index] == 0; return r[index] == 0;
@ -769,7 +769,7 @@ namespace DM_Weight.Port
canBusSerial.Write(buffer, 0, 8); canBusSerial.Write(buffer, 0, 8);
} }
private int[] CheckStorageStatus(int[] data) public int[] CheckStorageStatus(int[] data)
{ {
int a = data[0]; int a = data[0];
int b = data[1]; int b = data[1];

View File

@ -0,0 +1,44 @@
using SharpPromise;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DM_Weight.Port
{
public class PromiseUtil<T>
{
public int _delay { get; set; }
public T? _data { get; set; }
public async Task taskAsyncLoop(int delay, T data, Action<PromiseUtil<T>, Action, Action> action)
{
_data = data;
_delay = 0;
while (_delay >= 0)
{
await new Promise(async (Action onResolve, Action onReject) =>
{
await Task.Delay(_delay);
try
{
await Task.Run(() => action(this, onResolve, onReject));
}
catch (Exception ex)
{
onReject();
}
}).Then(() =>
{
_delay = delay;
}).Catch((Exception e) =>
{
_delay = -1;
});
}
}
}
}

View File

@ -21,6 +21,7 @@ using DM_Weight.Port;
using DM_Weight.select; using DM_Weight.select;
using DM_Weight.util; using DM_Weight.util;
using System.Threading; using System.Threading;
using System.Windows.Markup;
namespace DM_Weight.ViewModels namespace DM_Weight.ViewModels
{ {
@ -226,7 +227,7 @@ namespace DM_Weight.ViewModels
DialogParameters dialogParameters = new DialogParameters(); DialogParameters dialogParameters = new DialogParameters();
dialogParameters.Add("msgInfo", msg); dialogParameters.Add("msgInfo", msg);
DialogServiceExtensions.ShowDialogHost(_dialogService, "ShowMessageDialog", dialogParameters, "RootDialog"); DialogServiceExtensions.ShowDialogHost(_dialogService, "ShowMessageDialog", dialogParameters, "RootDialog");
} }
else else
{ {
@ -258,7 +259,264 @@ namespace DM_Weight.ViewModels
}); });
} }
public DelegateCommand OpenDrawer_New
{
get => new DelegateCommand(async () =>
{
OpenDrawerAction();
});
}
async Task OpenDrawerAction()
{
this.Status = 1;
// 解析需要打开的抽屉列表
//List<OrderTakeVo> drawerNos = this.data.GroupBy(it => it.ChannelStock.DrawerNo).Select(it => it.First()).ToList();
// 根据抽屉类型来决定打开前是否需要查询数量
var promiseUtil = new PromiseUtil<int>();
enumerable = ChannelStocks.GroupBy(cs => cs.DrawerNo, cs => cs);
enumerator = enumerable.GetEnumerator();
_portUtil.WindowName = "OrderTakeDrugWindow";
_portUtil.BoardType = ChannelStocks.Count > 0 ? ChannelStocks[0].BoardType : 1;
_portUtil.ColNos = ChannelStocks.Select(it => it.ColNo).ToArray();
enumerator.MoveNext();
await promiseUtil.taskAsyncLoop(500, 0, async (options, next, stop) =>
{
//var orderTakeVo = drawerNos[options._data];
//orderTakeVo.ChannelStock.DrawerNo;
IGrouping<int, ChannelStock> groupingStock = enumerator.Current;
var drawerNo = groupingStock.Key;
_portUtil.DrawerNo = groupingStock.Key;
int[] BeforeQuantity = new int[] { };
List<ChannelStock> channelStocks = groupingStock.ToList();
try
{
if (this.Status == 0)
{
stop();
}
// 开启抽屉
else if (this.Status == 1)
{
// 储物箱直接开
if (channelStocks[0].BoardType == 4)
{
if (channelStocks[0].DrawerState == 0)
{
byte[] resultOpen = await _portUtil.OpenStorage();
int[] rOpen = resultOpen.Select(it => Convert.ToInt32(it)).ToArray();
if (rOpen[4] != 0)
{
logger.Info($"储物箱使能成功");
channelStocks[0].DrawerState = 1;
next();
}
else
{
string _WindowName = "OrderTakeDialog";
// 重新初始化数据
_portUtil.ResetData();
// 指令发送错误,未打开
// 返回消息 抽屉打开失败
_eventAggregator.GetEvent<PortUtilEvent>().Publish(new util.DeviceMsg()
{
EventType = util.EventType.OPENERROR,
WindowName = "OrderTakeDialog",
Message = "储物箱使能失败"
});
logger.Info($"储物箱使能失败");
_portUtil.ResetData();
stop();
}
}
if (channelStocks[0].DrawerState == 1)
{
// 查询锁状态
byte[] resultBackDoor = await _portUtil.BackDoorState();
int[] rBackDoor = resultBackDoor.Select(it => Convert.ToInt32(it)).ToArray();
int[] lockStates = _portUtil.CheckStorageStatus(rBackDoor.Skip(3).Take(2).ToArray());
int[] lightStates = _portUtil.CheckStorageStatus(rBackDoor.Skip(5).Take(2).ToArray());
// 锁处于关闭状态
if (lockStates[Convert.ToInt32(ConfigurationManager.AppSettings["StorageBoxAddr"]) - 1] == 0)
{
// 锁还未打开过
if (_portUtil.statue == 0)
{
// 指示灯不闪烁了,说明规定时间内没有开锁,需要给前台提示
if (lightStates[Convert.ToInt32(ConfigurationManager.AppSettings["StorageBoxAddr"]) - 1] == 0)
{
// 打开失败
logger.Info($"储物箱指示灯不闪烁,使能过期");
enumerator.MoveNext();
next();
}
else
{
channelStocks[0].DrawerState = 1;
next();
}
}
else if (_portUtil.statue == 1)
{
// 锁是打开状态现在关闭了,说明操作完成了,告诉前台锁已关闭
_portUtil.statue = 2;
string _WindowName = "OrderTakeDialog";
// 重新初始化数据
//ResetData();
_eventAggregator.GetEvent<PortUtilEvent>().Publish(new util.DeviceMsg()
{
EventType = util.EventType.DRAWERCLOSE,
WindowName = _WindowName,
});
logger.Info($"储物箱关闭");
if (options._data == (enumerable.Count() - 1))
{
_portUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认");
this.Status = 3;
channelStocks[0].DrawerState = 0;
stop();
}
else
{
channelStocks[0].DrawerState = 0;
enumerator.MoveNext();
next();
}
}
}
}
}
if (channelStocks[0].DrawerState == 0)
{
// 判断是否为单支抽屉
if (channelStocks[0].BoardType == 2)
{
byte[] quantity = await _portUtil.CheckQuantityByDrawer();
BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
logger.Info($"单支抽屉,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】");
await _portUtil.HasLightOnByCol();
}
// 药盒
if (channelStocks[0].BoardType == 3)
{
// 药盒指示灯使能
await _portUtil.BoxLockLightOn();
}
if (channelStocks[0].BoardType == 6)
{
// 药盒指示灯使能
await _portUtil.BoxLockLightOn2();
}
byte[] buffer = await _portUtil.OpenDrawer();
int[] r = buffer.Select(it => Convert.ToInt32(it)).ToArray();
logger.Info($"OpenDrawer{string.Join(",", r)}");
if (_portUtil.DrawerState(r))
{
_portUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药");
channelStocks[0].DrawerState = 1;
next();
}
else
{
AlertMsg alertMsg = new AlertMsg
{
Message = $"抽屉【{drawerNo}】打开失败,请检测硬件",
Type = MsgType.ERROR,
};
_eventAggregator.GetEvent<SnackbarEvent>().Publish(alertMsg);
logger.Info($"抽屉打开失败");
_portUtil.ResetData();
stop();
}
}
// 检测状态
else if (channelStocks[0].DrawerState == 1)
{
// 查询抽屉是否为关闭状态
byte[] buffer = await _portUtil.CheckDrawerStatus();
int[] r = buffer.Select(it => Convert.ToInt32(it)).ToArray();
logger.Info($"GetDrawerStatus{string.Join(",", r)}");
// 抽屉没有关闭
if (_portUtil.DrawerState(r))
{
if (channelStocks[0].BoardType == 2)
{
byte[] quantity = await _portUtil.CheckQuantityByDrawer();
int[] AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
logger.Info($"AfterQuantity{string.Join(",", AfterQuantity)}");
logger.Info($"单支抽屉,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】");
ChannelStocks.ForEach(cl =>
{
if (cl.DrawerNo == drawerNo)
{
logger.Info($"单支抽屉【{drawerNo}】,应取药品数量【{cl.Quantity}】,现实取数量【{BeforeQuantity[cl.ColNo - 1] - AfterQuantity[cl.ColNo - 1]}】");
}
});
}
next(); // continue iteration
}
else
{
ChannelStocks.ForEach(cl =>
{
if (cl.DrawerNo == drawerNo)
{
cl.TakeQuantity = cl.Quantity;
}
});
channelStocks[0].DrawerState = 2;
if (options._data == (enumerable.Count() - 1))
{
_portUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认");
this.Status = 3;
channelStocks[0].DrawerState = 0;
stop();
}
else
{
options._data += 1;
channelStocks[0].DrawerState = 0;
enumerator.MoveNext();
next();
}
}
}
}
}
catch (Exception e)
{
//_portUtil.ResetData();
logger.Info($"处方取药发生错误,{e.Message}"); AlertMsg alertMsg = new AlertMsg
{
Message = $"处方取药发生错误{e.Message}",
Type = MsgType.ERROR,
};
_eventAggregator.GetEvent<SnackbarEvent>().Publish(alertMsg);
stop();
}
});
}
private void OpenOneByOne() private void OpenOneByOne()
{ {
IGrouping<int, ChannelStock> grouping = enumerator.Current; IGrouping<int, ChannelStock> grouping = enumerator.Current;
@ -382,7 +640,7 @@ namespace DM_Weight.ViewModels
}; };
_eventAggregator.GetEvent<SnackbarEvent>().Publish(alertMsg); _eventAggregator.GetEvent<SnackbarEvent>().Publish(alertMsg);
} }
if(!f.IsSuccess) if (!f.IsSuccess)
{ {
AlertMsg alertMsg = new AlertMsg AlertMsg alertMsg = new AlertMsg
{ {
@ -422,8 +680,17 @@ namespace DM_Weight.ViewModels
{ {
get => new DelegateCommand(() => get => new DelegateCommand(() =>
{ {
_portUtil.ResetData(); //Status = 0;
Status = 0; //_portUtil.statue = 0;
//_portUtil.ResetData();
if (Status != 0)
{
_portUtil.ResetData();
Status = 0;
}
RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
}); });
} }

View File

@ -198,7 +198,7 @@
materialDesign:ButtonProgressAssist.IsIndicatorVisible="{Binding Status, Converter={StaticResource StatusConverter}, ConverterParameter=opearBtnLoading}" materialDesign:ButtonProgressAssist.IsIndicatorVisible="{Binding Status, Converter={StaticResource StatusConverter}, ConverterParameter=opearBtnLoading}"
materialDesign:ButtonProgressAssist.IsIndeterminate="{Binding Status, Converter={StaticResource StatusConverter}, ConverterParameter=opearBtnLoading}" materialDesign:ButtonProgressAssist.IsIndeterminate="{Binding Status, Converter={StaticResource StatusConverter}, ConverterParameter=opearBtnLoading}"
Content="取药" Content="取药"
Command="{Binding OpenDrawer}"> Command="{Binding OpenDrawer_New}">
</Button> </Button>
<Button <Button
Margin="2" Margin="2"