更新多用户登录机制:
同时只允许一个用户登录操作A; 多个用户B登录时,有权限用户A将进行确认,若确认后操作权限转移到B,A变成ReadOnly模式,仅有只读权限; 目前ReadOnly模式禁用鼠标键盘功能,只能切换页面,无法操控页面内功能(滚动条、Log等无法点击查看)
This commit is contained in:
parent
b770eefdaf
commit
fce4967a57
|
@ -3,12 +3,10 @@
|
|||
<TableRecipeFormat RecipeChamberType="Sic" RecipeVersion="1.0">
|
||||
<Catalog DisplayName="Operation">
|
||||
<Group DisplayName="Overview">
|
||||
<Content DisplayName="Operation" Default="false" />
|
||||
<Content DisplayName="RunningMode" Default="false" />
|
||||
<Content DisplayName="ProcessMonitorWindow" Default="true" />
|
||||
<Content DisplayName="ProcessMonitorWindow" Default="true" Description="是否允许打开工艺实时数据监控窗口"/>
|
||||
</Group>
|
||||
<Group DisplayName="Behaviour">
|
||||
<Content DisplayName="ShutDown" Default="false" />
|
||||
<Content DisplayName="ShutDown" Default="false" Description="是否允许关闭系统"/>
|
||||
</Group>
|
||||
</Catalog>
|
||||
|
||||
|
@ -34,11 +32,10 @@
|
|||
|
||||
<Catalog DisplayName="Recipe">
|
||||
<Group DisplayName="Behaviour">
|
||||
<Content DisplayName="AllowEditCellAccessPerm" Default="false" />
|
||||
<Content DisplayName="ShowValuesInRecipeEditor" Default="false" />
|
||||
<Content DisplayName="ShowValueInProcessView" Default="false" />
|
||||
<Content DisplayName="AllowSaveInProcessView" Default="false" />
|
||||
<Content DisplayName="AllowRipInProcessView" Default="false" />
|
||||
<Content DisplayName="AllowEditCellAccessPerm" Default="false" Description="是否启用单元格权限编辑功能;选中的参数将被加入白名单,始终在Process视图的Recipe表格中显示其参数值"/>
|
||||
<Content DisplayName="AllowRipInProcessView" Default="false" Description="是否允许工艺中更新Recipe功能" />
|
||||
<Content DisplayName="ShowValueInProcessView" Default="false" Description="是否允许Process视图中显示Recipe参数;如果为False,则白名单以外的参数显示为‘*’号" />
|
||||
<Content DisplayName="AllowSaveInProcessView" Default="false" Description="是否允许Process视图中保存Recipe" />
|
||||
</Group>
|
||||
</Catalog>
|
||||
|
||||
|
|
|
@ -478,8 +478,8 @@ namespace SicModules.PMs
|
|||
DATA.Subscribe($"{Module}.Status", () => StringFsmStatus.Replace("0", "").Replace("1", "").Replace("2", ""));
|
||||
DATA.Subscribe($"{Module}.IsOnline", () => IsOnline);
|
||||
DATA.Subscribe($"{Module}.IsService", () => IsServiceIdle);
|
||||
DATA.Subscribe($"{Module}.DI206EqualsTrue_OR_DO177EqualsTrue", () => DI206EqualsTrue_OR_DO177EqualsTrue);
|
||||
|
||||
DATA.Subscribe($"{Module}.DI206EqualsTrue_OR_DO177EqualsTrue", () => DI206EqualsTrue_OR_DO177EqualsTrue, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
||||
|
||||
DATA.Subscribe($"{Module}.IsAlarm", () => IsAlarm);
|
||||
DATA.Subscribe($"{Module}.IsWarning", () => IsWarning);
|
||||
DATA.Subscribe($"{Module}.IsIdle", () => !IsWarning && (IsIdle || IsInit || IsSafety));
|
||||
|
|
|
@ -38,9 +38,11 @@
|
|||
<appender-ref ref="txtFileAppender"/>
|
||||
</root>
|
||||
</log4net>
|
||||
<system.diagnostics>
|
||||
<!--<system.diagnostics>
|
||||
<sources>
|
||||
<source name="System.ServiceModel" switchValue="Information,ActivityTracing" propagateActivity="true">
|
||||
<source name="System.ServiceModel"
|
||||
switchValue="Information, ActivityTracing"
|
||||
propagateActivity="true" >
|
||||
<listeners>
|
||||
<add name="xml"/>
|
||||
</listeners>
|
||||
|
@ -56,7 +58,7 @@
|
|||
</sharedListeners>
|
||||
<trace autoflush="true"/>
|
||||
</system.diagnostics>
|
||||
<!--<system.diagnostics>
|
||||
<system.diagnostics>
|
||||
<sources>
|
||||
<source name="System.ServiceModel.MessageLogging">
|
||||
<listeners>
|
||||
|
@ -68,9 +70,6 @@
|
|||
</sources>
|
||||
</system.diagnostics>-->
|
||||
<system.serviceModel>
|
||||
<!--<diagnostics>
|
||||
<messageLogging logEntireMessage="true" logMalformedMessages="false" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false" maxMessagesToLog="3000" maxSizeOfMessageToLog="2000" />
|
||||
</diagnostics>-->
|
||||
<bindings>
|
||||
<netTcpBinding>
|
||||
<binding name="Aitex_netTcpBinding" maxReceivedMessageSize="102400000" receiveTimeout="infinite">
|
||||
|
@ -101,7 +100,12 @@
|
|||
</services>
|
||||
|
||||
<client>
|
||||
<endpoint address="net.tcp://localhost:6701/SimulatorAdsPlcService" behaviorConfiguration="EndpointBehavior" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" name="Client_IWcfPlcService"/>
|
||||
<endpoint address="net.tcp://localhost:6701/SimulatorAdsPlcService"
|
||||
behaviorConfiguration="EndpointBehavior"
|
||||
binding="netTcpBinding"
|
||||
bindingConfiguration="Aitex_netTcpBinding"
|
||||
contract="MECF.Framework.Common.PLC.IWcfPlcService"
|
||||
name="Client_IWcfPlcService"/>
|
||||
</client>
|
||||
<behaviors>
|
||||
<serviceBehaviors>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<roles>
|
||||
<roleItem id="0" name="Manager" autologout="1" logouttime="20">
|
||||
<roleItem id="0" name="Manager" autologout="1" logouttime="20" buildin="true">
|
||||
Header,3;Overview,3;TM,3;EFEM,3;Device,3;ioPlatform,3;LeakCheck,3;Sequence,3;Recipe,3;EventLog,3;RealTimeCharting,3;WaferHistory,3;DataHistory,3;
|
||||
Charting,3;Config,3;Account,3;Role,3;Runtime,3;Alarm,3;mainPM1,3;processPM1,3;ioPM1,3;motionPM1,3;heaterPM1,3;alarmPM1,3;MFCFlowPM1,3;mainPM2,3;
|
||||
processPM2,3;ioPM2,3;motionPM2,3;heaterPM2,3;alarmPM2,3;MFCFlowPM2,3;
|
||||
|
@ -26,7 +26,7 @@
|
|||
Step33,3;Step34,3;Step35,3;Step36,3;Step37,3;Step38,3;Step39,3;Step40,3;Step41,3;Step42,3;Step43,3;Step44,3;Step45,3;Step46,3;Step47,3;Step48,3;Step49,3;
|
||||
Step50,3;
|
||||
</roleItem>
|
||||
<roleItem id="1" name="Engineer" autologout="1" logouttime="20">
|
||||
<roleItem id="1" name="Engineer" autologout="1" logouttime="20" buildin="true">
|
||||
Header,3;Overview,3;TM,3;EFEM,3;Device,3;ioPlatform,3;LeakCheck,3;Sequence,3;Recipe,3;EventLog,3;RealTimeCharting,3;WaferHistory,3;DataHistory,3;
|
||||
Charting,3;Config,3;Account,3;Role,3;Runtime,3;Alarm,3;mainPM1,3;processPM1,3;ioPM1,3;motionPM1,3;heaterPM1,3;alarmPM1,3;MFCFlowPM1,3;mainPM2,3;
|
||||
processPM2,3;ioPM2,3;motionPM2,3;heaterPM2,3;alarmPM2,3;MFCFlowPM2,3;
|
||||
|
@ -51,7 +51,7 @@
|
|||
Step33,3;Step34,3;Step35,3;Step36,3;Step37,3;Step38,3;Step39,3;Step40,3;Step41,3;Step42,3;Step43,3;Step44,3;Step45,3;Step46,3;Step47,3;Step48,3;Step49,3;
|
||||
Step50,3;
|
||||
</roleItem>
|
||||
<roleItem id="2" name="Technician" autologout="1" logouttime="20">
|
||||
<roleItem id="2" name="Technician" autologout="1" logouttime="20" buildin="true">
|
||||
Header,3;Overview,3;TM,3;EFEM,3;Device,3;ioPlatform,3;LeakCheck,3;Sequence,3;Recipe,3;EventLog,3;RealTimeCharting,3;WaferHistory,3;DataHistory,3;
|
||||
Charting,3;Config,3;Account,3;Role,3;Runtime,3;Alarm,3;mainPM1,3;processPM1,3;ioPM1,3;motionPM1,3;heaterPM1,3;alarmPM1,3;MFCFlowPM1,3;mainPM2,3;
|
||||
processPM2,3;ioPM2,3;motionPM2,3;heaterPM2,3;alarmPM2,3;MFCFlowPM2,3;
|
||||
|
@ -76,7 +76,7 @@
|
|||
Step33,3;Step34,3;Step35,3;Step36,3;Step37,3;Step38,3;Step39,3;Step40,3;Step41,3;Step42,3;Step43,3;Step44,3;Step45,3;Step46,3;Step47,3;Step48,3;Step49,3;
|
||||
Step50,3;
|
||||
</roleItem>
|
||||
<roleItem id="3" name="Operator" autologout="1" logouttime="20">
|
||||
<roleItem id="3" name="Operator" autologout="1" logouttime="20" buildin="true">
|
||||
Header,3;Overview,3;TM,3;EFEM,3;Device,3;ioPlatform,3;LeakCheck,3;Sequence,3;Recipe,3;EventLog,3;RealTimeCharting,3;WaferHistory,3;DataHistory,3;
|
||||
Charting,3;Config,3;Account,3;Role,3;Runtime,3;Alarm,3;mainPM1,3;processPM1,3;ioPM1,3;motionPM1,3;heaterPM1,3;alarmPM1,3;MFCFlowPM1,3;mainPM2,3;
|
||||
processPM2,3;ioPM2,3;motionPM2,3;heaterPM2,3;alarmPM2,3;MFCFlowPM2,3;
|
||||
|
|
|
@ -1,6 +1,37 @@
|
|||
create or replace function update_db_model() returns void as
|
||||
$$
|
||||
begin
|
||||
------------------------------------------------------------------------------------------------
|
||||
--
|
||||
if not exists(select * from information_schema.tables
|
||||
where
|
||||
table_catalog = CURRENT_CATALOG and table_schema = CURRENT_SCHEMA
|
||||
and table_name = 'credentials_history') then
|
||||
|
||||
CREATE TABLE credentials_history
|
||||
(
|
||||
"uid" serial NOT NULL,
|
||||
"login_name" varchar(50),
|
||||
"role_id" varchar(10),
|
||||
"host_name" varchar(100),
|
||||
"host_ip" varchar(50),
|
||||
"host_port" varchar(10),
|
||||
"os_version" varchar(50),
|
||||
"computer_info" text,
|
||||
"cpu_info" text,
|
||||
"disk_info" text,
|
||||
"operation" varchar(50),
|
||||
"operation_time" timestamp without time zone,
|
||||
CONSTRAINT "credentials_history_pkey" PRIMARY KEY ("uid" )
|
||||
)
|
||||
WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
ALTER TABLE credentials_history
|
||||
OWNER TO postgres;
|
||||
GRANT SELECT ON TABLE credentials_history TO postgres;
|
||||
end if;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------
|
||||
--
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</EventDefinition>
|
||||
<EventDefinition>
|
||||
<Id>10</Id>
|
||||
<Description>'{0}' 退出系统。</Description>
|
||||
<Description>{0} logged out</Description>
|
||||
<Level>Information</Level>
|
||||
<EventEnum>UserLoggedOff</EventEnum>
|
||||
<DetailDesc>用户退出系统。</DetailDesc>
|
||||
|
@ -18,11 +18,11 @@
|
|||
</EventDefinition>
|
||||
<EventDefinition>
|
||||
<Id>11</Id>
|
||||
<Description>User {0} login</Description>
|
||||
<Description>User {0} logged in</Description>
|
||||
<Level>Information</Level>
|
||||
<EventEnum>UserLoggedIn</EventEnum>
|
||||
<DetailDesc>用户登录</DetailDesc>
|
||||
<GlobalDescription_en>User {0} login</GlobalDescription_en>
|
||||
<GlobalDescription_en>User {0} logged in</GlobalDescription_en>
|
||||
<GlobalDescription_zh>账号{0}登录</GlobalDescription_zh>
|
||||
<Solution />
|
||||
</EventDefinition>
|
||||
|
|
|
@ -237,6 +237,12 @@
|
|||
<Name>SicModules</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Config\Menu.xml">
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
|
|
|
@ -3,17 +3,35 @@
|
|||
<configSections>
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a" />
|
||||
</configSections>
|
||||
<!--<system.diagnostics>
|
||||
<sources>
|
||||
<source name="System.ServiceModel"
|
||||
switchValue="Information, ActivityTracing"
|
||||
propagateActivity="true" >
|
||||
<listeners>
|
||||
<add name="xml"/>
|
||||
</listeners>
|
||||
</source>
|
||||
<source name="System.ServiceModel.MessageLogging">
|
||||
<listeners>
|
||||
<add name="xml"/>
|
||||
</listeners>
|
||||
</source>
|
||||
<source name="myUserTraceSource"
|
||||
switchValue="Information, ActivityTracing">
|
||||
<listeners>
|
||||
<add name="xml"/>
|
||||
</listeners>
|
||||
</source>
|
||||
</sources>
|
||||
<sharedListeners>
|
||||
<add name="xml"
|
||||
type="System.Diagnostics.XmlWriterTraceListener"
|
||||
initializeData="Error.svclog" />
|
||||
</sharedListeners>
|
||||
</system.diagnostics>-->
|
||||
|
||||
<system.serviceModel>
|
||||
<!--<diagnostics>
|
||||
<messageLogging
|
||||
logEntireMessage="false"
|
||||
logMalformedMessages="false"
|
||||
logMessagesAtServiceLevel="true"
|
||||
logMessagesAtTransportLevel="false"
|
||||
maxMessagesToLog="3000"
|
||||
maxSizeOfMessageToLog="2000"/>
|
||||
</diagnostics>-->
|
||||
|
||||
<bindings>
|
||||
<netTcpBinding>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<ResourceDictionary>
|
||||
|
||||
<converters:DummyConverter x:Key="dummyConverter" />
|
||||
<cv:ReserveBoolSensorConverter x:Key="BoolReverseConverter" />
|
||||
<cv:BoolReverseConverter x:Key="BoolReverseConverter" />
|
||||
<cv:BoolVisibilityConverter x:Key="BoolVisibilityConverter" />
|
||||
<cv:BoolCollapsedConverter x:Key="BoolCollapsedConverter" />
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ using Aitex.Core.WCF;
|
|||
using CommandLine;
|
||||
using MECF.Framework.UI.Client.ClientBase;
|
||||
using SciChart.Charting.Visuals;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SicUI.Client
|
||||
{
|
||||
|
@ -137,6 +138,7 @@ namespace SicUI.Client
|
|||
|
||||
#endif
|
||||
|
||||
Task tLoadSysInfo;
|
||||
try
|
||||
{
|
||||
|
||||
|
@ -178,6 +180,16 @@ namespace SicUI.Client
|
|||
|
||||
#endregion
|
||||
|
||||
_splashScreen?.SetMessage1("Initialize logging system ...");
|
||||
Singleton<Aitex.Core.RT.Log.LogManager>.Instance.Initialize();
|
||||
|
||||
BaseApp.Instance = new ClientApp();
|
||||
|
||||
tLoadSysInfo = Task.Run(() =>
|
||||
{
|
||||
BaseApp.Instance.LoadSystemInfo();
|
||||
});
|
||||
|
||||
_splashScreen?.SetMessage1(
|
||||
$"Connecting to SicRT ({hostEndpoint.Address.Host}), please wait ...");
|
||||
|
||||
|
@ -204,7 +216,6 @@ namespace SicUI.Client
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!EventClient.Instance.ConnectRT())
|
||||
{
|
||||
_splashScreen?.Complete();
|
||||
|
@ -223,11 +234,10 @@ namespace SicUI.Client
|
|||
return;
|
||||
}
|
||||
|
||||
_splashScreen?.SetMessage1("Initialize logging system ...");
|
||||
Singleton<Aitex.Core.RT.Log.LogManager>.Instance.Initialize();
|
||||
BaseApp.Instance.Initialize();
|
||||
|
||||
_splashScreen?.SetMessage1("Initialize sub modules ...");
|
||||
BaseApp.Instance = new ClientApp();
|
||||
_splashScreen?.SetMessage1("Preparing Environment ...");
|
||||
Task.WaitAll(tLoadSysInfo);
|
||||
|
||||
_splashScreen?.SetMessage1("Loading the window ...");
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace SicUI.Converter
|
||||
{
|
||||
internal class IsReadOnlyModeToUserInfoNameBgConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var defaultColor = Color.FromRgb(0xC8, 0xE8, 0xFF); //FFC8E8FF
|
||||
|
||||
if (value is bool isReadOnlyMode)
|
||||
{
|
||||
if (isReadOnlyMode)
|
||||
return new SolidColorBrush(Colors.Orange);
|
||||
else
|
||||
{
|
||||
var res = Application.Current.TryFindResource("TopFrame_UserInfoBG");
|
||||
if (res is SolidColorBrush brush)
|
||||
return brush;
|
||||
else
|
||||
return new SolidColorBrush(defaultColor);
|
||||
}
|
||||
}
|
||||
|
||||
return new SolidColorBrush(defaultColor);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cal="http://www.caliburn.org"
|
||||
xmlns:client="clr-namespace:SicUI.Client"
|
||||
xmlns:converter="clr-namespace:MECF.Framework.UI.Client.Ctrlib.Converter;assembly=MECF.Framework.UI.Client"
|
||||
xmlns:deviceControl="clr-namespace:Aitex.Core.UI.DeviceControl;assembly=MECF.Framework.UI.Core"
|
||||
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
|
||||
xmlns:wnd="http://OpenSEMI.Ctrlib.com/presentation"
|
||||
|
@ -13,20 +12,45 @@
|
|||
xmlns:controls="clr-namespace:MECF.Framework.UI.Client.Ctrlib.Controls;assembly=MECF.Framework.UI.Client"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
Title="MainView"
|
||||
Width="1900"
|
||||
Height="980"
|
||||
xmlns:converter="clr-namespace:SicUI.Converter"
|
||||
Title="Sic Auto Edition"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
WindowState="Maximized"
|
||||
WindowState="Maximized"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance Type=client:MainViewModel, IsDesignTimeCreatable=False}">
|
||||
<Window.Resources>
|
||||
<client:CollectionLastIndexConverter x:Key="collectionLastIndexConverter" />
|
||||
<converter:UnitOnlineBorderColorConverter x:Key="UnitOnlineBorderColorConverter" />
|
||||
<converter:IsReadOnlyModeToUserInfoNameBgConverter x:Key="IsReadOnlyModeToUserInfoNameBgConverter" />
|
||||
</Window.Resources>
|
||||
|
||||
<Grid Background="{DynamicResource MainArea_BG}">
|
||||
<Grid x:Name="LoginPart" Background="{StaticResource Login_BG}">
|
||||
<Grid x:Name="LoginPart" Panel.ZIndex="0" Background="{StaticResource Login_BG}">
|
||||
<Grid.Style>
|
||||
<Style>
|
||||
<Style.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsLogin}" Value="True"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Grid.Visibility" Value="Hidden" />
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsLogin}" Value="False"/>
|
||||
<Condition Binding="{Binding IsReadOnlyMode}" Value="True"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Grid.Visibility" Value="Hidden" />
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsLogin}" Value="False"/>
|
||||
<Condition Binding="{Binding IsReadOnlyMode}" Value="False"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Grid.Visibility" Value="Visible" />
|
||||
</MultiDataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<Ellipse
|
||||
MaxWidth="1000"
|
||||
MaxHeight="800"
|
||||
|
@ -241,7 +265,7 @@
|
|||
TabIndex="1">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="KeyDown">
|
||||
<cal:ActionMessage MethodName="Enter">
|
||||
<cal:ActionMessage MethodName="PasswordBoxEnterKeyPressed">
|
||||
<cal:Parameter Value="$eventargs" />
|
||||
<cal:Parameter Value="{Binding ElementName=tbLoginName, Path=Text}" />
|
||||
<cal:Parameter Value="{Binding ElementName=pdbPassword}" />
|
||||
|
@ -306,7 +330,7 @@
|
|||
Style="{StaticResource Login_Button}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Click">
|
||||
<cal:ActionMessage MethodName="Login">
|
||||
<cal:ActionMessage MethodName="RequestLogin">
|
||||
<cal:Parameter Value="{Binding ElementName=tbLoginName, Path=Text}" />
|
||||
<cal:Parameter Value="{Binding ElementName=pdbPassword}" />
|
||||
<cal:Parameter Value="{Binding ElementName=cbRole, Path=SelectedValue}" />
|
||||
|
@ -318,15 +342,6 @@
|
|||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
<Grid.Style>
|
||||
<Style>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsLogin}" Value="True">
|
||||
<Setter Property="Grid.Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
</Grid>
|
||||
|
||||
<Border
|
||||
|
@ -334,6 +349,26 @@
|
|||
Padding="1"
|
||||
CornerRadius="4">
|
||||
<Grid x:Name="MainPage">
|
||||
<Grid.Style>
|
||||
<Style>
|
||||
<Style.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsLogin}" Value="False"/>
|
||||
<Condition Binding="{Binding IsReadOnlyMode}" Value="True"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Grid.Visibility" Value="Visible" />
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsLogin}" Value="False"/>
|
||||
<Condition Binding="{Binding IsReadOnlyMode}" Value="False"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Grid.Visibility" Value="Hidden" />
|
||||
</MultiDataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="120" />
|
||||
<RowDefinition />
|
||||
|
@ -396,6 +431,7 @@
|
|||
Text="{Binding SoftwareVersion}" />
|
||||
</StackPanel>
|
||||
<Grid
|
||||
IsHitTestVisible="{Binding IsReadOnlyMode, Converter={StaticResource BoolReverseConverter}}"
|
||||
Grid.Column="1"
|
||||
Margin="-25,8,0,8"
|
||||
ColumnSpan="2">
|
||||
|
@ -478,7 +514,6 @@
|
|||
IsOnline="{Binding IsOnlineWaferRobot}"
|
||||
Status="{Binding WaferRobotStatus}"
|
||||
cal:Message.Attach="[SetOnline] = [Action SetModuleOnline($source, $eventArgs)];[SetOffline] = [Action SetModuleOffline($source, $eventArgs)]" />
|
||||
|
||||
<controls:ModuleStatusIndicator
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
|
@ -572,7 +607,6 @@
|
|||
SelectedIndex="{Binding EventLogsView.Count, Mode=OneWay, Converter={StaticResource collectionLastIndexConverter}}"
|
||||
Style="{DynamicResource Top_ComboBox}"
|
||||
Visibility="{Binding AllEventsVisibility}"/>
|
||||
|
||||
<Label
|
||||
Grid.Column="1"
|
||||
HorizontalContentAlignment="Center"
|
||||
|
@ -587,8 +621,6 @@
|
|||
Foreground="{DynamicResource FG_Black}"
|
||||
IsChecked="{Binding IsShowAlarmEventOnly, Delay=10}" />
|
||||
</Label>
|
||||
|
||||
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Width="90"
|
||||
|
@ -615,22 +647,8 @@
|
|||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</Button>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid
|
||||
Grid.Column="2"
|
||||
Margin="28,10"
|
||||
IsEnabled="{Binding IsPermission}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
<Label
|
||||
Grid.Column="3"
|
||||
Width="50"
|
||||
|
@ -653,7 +671,7 @@
|
|||
</Grid.RowDefinitions>
|
||||
<Border
|
||||
Margin="2,4"
|
||||
Background="{DynamicResource TopFrame_UserInfoBG}"
|
||||
Background="{Binding IsReadOnlyMode, Converter={StaticResource IsReadOnlyModeToUserInfoNameBgConverter}}"
|
||||
BorderBrush="{DynamicResource TopFrame_UserInfoBD}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
|
@ -674,7 +692,7 @@
|
|||
Style="{DynamicResource Logout_Button}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Click">
|
||||
<cal:ActionMessage MethodName="Logout" />
|
||||
<cal:ActionMessage MethodName="ShowLogoutDialog" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</Button>
|
||||
|
@ -682,7 +700,11 @@
|
|||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" Background="{DynamicResource MainArea_BG}">
|
||||
<Grid Grid.Row="1"
|
||||
x:Name="GdContentContainer"
|
||||
Background="{DynamicResource MainArea_BG}"
|
||||
IsHitTestVisible="{Binding IsReadOnlyMode, Converter={StaticResource BoolReverseConverter}}"
|
||||
PreviewKeyDown="GdContentContainer_OnPreviewKeyDown">
|
||||
<ContentControl
|
||||
x:Name="ActiveItem"
|
||||
Margin="10"
|
||||
|
@ -734,15 +756,7 @@
|
|||
</Menu>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Grid.Style>
|
||||
<Style>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsLogin}" Value="False">
|
||||
<Setter Property="Grid.Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
|
|
@ -33,6 +33,13 @@ namespace SicUI.Client
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
private void GdContentContainer_OnPreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
// 如果禁用了鼠标输入,同时禁用键盘输入
|
||||
if (!GdContentContainer.IsHitTestVisible)
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public class CollectionLastIndexConverter : IValueConverter
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,6 +16,7 @@ using SicUI.Controls;
|
|||
using MECF.Framework.UI.Client.CenterViews.Modules.PM;
|
||||
using System.Dynamic;
|
||||
using Caliburn.Micro.Core;
|
||||
using MECF.Framework.Common.Account.Permissions;
|
||||
|
||||
namespace SicUI.Models.Operations.Overviews
|
||||
{
|
||||
|
@ -770,7 +771,7 @@ namespace SicUI.Models.Operations.Overviews
|
|||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
var roleID = BaseApp.Instance.UserContext.RoleID;
|
||||
var roleID = BaseApp.Instance.UserContext.Role.RoleId;
|
||||
var allowProcessMonitorWin = RoleAccountProvider.Instance.GetMenuPermission(roleID, "Operation.Overview.ProcessMonitorWindow") != (int)MenuPermissionEnum.MP_NONE;
|
||||
ProcessMonitorButtonVisibility = allowProcessMonitorWin ? Visibility.Visible : Visibility.Collapsed;
|
||||
base.OnActivate();
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace SicUI.Converter
|
||||
{
|
||||
internal class IsReadOnlyModeToUserInfoNameBgConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var defaultColor = Color.FromRgb(0xC8, 0xE8, 0xFF); //FFC8E8FF
|
||||
|
||||
if (value is bool isReadOnlyMode)
|
||||
{
|
||||
if (isReadOnlyMode)
|
||||
return new SolidColorBrush(Colors.Orange);
|
||||
else
|
||||
{
|
||||
var res = Application.Current.TryFindResource("TopFrame_UserInfoBG");
|
||||
if (res is SolidColorBrush brush)
|
||||
return brush;
|
||||
else
|
||||
return new SolidColorBrush(defaultColor);
|
||||
}
|
||||
}
|
||||
|
||||
return new SolidColorBrush(defaultColor);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,8 +7,6 @@ namespace SicUI.Models.PMs
|
|||
{
|
||||
public class PMAlarmViewModel : SicModuleUIViewModelBase, ISupportMultipleSystem
|
||||
{
|
||||
public bool IsPermission { get => this.Permission == 3; }
|
||||
|
||||
[IgnorePropertyChange]
|
||||
public List<AlarmItem> AlarmEvents { get; set; }
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ namespace SicUI.Models.PMs
|
|||
|
||||
public Visibility TipsVisble => IsConfinementRingUp && !IsOnline ? Visibility.Hidden : Visibility.Visible;
|
||||
|
||||
public bool IsPermission { get => this.Permission == 3; }
|
||||
public bool IsActionEnable => IsConfinementRingUp && !IsOnline;
|
||||
public bool IsActionEnable1 => false;
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ namespace SicUI.Models.PMs
|
|||
|
||||
public Visibility TipsVisble => RingUpSensor ? Visibility.Hidden : Visibility.Visible;
|
||||
|
||||
public bool IsPermission { get => this.Permission == 3; }
|
||||
public bool IsActionEnable => RingUpSensor && !IsOnline;
|
||||
public bool IsActionEnable1 => false;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ using Aitex.Core.Common.DeviceData.IoDevice;
|
|||
using MECF.Framework.Common.Aitex.Core.Common.DeviceData;
|
||||
using System.CodeDom;
|
||||
using System;
|
||||
using MECF.Framework.Common.Account.Permissions;
|
||||
|
||||
namespace SicUI.Models.PMs
|
||||
{
|
||||
|
@ -829,8 +830,6 @@ namespace SicUI.Models.PMs
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsPermission { get => this.Permission == 3; }
|
||||
|
||||
public string Module => SystemName;
|
||||
|
||||
|
||||
|
@ -1346,9 +1345,9 @@ namespace SicUI.Models.PMs
|
|||
base.InitPM();
|
||||
|
||||
//权限
|
||||
var roleID = BaseApp.Instance.UserContext.RoleID;
|
||||
reactorStatusEnable = RoleAccountProvider.Instance.GetMenuPermission(roleID, "PM1.Main.ReactorStatus") == 3;
|
||||
reactorServiceEnable = RoleAccountProvider.Instance.GetMenuPermission(roleID, "PM1.Main.ReactorService") == 3;
|
||||
var roleID = BaseApp.Instance.UserContext.Role.RoleId;
|
||||
reactorStatusEnable = RoleAccountProvider.Instance.GetMenuPermission(roleID, "PM1.Main.ReactorStatus") == MenuPermissionEnum.MP_READ_WRITE;
|
||||
reactorServiceEnable = RoleAccountProvider.Instance.GetMenuPermission(roleID, "PM1.Main.ReactorService") == MenuPermissionEnum.MP_READ_WRITE;
|
||||
}
|
||||
|
||||
private bool reactorStatusEnable;
|
||||
|
|
|
@ -291,6 +291,7 @@ if exist "$(ProjectDir)..\SicSetup\Packages\SicUI\PresetGroups" rd "$(ProjectDir
|
|||
<Compile Include="Models\PMs\ContinueSelectDialogView.xaml.cs">
|
||||
<DependentUpon>ContinueSelectDialogView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\PMs\Converters\IsReadOnlyModeToUserInfoNameBgConverter.cs" />
|
||||
<Compile Include="Models\PMs\Converters\WaterTempDeviceDataToToolTipConverter.cs" />
|
||||
<Compile Include="Models\PMs\InverseBoolConverter.cs" />
|
||||
<Compile Include="Models\PMs\PMAlarmView.xaml.cs">
|
||||
|
@ -398,6 +399,7 @@ if exist "$(ProjectDir)..\SicSetup\Packages\SicUI\PresetGroups" rd "$(ProjectDir
|
|||
<DependentUpon>Splash.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="StartupArguments.cs" />
|
||||
<Compile Include="TimeredMainViewModel.cs" />
|
||||
<Page Include="Controls\AITPump.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -693,12 +695,6 @@ if exist "$(ProjectDir)..\SicSetup\Packages\SicUI\PresetGroups" rd "$(ProjectDir
|
|||
<ItemGroup>
|
||||
<Resource Include="Themes\Images\parts\atmrobot\image02.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Config\Menu.xml">
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Themes\Images\parts\image15.png" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -5,13 +5,19 @@
|
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SicUI"
|
||||
mc:Ignorable="d"
|
||||
ResizeMode="NoResize"
|
||||
ResizeMode="CanResize"
|
||||
WindowStyle="None"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="Splash" Height="510" Width="850"
|
||||
Background="Transparent"
|
||||
AllowsTransparency="True"
|
||||
SnapsToDevicePixels="True">
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome ResizeBorderThickness="0" CaptionHeight="0"/>
|
||||
</WindowChrome.WindowChrome>
|
||||
<Window.Effect>
|
||||
<DropShadowEffect Color="Gray" BlurRadius="20" Direction="-90" RenderingBias="Quality" ShadowDepth="10"/>
|
||||
</Window.Effect>
|
||||
<Grid >
|
||||
<Image Source="/Resources/Images/Splash.png" Stretch="Fill" />
|
||||
<TextBlock
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
using Aitex.Core.Util;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using Aitex.Core.RT.Log;
|
||||
using Cali = Caliburn.Micro.Core;
|
||||
using MECF.Framework.Common.DataCenter;
|
||||
|
||||
namespace SicUI
|
||||
{
|
||||
public class TimeredMainViewModel : Cali.Conductor<Cali.Screen>.Collection.OneActive
|
||||
{
|
||||
PeriodicJob _timer;
|
||||
ConcurrentBag<string> _subscribedKeys = new ConcurrentBag<string>();
|
||||
|
||||
Func<object, bool> _isSubscriptionAttribute;
|
||||
Func<MemberInfo, bool> _hasSubscriptionAttribute;
|
||||
|
||||
public TimeredMainViewModel()
|
||||
{
|
||||
_timer = new PeriodicJob(1000, this.OnTimer, "UIUpdaterThread - " + GetType().Name);
|
||||
|
||||
_isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
|
||||
_hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
|
||||
|
||||
SubscribeKeys(this);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct LASTINPUTINFO
|
||||
{
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
public int cbSize;
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
public int dwTime;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
|
||||
/// <summary>
|
||||
/// 获取鼠标键盘不活动的时间
|
||||
/// </summary>
|
||||
/// <returns>结果</returns>
|
||||
public static int GetLastInputTime()
|
||||
{
|
||||
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
|
||||
lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo);
|
||||
lastInputInfo.dwTime = 0;
|
||||
|
||||
int idleTime = 0;
|
||||
if (GetLastInputInfo(ref lastInputInfo))
|
||||
{
|
||||
idleTime = Environment.TickCount - lastInputInfo.dwTime;
|
||||
}
|
||||
|
||||
return ((idleTime > 0) ? (idleTime / 1000) : 0);
|
||||
}
|
||||
|
||||
protected virtual bool OnTimer()
|
||||
{
|
||||
try
|
||||
{
|
||||
Poll();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LOG.Error(ex.Message);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public virtual void EnableTimer(bool enable)
|
||||
{
|
||||
if (enable) _timer.Start();
|
||||
else _timer.Pause();
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Poll()
|
||||
{
|
||||
if (_subscribedKeys.Count > 0)
|
||||
{
|
||||
Dictionary<string, object> result = QueryDataClient.Instance.Service.PollData(_subscribedKeys);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
LOG.Error("获取RT数据失败");
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.Count != _subscribedKeys.Count)
|
||||
{
|
||||
string unknowKeys = string.Empty;
|
||||
foreach (string key in _subscribedKeys)
|
||||
{
|
||||
if (!result.ContainsKey(key))
|
||||
{
|
||||
unknowKeys += key + "\r\n";
|
||||
}
|
||||
}
|
||||
//System.Diagnostics.Debug.Assert(false, unknowKeys);
|
||||
}
|
||||
|
||||
InvokeBeforeUpdateProperty(result);
|
||||
|
||||
UpdateValue(result);
|
||||
|
||||
Application.Current.Dispatcher.Invoke(new System.Action(() =>
|
||||
{
|
||||
InvokePropertyChanged();
|
||||
|
||||
InvokeAfterUpdateProperty(result);
|
||||
}));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void InvokePropertyChanged()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
protected virtual void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void InvokeAfterUpdateProperty(Dictionary<string, object> data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UpdateValue(Dictionary<string, object> data)
|
||||
{
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
UpdateSubscribe(data, this);
|
||||
|
||||
var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<SubscriptionModuleAttribute>() != null);
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var moduleAttr = property.GetCustomAttribute<SubscriptionModuleAttribute>();
|
||||
UpdateSubscribe(data, property.GetValue(this), moduleAttr.Module);
|
||||
}
|
||||
}
|
||||
|
||||
protected void Subscribe(string key)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
_subscribedKeys.Add(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void SubscribeKeys(TimeredMainViewModel target)
|
||||
{
|
||||
Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
|
||||
property =>
|
||||
{
|
||||
SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
|
||||
string key = subscription.ModuleKey;
|
||||
if (!_subscribedKeys.Contains(key))
|
||||
_subscribedKeys.Add(key);
|
||||
});
|
||||
|
||||
Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
|
||||
method =>
|
||||
{
|
||||
SubscriptionAttribute subscription = method.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
|
||||
string key = subscription.ModuleKey;
|
||||
if (!_subscribedKeys.Contains(key))
|
||||
_subscribedKeys.Add(key);
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdateSubscribe(Dictionary<string, object> data, object target, string module = null)
|
||||
{
|
||||
Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
|
||||
property =>
|
||||
{
|
||||
PropertyInfo pi = (PropertyInfo)property;
|
||||
SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
|
||||
string key = subscription.ModuleKey;
|
||||
key = module == null ? key : string.Format("{0}.{1}", module, key);
|
||||
|
||||
if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
var convertedValue = Convert.ChangeType(data[key], pi.PropertyType);
|
||||
var originValue = Convert.ChangeType(pi.GetValue(target, null), pi.PropertyType);
|
||||
if (originValue != convertedValue)
|
||||
{
|
||||
if (pi.Name == "PumpLimitSetPoint")
|
||||
pi.SetValue(target, convertedValue, null);
|
||||
else
|
||||
pi.SetValue(target, convertedValue, null);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LOG.Error("由RT返回的数据更新失败" + key, ex);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
|
||||
property =>
|
||||
{
|
||||
FieldInfo pi = (FieldInfo)property;
|
||||
SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
|
||||
string key = subscription.ModuleKey;
|
||||
|
||||
if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
var convertedValue = Convert.ChangeType(data[key], pi.FieldType);
|
||||
pi.SetValue(target, convertedValue);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LOG.Error("由RT返回的数据更新失败" + key, ex);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue