Commit 2a8d7116 authored by 姜春辉's avatar 姜春辉

整理项目结构

Signed-off-by: 姜春辉's avatar姜春辉 <gaigai3355@hotmail.com>
parent f29cd5fc
<?xml version="1.0" encoding="utf-8" ?>
<Settings AddonName="GS.Remote.Synchronize" xmlns="urn:Chinags-Configuration">
<Structures>
<Structure Name="Syncs" Caption="同步管理">
<Declare>
<Property Name="DisPlayName" Caption="同步标题"></Property>
<Property Name="SyncSubject" Caption="同步名称"></Property>
<Property Name="SyncIndex" Caption="同步序号"></Property>
<Property Name="isPolling" Caption="是否自动"></Property>
<Property Name="isEnable" Caption="是否启用"></Property>
<Property Name="Interval" Caption="间隔时间"></Property>
<Property Name="ImplDLLName" Caption="实现类库"></Property>
<Property Name="Souces" Caption="数据来源(服务地址)" ></Property>
<Property Name="Screen" Caption="废弃字段"></Property>
<Property Name="isPackage" Caption="是否分包"></Property>
<Property Name="Tag" Caption="标识"></Property>
</Declare>
<Datas>
<Data DisPlayName="人员信息同步" SyncSubject="emply" SyncIndex="1" isPolling="true" isEnable="true" Interval="60000" ImplDLLName="GS.Synchronous.Emply.dll" Souces="/Services/Identification/GetAllCard/json" Tag="" Screen=""/>
<Data DisPlayName="假条信息同步" SyncSubject="leave" SyncIndex="2" isPolling="true" isEnable="true" Interval="60000" ImplDLLName="GS.Synchronous.Emply.dll" Souces="/Services/Identification/GetAllLeave/json" Tag="" Screen=""/>
<Data DisPlayName="宿舍信息同步" SyncSubject="bedroom" SyncIndex="3" isPolling="true" isEnable="true" Interval="60000" ImplDLLName="GS.Synchronous.Emply.dll" Souces="/Services/Identification/GetAllBedRoom/json" Tag="" Screen=""/>
<Data DisPlayName="宿舍统计汇总同步" SyncSubject="bedroomsummary" SyncIndex="4" isPolling="true" isEnable="true" Interval="30000" ImplDLLName="GS.Synchronous.Emply.dll" Souces="/Services/Identification/BedRoomSummary/json" Tag="" Screen=""/>
<Data DisPlayName="校门统计汇总同步" SyncSubject="commonsummary" SyncIndex="4" isPolling="true" isEnable="true" Interval="30000" ImplDLLName="GS.Synchronous.Emply.dll" Souces="/Services/Identification/CommonSummary/json" Tag="" Screen=""/>
</Datas>
</Structure>
</Structures>
</Settings>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0" Name="通软远程同步插件" SymbolicName="GS.Remote.Synchronize" Version="2.0.0" StartLevel="50">
<License>G9qz0tn2lAHmmSZ540Wirn9/UuZE4twBn0Q0+YIFL3cuwIyUVwTCRvDkv/4IiZbAowwUv05TUk2i0jmGSLsH0O7zaef/JjEMw1e+/T63l9lKJLup8a1Rx6DDfDhgy8swmpD2/33KS2MRCdBtgkZiYN403E4MAFNcEHPcMPYD90U=</License>
<Activator Type="GS.Remote.Synchronize.Activator" />
<Runtime>
<Assembly Path="GS.Remote.Synchronize.dll" Share="true" />
</Runtime>
<ObjectSpaces>
</ObjectSpaces>
<Services>
<Service Caption="注册数据同步相关服务" TypeAndName="GS.Remote.Synchronize.EasyTask.IEasyTaskService"></Service>
</Services>
</Extensibility>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns="urn:Chinags-Configuration" AddonName="GS.Terminal.Console">
<Dictionaries>
<Dict Name="baseConfig" Caption="基本配置">
<Key Name="WatchPort" Value="10031" Caption="监听端口" Choice="" />
<Key Name="HttpPort" Value="10032" Caption="控制页面端口" Choice="" />
</Dict>
</Dictionaries>
</Settings>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0" Name="终端控制台插件" SymbolicName="GS.Terminal.Console" Version="1.0.0.0" StartLevel="10">
<License>hPnEXlXcHZOUdEa4a8sn56bTmI9lqbfLm/krwT3T7KFeREu3k58r9HCL/9p4ZrbYlrf6a14Bquo70dQN4zVxCEN+OoF9zCU7BCjqD7Z9PpnWv0yEeV/hD4/VvDzchq3sV64XgtxIIuKrI+WjZ/gZcMVQRq2RwCE/hgHbDtcoT6k=</License>
<Activator Type="GS.Terminal.Console.Activator" />
<Runtime>
<Assembly Path="GS.Terminal.Console.dll" Share="true" />
</Runtime>
<Services>
<Service Caption="远程指令服务" TypeAndName="GS.Terminal.Console.Services.RemoteService">
<!--
/// <summary>
/// 开始向远程机发送心跳
/// </summary>
/// <param name="remoteIp">地址</param>
/// <param name="remotePort">端口</param>
/// <param name="interval">间隔</param>
void StartHeart(string remoteIp,int remotePort, int interval)
发送心跳指令$Heart
指令内容通过 TERMINAL_STATUS 公共交互字段填充
/// <summary>
/// 停止发送心跳
/// </summary>
/// <param name="remoteIp">心跳远程地址</param>
void StopHeart(string remoteIp)
/// <summary>
/// 发送ping指令
/// </summary>
/// <param name="serverIP">服务器ip</param>
/// <param name="StatusChangedCallback">ping指令状态变更回调</param>
void StartPing(string serverIP,Action<IPStatus> StatusChangedCallback)
/// <summary>
/// 停止Ping
/// </summary>
/// <param name="serverIP">服务器地址</param>
/// <param name="StatusChangedCallback">移除事件</param>
void StopPing(string serverIP, Action<IPStatus> StatusChangedCallback)
-->
</Service>
</Services>
</Extensibility>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Settings AddonName="GS.Terminal.DeviceManager" xmlns="urn:Chinags-Configuration">
<Dictionaries>
<Dict Caption="基本配置" Name="BaseConfig">
<Key Caption="卡号反转" Choice="0,1" Name="Isrotate" Value="1"/>
<Key Caption="虚拟读卡间隔" Choice="" Name="VirtualReadCardInterval" Value="2000"/>
<Key Caption="开启虚拟读卡" Choice="0,1" Name="IsOpenVirtualReadCard" Value="1"/>
<Key Caption="卡号是否写日志" Choice="0,1" Name="IsWriteCardNoLog" Value="1"/>
<Key Caption="开启读卡缓存" Choice="0,1" Name="IsOpenCache" Value="true"/>
<Key Caption="缓存时长(秒)" Choice="" Name="CacheInterval" Value="15"/>
<!--<Key Caption="串口数据字符串过滤(正则)" Choice="" Name="SerialStringFilter" Value="550064A50D\w{16}(?&lt;SerialNo&gt;\w{8})\w{6}55" />-->
<Key Caption="串口数据字符串过滤(正则)" Choice="" Name="SerialStringFilter" Value="00\w{4}(?&lt;SerialNo&gt;\w{8})\w{4}00" />
</Dict>
</Dictionaries>
<Structures>
<Structure Name="Device" Caption="设备管理">
<Declare>
<Property Name="DisplayName" Caption="设备名称"></Property>
<Property Name="Type" Caption="设备类型"></Property>
<Property Name="Descript" Caption="描述"></Property>
<Property Name="VID" Caption="厂商ID"></Property>
<Property Name="PID" Caption="产品ID"></Property>
<Property Name="MI" Caption="MIN"></Property>
<Property Name="isVirtual" Caption="是否虚拟设备"></Property>
<Property Name="ImplDLLName" Caption="实现类库"></Property>
<Property Name="isWatch" Caption="是否插拔监控"></Property>
<Property Name="isPolling" Caption="是否轮询"></Property>
<Property Name="AllowFind" Caption="是否允许查找"></Property>
<Property Name="Interval" Caption="轮询间隔"></Property>
<Property Name="Tag" Caption="标识"></Property>
</Declare>
<Datas>
</Datas>
</Structure>
</Structures>
</Settings>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0" Name="终端设备管理插件" SymbolicName="GS.Terminal.DeviceManager" Version="1.0.0.0" StartLevel="45">
<License>
ILs+dORy9gG1KRYJYDkpVKeoyw3aXQPF+oAg5XmFQG0Rrli+Axt2xuespPojd7nDCtc5Qucl7w+EE4eRxFlBs/uoR6zEjWofGTNv1ZsmGQgRQzsGOTQyFhvVnmMrw1M13xO0Im2pZcrYT9OnCMnHP3Cr/hgrptaftI8hT+C2XVE=
</License>
<Activator Type="GS.Terminal.DeviceManager.AddonActivator" />
<Runtime>
<Assembly Path="GS.Terminal.DeviceManager.dll" Share="true" />
</Runtime>
<Services>
<Service TypeAndName="GS.Terminal.DeviceManager.Service.DeviceInfoService" Caption="设备信息管理服务">
<Interface>
<![CDATA[
// 获得设备列表 采用JSON方式返回
string GetJsonDevices()
// 获得设备列表 采用XML方式返回
string GetXmlDevices()
// 获取指定类型的设备列表 采用JSON方式返回
string GetJsonDevicesByType(string deviceTypeName)
// 获取指定类型的设备列表 采用XML方式返回
string GetXmlDevicesByType(string deviceTypeName)
// 获取指定名称的设备 采用XML方式返回
string GetXmlDeviceByName(string deviceName)
// 获取指定名称的设备 采用JSON方式返回
string GetJsonDeviceByName(string deviceName)
]]>
</Interface>
</Service>
<Service TypeAndName="GS.Terminal.DeviceManager.Service.DeviceTiggerService" Caption="设备触发器">
<Interface>
<![CDATA[
//扫描仪获取数据 默认第一个未占用扫描仪数据
void doScanner(Action<dynamic, dynamic> de_OnDeviceCall,string strType)
//读卡器获取数据 默认第一个未占用读卡器数据
string SerialReaderTouch(Action<dynamic,dynamic> de_OnDeviceCall)
//调取默认打印机,进行打印
void doPrint(Action<dynamic, dynamic> de_OnDeviceCall,string printInfo)
]]>
</Interface>
</Service>
<Service TypeAndName="GS.Terminal.DeviceManager.Service.DeviceCallControl" Caption="轮询处理服务注册">
<Interface>
<![CDATA[
//二代证设备事件处理注册
void RegistSecondCallback(Action<dynamic> GetCallback)
//扫描设备事件处理注册
void RegistSacnnerCallback(Action<dynamic> GetCallback)
//读卡器设备事件处理注册
void RegistCardCallback(Action<dynamic> GetCallback)
//二代证设备事件处理注销
void RemoveSecondCallback(Action<dynamic> GetCallback)
//扫描设备事件处理注销
void RemoveSacnnerCallback(Action<dynamic> GetCallback)
//读卡器设备事件处理注销
void RemoveCardCallback(Action<dynamic> GetCallback)
]]>
</Interface>
</Service>
<Service TypeAndName="GS.Terminal.DeviceManager.Service.DeviceConfigControl" Caption="设备配置管理">
<Interface>
<![CDATA[
//对打印机模板进行配置
void PrinterTemplateConfig()
]]>
</Interface>
</Service>
</Services>
</Extensibility>
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns="urn:Chinags-Configuration" AddonName="GS.Terminal.FaceRecognization">
<Dictionaries>
<Dict Name="baseConfig" Caption="基本配置">
<Key Caption="面部识别SDK版本" Choice="" Name="SDKVersion" Value="2" />
<Key Caption="摄像头输出图像尺寸" Choice="" Name="VideoOutPutSize" Value="352,288" />
<Key Caption="摄像头通道编号" Choice="" Name="VideoPort" Value="0" />
<Key Caption="摄像头启动模式" Choice="" Name="VideoMode" Value="" />
<Key Caption="识别间隔" Choice="" Name="RecognizationInterval" Value="1000" />
<Key Caption="是否开启活体检测,进针对SDKVersion为2时生效" Choice="" Name="EnableAliveness" Value="true" />
<Key Caption="摄像头图像输出间隔(毫秒)" Choice="" Name="VideoOutputSpan" Value="20" />
<Key Caption="摄像头画面旋转" Choice="" Name="VideoOutputRotate" Value="0" />
<Key Caption="面部特征值阀值" Choice="" Name="FaceRecognizationValue" Value="0.8" />
<Key Caption="是否为增值版" Choice="" Name="IsArcFacePro" Value="" >
<![CDATA[
增值版需将离线激活文件放置到程序根目录下,重命名为ArcFacePro.dat
]]>
</Key>
</Dict>
</Dictionaries>
</Settings>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0"
Name="提供面部识别服务的插件"
SymbolicName="GS.Terminal.FaceRecognization"
Version="1.0.0.0" StartLevel="10">
<License>Rr+1HM0Sq4Bpkvdel43Ls95HlVj7GKdkBGSBnHLi0a2yCUJBWU/GxD/w4mqHu8AT85wxxV7I0WtxRe8S45zlBYRtd4wEZb0PpAtdcCPzpfwP7ozPI6pHfUMqiF7Evvc08Ech7xSDIu1WW8xUMJiThe1xq61Y2xoaNZWMQWyrGhc=</License>
<Activator Type="GS.Terminal.FaceRecognization.Program" />
<Runtime>
<Assembly Path="GS.Terminal.FaceRecognization.dll" Share="true" />
</Runtime>
<Services>
<Service Caption="面部识别服务"
TypeAndName="GS.Terminal.FaceRecognization.Service"></Service>
<Service Caption="面部识别快速识别引擎服务"
TypeAndName="GS.Terminal.FaceRecognization.ArcFace2FastServices"></Service>
</Services>
</Extensibility>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns="urn:Chinags-Configuration" AddonName="GS.Terminal.LogicShell">
</Settings>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0" Name="终端业务界面插件" SymbolicName="GS.Terminal.LogicShell" Version="2.0.1.0" StartLevel="30">
<License>PQypSf3bqcoeawY+ml/JvhDU784Tc+sIPCMDNb/42vS8AoqOxowMaqfLyPjHuJ1XdGb2rZ0YvlwOyKBVlllR1r+8iGq/4HJ7b9QAyoYbmqDF8gixxRk2PrvV9+lY5eepuUtZ3xi09boITUZ31yz6qtVLaei13YFKAnk5Db2YssY=</License>
<Activator Type="GS.Terminal.LogicShell.Activator" />
<Runtime>
<Assembly Path="GS.Terminal.LogicShell.dll" Share="true" />
</Runtime>
<Services>
<Service Caption="试图控制服务" TypeAndName="GS.Terminal.LogicShell.Interface.IViewHelperService"></Service>
</Services>
</Extensibility>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns="urn:Chinags-Configuration" AddonName="GS.Terminal.MainShell">
<Dictionaries>
<Dict Name="WindowAttribute" Caption="窗体属性">
<Key Caption="窗口头部标题" Name="LogoTitle" Value="" Choice=""/>
<Key Caption="高级设置窗口打开延迟(毫秒)" Name="PasswordWindowDelay" Value="3000" Choice="" />
</Dict>
</Dictionaries>
</Settings>
<?xml version="1.0" encoding="utf-8" ?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0" Name="主界面" SymbolicName="GS.Terminal.MainShell" Version="2.0.0.0" StartLevel="20">
<License>iLVGuqCCTy+V0cauDJoMTHmmpAGXpbej0ziJivEZX1sq8Qo/WBXJ5WEiWWtxpkkf45wkKUmkNJi8auJi5y5X1VYSP+D15/TROtR85kiQpdZx7IHQXpodt3tjhVnpWNwr9s4TiJrIiQQsV4QKVL+7ysElGccdwgLNOa56vTwyouk=</License>
<Activator Type="GS.Terminal.MainShell.Program" />
<Runtime>
<Assembly Path="GS.Terminal.MainShell.dll" Share="true" />
</Runtime>
<Services>
<Service Caption="跳转服务" TypeAndName="GS.Terminal.MainShell.Services.NavigateService"></Service>
<Service Caption="界面控制服务" TypeAndName="GS.Terminal.MainShell.Services.UIService"></Service>
</Services>
</Extensibility>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns="urn:Chinags-Configuration" AddonName="GS.Terminal.Speak">
<Dictionaries>
<Dict Name="baseConfig" Caption="基本设置">
<Key Name="VoiceSpeed" Value="1" Caption="语音播报速度" Choice="0,1,2,3,4,5" />
<Key Name="VoicePackage" Value="1" Caption="语音包序号" Choice="0,1,2,3" />
</Dict>
</Dictionaries>
</Settings>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0" Name="终端语音播报插件" SymbolicName="GS.Terminal.Speak" Version="1.0.0.0" StartLevel="10">
<License>ZIdlI0PmssjqRnU+teBUtPhVVlUGs51sqQW2K/B/8CK47gkBxo35i2/GK+6DDmKLdDKbDjY3NfCW3HjfsvajC3zLBXi8tBmfGG9CH59LyryQF2637T4KY4thHSmeluvwqOdh0USs8grFkx/Fphr/bHYKwPJJeCqp9QUBIk4XPKc=</License>
<Activator Type="GS.Terminal.Speak.Activator" />
<Runtime>
<Assembly Path="GS.Terminal.Speak.dll" Share="true" />
</Runtime>
<Services>
<Service Caption="语音播报服务" TypeAndName="GS.Terminal.Speak.Service">
<!--
/// <summary>
/// 播报文本语音
/// </summary>
/// <param name="SpeakMessage">文本内容</param>
public void Voice(string SpeakMessage)
-->
</Service>
</Services>
</Extensibility>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns="urn:Chinags-Configuration" AddonName="GS.Terminal.Theme">
<Dictionaries>
<Dict Name="Theme" Caption="默认主题">
<Key Caption="主题名称" Choice="" Name="ThemeName" Value="Default"/>
</Dict>
</Dictionaries>
</Settings>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0" Name="终端皮肤管理插件" SymbolicName="GS.Terminal.Theme" Version="1.0.0.0" StartLevel="10">
<License>
ULuQdHnvhrvUlZmzA5BCjYAK7Qd9kGYtaWzaNyalfGLllQno+WuOpN02bNnqtZBVy0CMsc5vHdGEC2CKn1Oo5d0/h0pezKKRK8pWwWVOkN42Slqjd15Zh/fIcKo6JYLaAWhUs1/NAGXPzLIp5GddHGaEEB9RuicntOi9fUa06YE=
</License>
<Activator Type="GS.Terminal.Theme.AddonActivator"/>
<Runtime>
<Assembly Path="GS.Terminal.Theme.dll" Share="true"/>
</Runtime>
<Services>
<Service Caption="主题管理服务" TypeAndName="GS.Terminal.Theme.Service"></Service>
</Services>
</Extensibility>
\ No newline at end of file
ThemeName=Default
ThemeDescribe=默认
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS.EnterpriseIdentification.ServiceModel
{
public class Employee
{
/// <summary>
/// 人员ID
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// 人员姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 部门ID
/// </summary>
public Guid DepartId { get; set; }
/// <summary>
/// 部门名称
/// </summary>
public string DepartName { get; set; }
/// <summary>
/// 卡号
/// </summary>
public string CardNum { get; set; }
/// <summary>
/// 照片路径
/// </summary>
public string PhotoPath { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GS.EnterpriseIdentification.ServiceModel
{
public class EmployeeFaceData
{
public Guid UserId { get; set; }
public byte[] FaceData { get; set; }
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GS.EnterpriseIdentification.ServiceModel</RootNamespace>
<AssemblyName>GS.EnterpriseIdentification.ServiceModel</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Employee.cs" />
<Compile Include="EmployeeFaceData.cs" />
<Compile Include="UploadIdentifyInfoRequestBody.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UploadVisitorIdentifyInfoRequestBody.cs" />
<Compile Include="VisitInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("GS.EnterpriseIdentification.ServiceModel")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GS.EnterpriseIdentification.ServiceModel")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("d9d132f9-e932-42b3-b6bc-1aa597b79a3a")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GS.EnterpriseIdentification.ServiceModel
{
public class UploadIdentifyInfoRequestBody
{
public string tCode { get; set; }
public List<IdentifyInfo> datas { get; set; }
}
public class IdentifyInfo
{
public Guid localid { get; set; }
public Guid EmplyId { get; set; }
public string CardNum { get; set; }
public DateTime CardTime { get; set; }
public byte[] SitePhoto { get; set; }
public int IdentifyMethod { get; set; }
public double FaceResult { get; set; }
public int Tag { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GS.EnterpriseIdentification.ServiceModel
{
public class UploadVisitorIdentifyInfoRequestBody
{
public string tCode { get; set; }
public List<VisitorIdentifyInfo> datas { get; set; }
}
public class VisitorIdentifyInfo
{
public Guid localid { get; set; }
public Guid VisitInfoId { get; set; }
public DateTime CardTime { get; set; }
public byte[] SitePhoto { get; set; }
public int IdentifyMethod { get; set; }
public double FaceResult { get; set; }
public int Tag { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GS.EnterpriseIdentification.ServiceModel
{
public class VisitInfo
{
public string CardNum { get; set; }
public Guid Id { get; set; }
#region 访客信息
public string VisitorName { get; set; }
public string VisitorIdNum { get; set; }
public string Gender { get; set; }
public string Nation { get; set; }
public string VisitorCompany { get; set; }
#endregion
public DateTime VisitTime { get; set; }
public string CarNum { get; set; }
public string CertPhoto { get; set; }
public string PlacePhoto { get; set; }
public bool IsAppointment { get; set; }
public List<byte[]> VisitorFaceData { get; set; } =
new List<byte[]>();
#region 被访信息
public Guid VisitDepartId { get; set; }
public string VisitDepartName { get; set; }
public Guid VisitEmplyId { get; set; }
public string VisitEmplyName { get; set; }
public string VisitArea { get; set; }
#endregion
}
}
using GS.EnterpriseIdentification.ServiceModel;
using GS.Remote.Synchronize.Core;
using GS.Unitive.Framework.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GS.Synchronize.EnterpriseIdentification
{
[Export(typeof(ISyncOperator))]
public class EmployeeSync : ISyncOperator
{
public EmployeeSync()
{
try
{
if (!File.Exists(localDataFile))
File.Create(localDataFile).Dispose();
}
catch { }
}
public string SyncSubject => "employee";
public SyncConfig config { get; set; }
private Syncer Syncer;
private string localDataFile = Path.Combine(Application.StartupPath, "localData", "employee.local");
public void Synchronous(object parameter)
{
if (string.IsNullOrEmpty(config.Souces))
{
AddonRuntime.Instance.LogWriter.Error($"同步器[{SyncSubject}]缺少Souces属性,请在GS.Remote.Synchronize的Config文件中配置", null);
return;
}
if (Syncer == null)
{
Syncer = new Syncer(localDataFile, config.Souces);
}
Syncer.Sync<List<Employee>>();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3CBE05BA-D6B7-49AB-B608-B67A2AC270C9}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GS.Synchronize.EnterpriseIdentification</RootNamespace>
<AssemblyName>GS.Synchronize.EnterpriseIdentification</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Host\GS.Terminal.Identification.EnterpriseHost\GS.Terminal.Identification.EnterpriseHost\Addons\GS.Remote.Synchronize\Synchronous\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="GS.Remote.Synchronize">
<HintPath>..\..\..\Release\Addons\GS.Remote.Synchronize\GS.Remote.Synchronize.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="GS.Unitive.Framework, Version=1.4.0.2, Culture=neutral, PublicKeyToken=769358b197600ab3, processorArchitecture=MSIL">
<HintPath>..\..\Host\GS.Terminal.Identification.EnterpriseHost\packages\GS.Unitive.Framework.1.4.0.2\lib\net40\GS.Unitive.Framework.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\Host\GS.Terminal.Identification.EnterpriseHost\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
<Private>True</Private>
<Private>False</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\Host\GS.Terminal.Identification.EnterpriseHost\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="EmployeeSync.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GS.EnterpriseIdentification.ServiceModel\GS.EnterpriseIdentification.ServiceModel.csproj">
<Project>{d9d132f9-e932-42b3-b6bc-1aa597b79a3a}</Project>
<Name>GS.EnterpriseIdentification.ServiceModel</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("GS.Synchronize.EnterpriseIdentification")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GS.Synchronize.EnterpriseIdentification")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("3cbe05ba-d6b7-49ab-b608-b67a2ac270c9")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="GS.Unitive.Framework" version="1.4.0.2" targetFramework="net452" />
<package id="log4net" version="2.0.8" targetFramework="net452" />
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net452" />
</packages>
\ No newline at end of file
#region << >>
/*----------------------------------------------------------------
* 项目名称 :GS.Terminal.Identification.DbHandler
* 项目描述 :
* 类 名 称 :DbContext
* 类 描 述 :
* 所在的域 :DESKTOP-MNML8TD
* 命名空间 :GS.Terminal.Identification.DbHandler
* 机器名称 :DESKTOP-MNML8TD
* CLR 版本 :4.0.30319.42000
* 作 者 :栾凤杰
* 创建时间 :2018/11/6 14:52:38
* 更新时间 :2018/11/6 14:52:38
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ 青岛通软网络有限公司 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using GS.Terminal.Identification.LocalDbModel;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS.Terminal.Identification.DbHandler
{
public class DbContext<T> where T : class, new()
{
public DbContext()
{
Db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = @"DataSource=LocalDb.sqlite",
DbType = DbType.Sqlite,
InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了
});
//调式代码 用来打印SQL
//Db.Aop.OnLogExecuting = (sql, pars) =>
//{
// Console.WriteLine(sql + "\r\n" +
// Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
// Console.WriteLine();
//};
}
public SqlSugarClient Db;//用来处理事务多表查询和复杂的操作
public SimpleClient<T> CurrentDb { get { return new SimpleClient<T>(Db); } }//用来处理T表的常用操作
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{55C05F45-1762-4EEE-AFD2-417610726759}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GS.Terminal.Identification.DbHandler</RootNamespace>
<AssemblyName>GS.Terminal.Identification.DbHandler</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="SqlSugar, Version=5.0.1.4, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\sqlSugar.5.0.1.4\lib\SqlSugar.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DbContext.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GS.Terminal.Identification.LocalDbModel\GS.Terminal.Identification.LocalDbModel.csproj">
<Project>{d753a763-da74-4697-99f5-8815f850a7d3}</Project>
<Name>GS.Terminal.Identification.LocalDbModel</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("GS.Terminal.Identification.DbHandler")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GS.Terminal.Identification.DbHandler")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("55c05f45-1762-4eee-afd2-417610726759")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="sqlSugar" version="5.0.1.4" targetFramework="net452" />
</packages>
\ No newline at end of file
#region << >>
/*----------------------------------------------------------------
* 项目名称 :GS.Terminal.Identification.Enterprise.Logic
* 项目描述 :
* 类 名 称 :CardHandler
* 类 描 述 :UHF读卡回调处理
* 所在的域 :DESKTOP-MNML8TD
* 命名空间 :GS.Terminal.Identification.Enterprise.Logic
* 机器名称 :DESKTOP-MNML8TD
* CLR 版本 :4.0.30319.42000
* 作 者 :栾凤杰
* 创建时间 :2018/10/24 16:08:22
* 更新时间 :2018/10/24 16:08:22
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ 青岛通软网络有限公司 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using GS.EnterpriseIdentification.ServiceModel;
using GS.Terminal.Common.LocalSetting;
using GS.Terminal.Identification.Enterprise.Logic.Core;
using GS.Unitive.Framework.Core;
using IdentificationViewModels;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace GS.Terminal.Identification.Enterprise.Logic
{
/// <summary>
/// UHF读卡回调处理
/// </summary>
public class CardHandler
{
private static MainPageViewModel ViewModel => Program.locator.MainPage;
/// <summary>
/// UHF读卡回调方法
/// </summary>
/// <param name="cardMsg"></param>
public static void CardCallback(dynamic cardMsg)
{
string cardNum = cardMsg.OperaDeviceData.Message;
#if DEBUG
AddonRuntime.Instance.LogWriter.Error($"DEBUG:Logic插件CardCallback收到卡号{cardNum}", null);
#endif
if (string.IsNullOrEmpty(cardNum)) return;
try
{
ViewModel.IsStandby = false;
MainHandler.CleanViewTimer.Stop();
//拿到卡号
//检索卡号队列, 清除30秒以上的
LogicHandler.CheckQuery();
var visitor = LocalDataCenter.GetVisitInfoByCardNum(cardNum);
//访客打卡
if (visitor != null)
{
LogicHandler.HandlerIdentify(visitor, true);
return;
}
var employee = LocalDataCenter.GetEmplyByCardNum(cardNum);
//员工打卡
if (employee != null)
{
LogicHandler.HandlerIdentify(employee, true);
return;
}
//无效卡
}
catch (AggregateException exs)
{
foreach (var item in exs.InnerExceptions)
{
AddonRuntime.Instance.LogWriter.Error("Logic插件读卡回调出错", item);
}
}
finally
{
MainHandler.CleanViewTimer.Start();
}
}
}
}
#region << >>
/*----------------------------------------------------------------
* 项目名称 :GS.Terminal.Identification.Enterprise.Logic
* 项目描述 :
* 类 名 称 :FaceHandler
* 类 描 述 :
* 所在的域 :DESKTOP-MNML8TD
* 命名空间 :GS.Terminal.Identification.Enterprise.Logic
* 机器名称 :DESKTOP-MNML8TD
* CLR 版本 :4.0.30319.42000
* 作 者 :栾凤杰
* 创建时间 :2018/10/24 20:55:40
* 更新时间 :2018/10/24 20:55:40
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ 青岛通软网络有限公司 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using GS.EnterpriseIdentification.ServiceModel;
using GS.Terminal.Identification.Enterprise.Logic.Core;
using GS.Unitive.Framework.Core;
using IdentificationViewModels;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace GS.Terminal.Identification.Enterprise.Logic
{
internal class FaceHandler
{
private static MainPageViewModel ViewModel => Program.locator.MainPage;
internal static void OnRecognized(string key, float score)
{
try
{
ViewModel.IsStandby = false;
MainHandler.CleanViewTimer.Stop();
if (score < Program.config.LogicConfig.FaceCompareValue) return;
LogicHandler.CheckQuery();
var visitor = LocalDataCenter.GetVisitInfoByFaceData(key);
if (visitor != null)
{
Program.speakService.VoiceBySoundPlayer("识别成功");
LogicHandler.HandlerIdentify(visitor, false, score);
return;
}
var employee = LocalDataCenter.GetEmplyByFaceData(key);
if (employee != null)
{
Program.speakService.VoiceBySoundPlayer("已识别");
LogicHandler.HandlerIdentify(employee, false, score);
return;
}
Program.speakService.VoiceBySoundPlayer("未识别");
}
catch (AggregateException exs)
{
foreach (var item in exs.InnerExceptions)
{
AddonRuntime.Instance.LogWriter.Error("Logic插件面部识别回调出错", item);
}
}
finally
{
MainHandler.CleanViewTimer.Start();
}
}
}
}
#region << >>
/*----------------------------------------------------------------
* 项目名称 :GS.Terminal.Identification.Enterprise.Logic
* 项目描述 :
* 类 名 称 :LogicHandler
* 类 描 述 :
* 所在的域 :DESKTOP-MNML8TD
* 命名空间 :GS.Terminal.Identification.Enterprise.Logic
* 机器名称 :DESKTOP-MNML8TD
* CLR 版本 :4.0.30319.42000
* 作 者 :栾凤杰
* 创建时间 :2018/10/25 9:28:32
* 更新时间 :2018/10/25 9:28:32
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ 青岛通软网络有限公司 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using GalaSoft.MvvmLight.Threading;
using GS.EnterpriseIdentification.ServiceModel;
using GS.Terminal.Identification.DbHandler;
using GS.Terminal.Identification.LocalDbModel;
using GS.Unitive.Framework.Core;
using IdentificationViewModels;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace GS.Terminal.Identification.Enterprise.Logic
{
/// <summary>
/// 服务于CardHandler和FaceHandler的公共方法
/// </summary>
public class LogicHandler
{
private static MainPageViewModel ViewModel => Program.locator.MainPage;
/// <summary>
/// 历史识别队列
/// </summary>
internal static Dictionary<DateTime, Guid> IdentifyQueue { get; set; } = new Dictionary<DateTime, Guid>();
/// <summary>
/// 检查历史队列, 删除存在30秒以上的
/// </summary>
internal static void CheckQuery()
{
var timeOutDict = IdentifyQueue
.Where(ss => DateTime.Now - ss.Key > TimeSpan.FromSeconds(Program.identifyTimeSpan))
.ToDictionary(ss => ss.Key, ss => ss.Value);
foreach (var item in timeOutDict)
{
IdentifyQueue.Remove(item.Key);
}
}
/// <summary>
/// 向历史列表添加数据(只能显示8条)
/// </summary>
/// <param name="human"></param>
internal static void AddToHistory(Human human)
{
DispatcherHelper.RunAsync(() =>
{
ViewModel.VisitHistory.Insert(0, human);
if (ViewModel.VisitHistory.Count > 8)
{
ViewModel.VisitHistory.RemoveAt(8);
}
});
}
/// <summary>
/// 将员工识别记录存入数据库
/// </summary>
/// <param name="human"></param>
/// <param name="employee"></param>
private static void InsertToDb(Human human, Employee employee, double faceResult)
{
var id = Guid.NewGuid();
Task.Run(() =>
{
var db = new DbContext<识别历史>().CurrentDb;
try
{
db.Insert(new 识别历史
{
识别ID = id,
人员姓名 = human.Name,
部门名称 = human.Depart,
是否刷卡识别 = human.IsCard,
识别时间 = DateTime.Now,
人员ID = employee.Id,
部门ID = employee.DepartId,
卡号 = employee.CardNum,
是否访客 = false,
面部识别对比结果 = faceResult,
现场照片 = Program.config.LogicConfig.IsTakePhoto ? Tools.SaveFile(ViewModel.ActiveVideo) : null,
});
}
catch (Exception ex)
{
AddonRuntime.Instance.LogWriter.Error("本地保存历史出错: ", ex);
}
}).ContinueWith((task) =>
{
Program.uploader.Do(id);
});
}
/// <summary>
/// 访客识别历史
/// </summary>
/// <param name="human"></param>
/// <param name="visitInfo"></param>
private static void InsertToDb(Human human, VisitInfo visitInfo, double faceResult)
{
var id = Guid.NewGuid();
Task.Run(() =>
{
var db = new DbContext<识别历史>().CurrentDb;
try
{
db.Insert(new 识别历史
{
识别ID = id,
登记ID = visitInfo.Id,
人员姓名 = human.Name,
部门名称 = human.Depart,
是否刷卡识别 = human.IsCard,
识别时间 = DateTime.Now,
人员ID = visitInfo.VisitEmplyId,
部门ID = visitInfo.VisitDepartId,
卡号 = visitInfo.CardNum,
是否访客 = true,
面部识别对比结果 = faceResult,
现场照片 = Program.config.LogicConfig.IsTakePhoto ? Tools.SaveFile(ViewModel.ActiveVideo) : null,
被访人员姓名 = visitInfo.VisitEmplyName,
被访部门名称 = visitInfo.VisitDepartName
});
}
catch (Exception ex)
{
AddonRuntime.Instance.LogWriter.Error("本地保存历史出错: ", ex);
}
}).ContinueWith((task) =>
{
Program.uploader.Do(id);
});
}
/// <summary>
/// 生成员工的ViewModel
/// </summary>
/// <param name="employee"></param>
/// <param name="isCard"></param>
/// <param name="isVisitor"></param>
/// <returns></returns>
internal static Human GenHuman(Employee employee, bool isCard, bool isVisitor = false)
{
return new Human
{
Depart = employee.DepartName,
Name = employee.Name,
IsCard = isCard,
IsVisitor = isVisitor,
Time = DateTime.Now.ToString("HH:mm:ss"),
HumanPhoto = string.IsNullOrWhiteSpace(employee.PhotoPath) ? null : Path.Combine(Program.webPath, employee.PhotoPath),
};
}
/// <summary>
/// 生成访客的ViewModel
/// </summary>
/// <param name="visit"></param>
/// <param name="isCard"></param>
/// <param name="isVisitor"></param>
/// <returns></returns>
internal static Human GenHuman(VisitInfo visit, bool isCard, bool isVisitor = true)
{
return new Human
{
Depart = visit.VisitDepartName,
Name = visit.VisitorName,
IsCard = isCard,
IsVisitor = isVisitor,
Time = DateTime.Now.ToString("HH:mm:ss"),
HumanPhoto = string.IsNullOrWhiteSpace(visit.CertPhoto) ? null : Path.Combine(Program.webPath, visit.CertPhoto),
};
}
/// <summary>
/// 访客识别后处理
/// </summary>
/// <param name="identifyVisit"></param>
/// <param name="isCard"></param>
internal static void HandlerIdentify(VisitInfo identifyVisit, bool isCard, double faceResult = 0)
{
Guid activateVisit = IdentifyQueue.FirstOrDefault(ss => ss.Value == identifyVisit.Id).Value;
//访客存在队列中
if (activateVisit != Guid.Empty)
{
return;
}
//访客不存在队列中
else
{
//访客加入队列
IdentifyQueue.Add(DateTime.Now, identifyVisit.Id);
//处理本次识别
var human = GenHuman(identifyVisit, isCard);
#if DEBUG
///测试人脸阈值
human.Name += faceResult.ToString("f2");
///测试人脸阈值
#endif
ViewModel.ActiveHuman = human;
AddToHistory(human);
InsertToDb(human, identifyVisit, faceResult);
}
}
/// <summary>
/// 员工识别后处理
/// </summary>
/// <param name="identifyEmployee"></param>
/// <param name="isCard"></param>
internal static void HandlerIdentify(Employee identifyEmployee, bool isCard, double faceResult = 0)
{
var activateEmply = IdentifyQueue.FirstOrDefault(ss => ss.Value == identifyEmployee.Id).Value;
//员工存在队列中
if (activateEmply != Guid.Empty)
{
return;
}
//员工不存在队列中
else
{
//员工加入队列
IdentifyQueue.Add(DateTime.Now, identifyEmployee.Id);
//处理本次识别
var human = GenHuman(identifyEmployee, isCard);
#if DEBUG
//测试人脸阈值
human.Name += faceResult.ToString("f2");
///测试人脸阈值
#endif
ViewModel.ActiveHuman = human;
AddToHistory(human);
InsertToDb(human, identifyEmployee, faceResult);
}
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns="urn:Chinags-Configuration" AddonName="GS.Terminal.Identification.Enterprise.Logic">
<Dictionaries>
<Dict Caption="业务逻辑基本配置" Name="LogicConfig">
<Key Caption="同一个人面部识别间隔" Choice="" Name="IdentifyTimeSpan" Value="15"/>
<Key Caption="面部识别阈值" Choice="" Name="FaceCompareValue" Value="0.8"/>
<Key Caption="是否拍照" Choice="" Name="IsTakePhoto" Value="true"/>
<Key Caption="自动待机延时(秒)" Choice="" Name="CleanViewDelay" Value="15"/>
</Dict>
</Dictionaries>
<Structures>
<Structure Name="DataSyncConfig" Caption="同步管理">
<Declare>
<Property Name="DisPlayName" Caption="同步标题"></Property>
<Property Name="Key" Caption="同步标识"></Property>
<Property Name="IntervalSec" Caption="同步间隔(秒)"></Property>
<Property Name="ServiceUrl" Caption="同步服务地址"></Property>
<Property Name="Enable" Caption="是否开启"></Property>
</Declare>
<Datas>
<Data DisPlayName="员工信息同步" Key="Employee" IntervalSec="100" ServiceUrl="/Services/EnterpriseIdentification/GetAllEmployee/json" Enable="true"/>
<Data DisPlayName="员工面部特征同步" Key="EmployeeFaceData" IntervalSec="30" ServiceUrl="/Services/EnterpriseIdentification/GetAllEmployeeFaceData/json" Enable="true"/>
<Data DisPlayName="来访记录同步" Key="VisitInfo" IntervalSec="30" ServiceUrl="/Services/EnterpriseIdentification/GetVisitor/json" Enable="true"/>
</Datas>
</Structure>
<Structure Name="ServiceConfig" Caption="服务配置">
<Declare>
<Property Name="ServiceKey" Caption="服务标识"/>
<Property Name="ServiceName" Caption="批量保存识别记录"/>
<Property Name="ServiceUrl" Caption="服务地址"/>
</Declare>
<Datas>
<Data ServiceKey="SaveIdentityBatch" ServiceName="批量上传员工识别记录" ServiceUrl="/Services/EnterpriseIdentification/SaveIdentityInfoBatch/json"/>
<Data ServiceKey="SaveVisitorIdentifyBatch" ServiceName="批量上传访客识别记录" ServiceUrl="/Services/EnterpriseIdentification/SaveVisitorIdentifyBatch/json"/>
</Datas>
</Structure>
</Structures>
</Settings>
\ No newline at end of file
using GS.Terminal.Common.LocalSetting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS.Terminal.Identification.Enterprise.Logic.Config
{
public class ServiceListing
{
private ServiceListingConfig _ServiceListingConfig;
private string _webpath;
public ServiceListing(string webpath)
{
_ServiceListingConfig =
LocalSettingLoader.Load<ServiceListingConfig>(Program.addonContext);
_webpath = webpath;
}
private Uri _SaveIdentityBatch;
/// <summary>
/// 批量上传识别记录
/// </summary>
public Uri SaveIdentityBatch
{
get
{
if (_SaveIdentityBatch == null)
{
_SaveIdentityBatch = getConfigUrlByKey("SaveIdentityBatch", "/Services/EnterpriseIdentification/SaveIdentityInfoBatch/json");
}
return _SaveIdentityBatch;
}
}
private Uri _SaveVisitorIdentifyBatch;
public Uri SaveVisitorIdentifyBatch
{
get
{
if (_SaveVisitorIdentifyBatch == null)
{
_SaveVisitorIdentifyBatch = getConfigUrlByKey("SaveVisitorIdentifyBatch", "/Services/Visitor/SaveVisitorIdentifyBatch");
}
return _SaveVisitorIdentifyBatch;
}
}
private Uri getConfigUrlByKey(string key, string defaultUrl)
{
if (_ServiceListingConfig != null && _ServiceListingConfig.Datas != null)
{
var config = _ServiceListingConfig.Datas.FirstOrDefault(ss => ss.ServiceKey == key);
if (config != null && !string.IsNullOrEmpty(config.ServiceUrl))
{
var url = $"{_webpath}/{config.ServiceUrl}";
if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
return new Uri(url, UriKind.Absolute);
}
}
}
return new Uri($"{_webpath}/{defaultUrl}", UriKind.Absolute);
}
}
public class ServiceListingConfig : IStructureSetting<ServiceListingConfigItem>
{
public List<ServiceListingConfigItem> Datas { get; set; }
public string StructureName => "ServiceConfig";
}
public class ServiceListingConfigItem : IStructureSettingItem
{
public string ServiceKey { get; set; }
public string ServiceName { get; set; }
public string ServiceUrl { get; set; }
}
}
#region << >>
/*----------------------------------------------------------------
* 项目名称 :GS.Terminal.Identification.Enterprise.Logic.Config
* 项目描述 :
* 类 名 称 :TerminalSetting
* 类 描 述 :
* 所在的域 :DESKTOP-MNML8TD
* 命名空间 :GS.Terminal.Identification.Enterprise.Logic.Config
* 机器名称 :DESKTOP-MNML8TD
* CLR 版本 :4.0.30319.42000
* 作 者 :栾凤杰
* 创建时间 :2018/11/6 12:08:00
* 更新时间 :2018/11/6 12:08:00
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ 青岛通软网络有限公司 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using GS.Terminal.Common.LocalSetting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS.Terminal.Identification.Enterprise.Logic.Config
{
public class TerminalSetting
{
public TerminalSetting()
{
var properties = GetType().GetProperties();
foreach (var item in properties.Where(ss => !(ss.PropertyType.GetInterface(nameof(ISetting)) is null)))
{
item.SetValue(this, LocalSettingLoader.Load(item.PropertyType, Program.addonContext));
}
}
/// <summary>
/// 宿主配置
/// </summary>
public GlobalAppConfig GlobalConfig { get; set; }
/// <summary>
/// Logic插件配置
/// </summary>
public LogicConfig LogicConfig { get; set; }
/// <summary>
/// 同步器配置
/// </summary>
public DataSyncConfig DataSyncConfig { get; set; }
}
public class GlobalAppConfig : IGlobalSetting
{
/// <summary>
/// 升级检测地址
/// </summary>
public string UpdateUrl { get; set; }
/// <summary>
/// 服务器IP
/// </summary>
public string ServerIP { get; set; }
/// <summary>
/// 设备编号
/// </summary>
public string tCode { get; set; }
/// <summary>
/// Web服务地址
/// </summary>
public string WebPath { get; set; }
}
public class LogicConfig : IDictSetting
{
public string DictName => nameof(LogicConfig);
/// <summary>
/// 人脸识别间隔
/// </summary>
public int IdentifyTimeSpan { get; set; }
/// <summary>
/// 面部识别阈值
/// </summary>
public double FaceCompareValue { get; set; }
/// <summary>
/// 是否拍照
/// </summary>
public bool IsTakePhoto { get; set; }
/// <summary>
/// 自动待机延时(秒)
/// </summary>
public int CleanViewDelay { get; set; }
}
public class DataSyncConfig : IStructureSetting<DataSyncConfigItem>
{
public List<DataSyncConfigItem> Datas { get; set; }
public string StructureName => nameof(DataSyncConfig);
}
public class DataSyncConfigItem : IStructureSettingItem
{
public string DisPlayName { get; set; }
public string Key { get; set; }
public int IntervalSec { get; set; }
public string ServiceUrl { get; set; }
public bool Enable { get; set; }
}
}
using GS.EnterpriseIdentification.ServiceModel;
using GS.Terminal.Common;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS.Terminal.Identification.Enterprise.Logic.Core
{
public class LocalDataCenter
{
private static List<Employee> Employee = new List<Employee>();
private static List<VisitInfo> VisitInfo = new List<VisitInfo>();
private static List<FaceEntity> AllFace = new List<FaceEntity>();
internal static void InitDataSync()
{
#region 人员信息
{
var Key = "Employee";
var config = Program.config.DataSyncConfig.Datas.FirstOrDefault(ss => ss.Key.Equals(Key, StringComparison.CurrentCultureIgnoreCase));
if (config != null && config.Enable)
{
var employeeSync =
Program.syncService.Regist<Employee>(Key,
$"{Program.config.GlobalConfig.WebPath}/{config.ServiceUrl}",
config.IntervalSec);
employeeSync.OnDataInit += EmployeeSync_OnDataInit;
employeeSync.OnDataChanged += EmployeeSync_OnDataChanged;
}
}
#endregion
#region 员工面部特征
{
var Key = "EmployeeFaceData";
var config = Program.config.DataSyncConfig.Datas.FirstOrDefault(ss => ss.Key.Equals(Key, StringComparison.CurrentCultureIgnoreCase));
if (config != null && config.Enable)
{
var employeeFaceDataSync =
Program.syncService.Regist<EmployeeFaceData>(Key,
$"{Program.config.GlobalConfig.WebPath}/{config.ServiceUrl}",
config.IntervalSec);
employeeFaceDataSync.OnDataInit += EmployeeFaceDataSync_OnDataInit;
employeeFaceDataSync.OnDataChanged += EmployeeFaceDataSync_OnDataChanged;
}
}
#endregion
#region 来访记录同步
{
var Key = "VisitInfo";
var config = Program.config.DataSyncConfig.Datas.FirstOrDefault(ss => ss.Key.Equals(Key, StringComparison.CurrentCultureIgnoreCase));
if (config != null && config.Enable)
{
var visitInfoSync =
Program.syncService.Regist<VisitInfo>(Key,
$"{Program.config.GlobalConfig.WebPath}/{config.ServiceUrl}",
config.IntervalSec);
visitInfoSync.OnDataInit += VisitInfoSync_OnDataInit;
visitInfoSync.OnDataChanged += VisitInfoSync_OnDataChanged;
}
}
#endregion
}
#region 来访记录同步
private static void VisitInfoSync_OnDataChanged(object sender, List<VisitInfo> newData)
{
VisitInfo = newData;
SetVisitFaceList(newData);
}
private static void VisitInfoSync_OnDataInit(object sender, List<VisitInfo> data)
{
VisitInfo = data;
SetVisitFaceList(data);
}
#endregion
#region 员工面部特征
private static void EmployeeFaceDataSync_OnDataChanged(object sender, List<EmployeeFaceData> newData)
{
SetEmplyFaceList(newData);
}
private static void EmployeeFaceDataSync_OnDataInit(object sender, List<EmployeeFaceData> data)
{
SetEmplyFaceList(data);
}
#endregion
#region 人员信息
private static void EmployeeSync_OnDataChanged(object sender, List<Employee> newData)
{
Employee = newData ?? new List<Employee>();
}
private static void EmployeeSync_OnDataInit(object sender, List<Employee> data)
{
Employee = data ?? new List<Employee>();
}
#endregion
/// <summary>
/// 将VisitFaceList以VisitInfo填充
/// </summary>
/// <param name="visits"></param>
internal static void SetVisitFaceList(List<VisitInfo> visits)
{
var t = new List<FaceEntity>();
foreach (var item in visits)
{
foreach (var face in item.VisitorFaceData)
{
t.Add(new FaceEntity { Id = item.Id, PersonType = 'v', FaceData = face });
}
}
mergeFace(t);
}
internal static void SetEmplyFaceList(List<EmployeeFaceData> facedata)
{
var t = new List<FaceEntity>();
foreach (var item in facedata)
t.Add(new FaceEntity { Id = item.UserId, PersonType = 'e', FaceData = item.FaceData });
mergeFace(t);
}
private static void mergeFace(List<FaceEntity> newdata)
{
if (newdata != null && newdata.Count > 0)
lock (AllFace)
{
var vlist = AllFace.Where(ss => ss.PersonType == newdata.FirstOrDefault().PersonType).ToList();
vlist.ForEach(item => AllFace.Remove(item));
AllFace.AddRange(newdata);
Face.FaceRecognizationService
.RegistArcFace2RecognizedEvent(
AllFace.Select(ss => new KeyValuePair<string, byte[]>(ss.Key, ss.FaceData)).ToList(),
null);
}
}
/// <summary>
/// 根据卡号找人员
/// </summary>
/// <param name="cardNum"></param>
/// <returns></returns>
internal static Employee GetEmplyByCardNum(string cardNum)
{
return Employee.FirstOrDefault(ss => ss.CardNum.Equals(cardNum, StringComparison.CurrentCultureIgnoreCase));
}
/// <summary>
/// 根据面部特征找访客
/// </summary>
/// <param name="facedata"></param>
/// <returns></returns>
internal static VisitInfo GetVisitInfoByFaceData(string key)
{
var face =
AllFace.Where(ss => ss.PersonType == 'v').FirstOrDefault(ss => ss.Key == key);
if (face == null) return null;
var visitor = VisitInfo.FirstOrDefault(ss => ss.Id == face.Id);
return visitor;
}
/// <summary>
/// 根据卡号找访客
/// </summary>
/// <param name="cardNum"></param>
/// <returns></returns>
internal static VisitInfo GetVisitInfoByCardNum(string cardNum)
{
return VisitInfo.Where(ss => ss.CardNum == cardNum).FirstOrDefault();
}
/// <summary>
/// 根据面部特征查找员工
/// </summary>
/// <param name="facedata"></param>
/// <returns></returns>
internal static Employee GetEmplyByFaceData(string key)
{
var face =
AllFace.Where(ss => ss.PersonType == 'e').FirstOrDefault(ss => ss.Key == key);
if (face == null) return null;
var emply = Employee.FirstOrDefault(ss => ss.Id == face.Id);
return emply;
}
}
public class FaceEntity
{
/// <summary>
/// v:访客 e:员工
/// </summary>
public char PersonType { get; set; }
public Guid Id { get; set; }
public byte[] FaceData { get; set; }
public string Key
{
get
{
return $"{PersonType}.{Id.ToString("N")}";
}
}
}
}
using GS.Terminal.Identification.LocalDbModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
using GS.Terminal.Common.WebService;
using GS.Unitive.Framework.Core;
using System.IO;
using GS.Terminal.Identification.DbHandler;
namespace GS.Terminal.Identification.Enterprise.Logic
{
public class Uploader
{
public string tCode { get; private set; }
/// <summary>
/// 上传失败重试间隔(补传间隔)
/// </summary>
public int RetrySpacing { get; set; } = 60 * 1000;
/// <summary>
/// 队列最大数量
/// </summary>
public int QueueMax { get; set; } = 10;
/// <summary>
/// 上传队列
/// </summary>
private List<识别历史> UploadQueue = new List<识别历史>();
/// <summary>
/// 上传计时器
/// </summary>
Timer timer = new Timer(10 * 1000);
/// <summary>
/// 数据上传完毕
/// </summary>
//public event Action<Guid> DataUploaded;
public Uploader(string tcode)
{
tCode = tcode;
timer.Elapsed += Timer_Elapsed;
Task.Run(async () =>
{
while (true)
{
var recordDatas = new DbContext<识别历史>().CurrentDb.GetList(ss => ss.识别时间 >= DateTime.Now.AddDays(-3).Date && !ss.是否已上传);
foreach (var item in recordDatas)
{
PostDataBatch(item);
}
await Task.Delay(RetrySpacing);
}
});
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
//上传
if (UploadQueue.Count <= 0) return;
#region 访客
var visitData = UploadQueue.Where(ss => ss.是否访客).Select(ss => new
{
localid = ss.识别ID,
VisitInfoId = ss.登记ID,
CardTime = ss.识别时间,
SitePhoto = Tools.ReadFile(ss.现场照片),
IdentifyMethod = ss.是否刷卡识别 ? 0 : 1,
FaceResult = ss.面部识别对比结果,
Tag = 2,
});
if (visitData != null)
{
var visitBody = new
{
tCode = tCode,
datas = visitData
};
var visitResult = new WebServiceCenter(AddonRuntime.Instance.LogWriter,
"",
"")
.Post<WebServiceResult<List<ResultPost>>>(Program.serviceListing.SaveVisitorIdentifyBatch, visitBody);
if (!visitResult.HasError())
{
List<识别历史> updateList = new List<识别历史>(visitResult.result.Count);
foreach (var res in visitResult.result)
{
var data = new DbContext<识别历史>().Db.Queryable<识别历史>().Single(ss => ss.识别ID == res.localid);
if (data != null)
{
data.是否已上传 = true;
data.远程ID = res.remoteid;
updateList.Add(data);
}
}
if (updateList.Count > 0)
{
new DbContext<识别历史>().CurrentDb.UpdateRange(updateList.ToArray());
}
}
}
#endregion
#region 员工
var emplyData = UploadQueue.Where(ss => !ss.是否访客).Select(ss => new
{
localid = ss.识别ID,
EmplyId = ss.人员ID,
CardNum = ss.卡号,
CardTime = ss.识别时间,
SitePhoto = Tools.ReadFile(ss.现场照片),
Tag = 2,
IdentifyMethod = ss.是否刷卡识别 ? 0 : 1,
FaceResult = ss.面部识别对比结果
});
if (emplyData != null)
{
var emplyBody = new
{
tCode = tCode,
datas = emplyData
};
var emplyResult = new WebServiceCenter(AddonRuntime.Instance.LogWriter,
"",
"")
.Post<WebServiceResult<List<ResultPost>>>(Program.serviceListing.SaveIdentityBatch, emplyBody);
if (!emplyResult.HasError())
{
List<识别历史> updateList = new List<识别历史>(emplyResult.result.Count);
foreach (var res in emplyResult.result)
{
var data = new DbContext<识别历史>().Db.Queryable<识别历史>().Single(ss => ss.识别ID == res.localid);
if (data != null)
{
data.是否已上传 = true;
data.远程ID = res.remoteid;
updateList.Add(data);
}
}
if (updateList.Count > 0)
{
new DbContext<识别历史>().CurrentDb.UpdateRange(updateList.ToArray());
}
}
}
#endregion
UploadQueue.Clear();
}
private void Upload(Guid id)
{
Task.Run(() =>
{
try
{
lock (UploadQueue)
{
var recordData = new DbContext<识别历史>().CurrentDb.GetSingle(ss => ss.识别ID == id && !ss.是否已上传);
if (recordData != null)
PostDataBatch(recordData);
}
}
catch (Exception ee)
{
AddonRuntime.Instance.LogWriter.Error("上传识别记录发生异常", ee);
}
});
}
/// <summary>
/// 单条记录加入队列
/// </summary>
/// <param name="record"></param>
private void PostDataBatch(识别历史 record)
{
//如果此记录已存在, 直接返回
if (UploadQueue.Count(ss => ss.识别ID == record.识别ID) > 0) return;
UploadQueue.Add(record);
if (UploadQueue.Count >= QueueMax)
{
Timer_Elapsed(null, null);
}
TimerRestart();
}
private void TimerRestart()
{
timer.Stop();
timer.Start();
}
public void Do(Guid id)
{
Upload(id);
}
}
public class ResultPost
{
public Guid localid { get; set; }
public int remoteid { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS.Terminal.Identification.Enterprise.Logic.Face
{
internal class FaceRecognizationService
{
private static dynamic faceService = null;
private static void getService()
{
if (faceService == null)
faceService = Program.addonContext.GetFirstOrDefaultService("GS.Terminal.FaceRecognization",
"GS.Terminal.FaceRecognization.Service");
}
/// <summary>
/// 注册面部识别2.0回调
/// </summary>
/// <param name="faceData"></param>
/// <param name="callback"></param>
public static void RegistArcFace2RecognizedEvent(List<KeyValuePair<string, byte[]>> faceData,
Action<string, float> callback)
{
getService();
faceService.RegistArcFace2RecognizedEvent(faceData, callback);
}
/// <summary>
/// 注销面部识别事件
/// </summary>
/// <param name="callback"></param>
public static void UnRegistArcFace2RecognizedEvent(Action<string, float> callback)
{
getService();
faceService.UnRegistArcFace2RecognizedEvent(callback);
}
/// <summary>
/// 注册摄像头事件
/// </summary>
/// <param name="callback"></param>
public static void RegistArcFace2RecognizedVideoOutPutWhitFaceInfoEvent(Action<Bitmap> callback)
{
getService();
faceService.RegistArcFace2RecognizedVideoOutPutWhitFaceInfoEvent(callback);
}
public static void RegistOutPutImageEvent(Action<Bitmap> callback)
{
getService();
faceService.RegistOutPutImageEvent(callback);
}
public static void RegistArcFace2RecognizedVideoOutPutBufferWhitFaceInfoEvent(Action<byte[]> callback)
{
getService();
faceService.RegistArcFace2RecognizedVideoOutPutBufferWhitFaceInfoEvent(callback);
}
/// <summary>
/// 注销摄像头事件
/// </summary>
/// <param name="callback"></param>
public static void UnRegistArcFace2RecognizedVideoOutPutWhitFaceInfoEvent(Action<Bitmap> callback)
{
getService();
faceService.UnRegistArcFace2RecognizedVideoOutPutWhitFaceInfoEvent(callback);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8ADCB6FE-2682-4320-8524-05F0787E752E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GS.Terminal.Identification.Enterprise.Logic</RootNamespace>
<AssemblyName>GS.Terminal.Identification.Enterprise.Logic</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Host\GS.Terminal.Identification.EnterpriseHost\GS.Terminal.Identification.EnterpriseHost\Addons\GS.Terminal.Identification.Enterprise.Logic\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\Host\GS.Terminal.Identification.EnterpriseHost\GS.Terminal.Identification.EnterpriseHost\Addons\GS.Terminal.Identification.Enterprise.Logic\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="CommonServiceLocator, Version=2.0.2.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\CommonServiceLocator.2.0.2\lib\net45\CommonServiceLocator.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="GalaSoft.MvvmLight, Version=5.4.1.0, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.4.1.1\lib\net45\GalaSoft.MvvmLight.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="GalaSoft.MvvmLight.Extras, Version=5.4.1.0, Culture=neutral, PublicKeyToken=669f0b5e8f868abf, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.4.1.1\lib\net45\GalaSoft.MvvmLight.Extras.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="GalaSoft.MvvmLight.Platform, Version=5.4.1.0, Culture=neutral, PublicKeyToken=5f873c45e98af8a1, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.4.1.1\lib\net45\GalaSoft.MvvmLight.Platform.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="GS.Remote.Synchronize.EasyTask">
<HintPath>..\..\release\Addons\GS.Remote.Synchronize\GS.Remote.Synchronize.EasyTask.dll</HintPath>
</Reference>
<Reference Include="GS.Terminal.Common">
<HintPath>..\..\release\Tools\GS.Terminal.Common.dll</HintPath>
</Reference>
<Reference Include="GS.Terminal.LogicShell.Interface">
<HintPath>..\..\release\Addons\GS.Terminal.LogicShell\GS.Terminal.LogicShell.Interface.dll</HintPath>
</Reference>
<Reference Include="GS.Unitive.Framework, Version=1.4.0.2, Culture=neutral, PublicKeyToken=769358b197600ab3, processorArchitecture=MSIL">
<HintPath>..\packages\GS.Unitive.Framework.1.4.0.2\lib\net40\GS.Unitive.Framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="SqlSugar, Version=5.0.1.4, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\sqlSugar.5.0.1.4\lib\SqlSugar.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.4.1.1\lib\net45\System.Windows.Interactivity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="CallbackHandler\CardHandler.cs" />
<Compile Include="CallbackHandler\FaceHandler.cs" />
<Compile Include="CallbackHandler\LogicHandler.cs" />
<Compile Include="Config\ServiceListing.cs" />
<Compile Include="Config\TerminalSetting.cs" />
<Compile Include="Core\LocalDataCenter.cs" />
<Compile Include="Core\Uploader.cs" />
<Compile Include="Face\FaceRecognizationService.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Service.cs" />
<Compile Include="Tools.cs" />
<Compile Include="ViewModelHandler\HeadHandler.cs" />
<Compile Include="ViewModelHandler\MainHandler.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Config.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
</None>
<None Include="Mapper.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GS.Terminal.Identification.DbHandler\GS.Terminal.Identification.DbHandler.csproj">
<Project>{55C05F45-1762-4EEE-AFD2-417610726759}</Project>
<Name>GS.Terminal.Identification.DbHandler</Name>
</ProjectReference>
<ProjectReference Include="..\GS.Terminal.Identification.LocalDbModel\GS.Terminal.Identification.LocalDbModel.csproj">
<Project>{d753a763-da74-4697-99f5-8815f850a7d3}</Project>
<Name>GS.Terminal.Identification.LocalDbModel</Name>
</ProjectReference>
<ProjectReference Include="..\GS.EnterpriseIdentification.ServiceModel\GS.EnterpriseIdentification.ServiceModel.csproj">
<Project>{d9d132f9-e932-42b3-b6bc-1aa597b79a3a}</Project>
<Name>GS.EnterpriseIdentification.ServiceModel</Name>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\IdentificationViewModels\IdentificationViewModels.csproj">
<Project>{a5c283a6-6d6e-4e2d-b186-02527e43053f}</Project>
<Name>IdentificationViewModels</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
</Target>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<Extensibility xmlns="urn:Chinags-Extensibility-1.0" Name="身份识别逻辑插件" SymbolicName="GS.Terminal.Identification.Enterprise.Logic" Version="1.0.0.0" StartLevel="40">
<License>ES4v4vg0AoI8kNm/irYbG5yCzs1mLaV2RpJtuGzwW7ma//MZXsU/GQr6e4znYWM1Cmvm4000b2GOJjpvJEw4n2ZR1fwplrz0onNMloqo/9iA5lb3wDwLVbpj/hT2nJlmwqnHxliRI7JMrbRkXm7ytHE55oNjg8kiUOoY6tFO9+0=</License>
<Activator Type="GS.Terminal.Identification.Enterprise.Logic.Program"/>
<Runtime>
<Assembly Path="GS.Terminal.Identification.Enterprise.Logic.dll" Share="true"/>
</Runtime>
<ObjectSpaces>
<Channel ConnectionName="sqlite" ModelAssembly="" Name="sqlChannel"/>
</ObjectSpaces>
<Services>
<Service TypeAndName="GS.Terminal.Identification.Enterprise.Logic.Service" Caption="跑马灯"/>
</Services>
</Extensibility>
using GalaSoft.MvvmLight.Ioc;
using GS.EnterpriseIdentification.ServiceModel;
using GS.Remote.Synchronize.EasyTask;
using GS.Terminal.Common;
using GS.Terminal.Identification.DbHandler;
using GS.Terminal.Identification.Enterprise.Logic.Core;
using GS.Terminal.Identification.LocalDbModel;
using GS.Terminal.LogicShell.Interface;
using GS.Unitive.Framework.Core;
using IdentificationViewModels;
using Microsoft.VisualBasic.ApplicationServices;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace GS.Terminal.Identification.Enterprise.Logic
{
public class Program : IAddonActivator
{
internal static IAddonContext addonContext; // 插件上下文
internal static IViewHelperService logicShellService; // LogicShell服务
internal static dynamic deviceManagerService; // DeviceManager服务
internal static dynamic speakService; //语音播放插件
internal static Locator locator; // ViewModel获取
//internal static FaceRecognizationService faceRecognizationService; // 人脸识别服务 //改用2.0接口
internal static dynamic uIService; // MainShell服务
internal static double faceCompareValue = 0.6; // 人脸识别值
internal static double identifyTimeSpan = 30; // 识别间隔
internal static string webPath; // 照片Web地址
internal static Config.TerminalSetting config; // 配置
internal static Config.ServiceListing serviceListing; // 服务清单配置
internal static Uploader uploader; // 数据上传
internal static IEasyTaskService syncService; // 数据同步插件服务
public void Start(IAddonContext Context)
{
AddonRuntime.Instance.onRuntimeCompleted += Instance_onRuntimeCompleted;
addonContext = Context;
LoadConfig();
InitSqliteDb();
uploader = new Uploader(config.GlobalConfig.tCode);
}
/// <summary>
/// 初始化本地Sqlite数据库
/// </summary>
private void InitSqliteDb()
{
FileInfo fileInfo = new FileInfo(@"LocalDb.sqlite");
if (!fileInfo.Exists || fileInfo.Length <= 0)
{
using (FileStream fs = new FileStream(@"LocalDb.sqlite", FileMode.Create)) { }
//根据实体初始化表, 注意:Sqlite不支持字段改名, 所以Sqlite执行后会将原表备份并创建新表, 原表的数据不会被带到新表
new DbContext<识别历史>().Db.CodeFirst.InitTables(typeof(识别历史));
}
}
private static void LoadConfig()
{
config = new Config.TerminalSetting();
webPath = config.GlobalConfig.WebPath;
identifyTimeSpan = config.LogicConfig.IdentifyTimeSpan;
faceCompareValue = config.LogicConfig.FaceCompareValue;
serviceListing = new Config.ServiceListing(config.GlobalConfig.WebPath);
}
private void Instance_onRuntimeCompleted(object sender)
{
GetAndRegistServices();
RegistViewModel();
MainHandler.ViewModel.tCode = config.GlobalConfig.tCode;
MainHandler.ViewModel.VersionString = new ApplicationBase().Info.Version.ToString();
logicShellService.ShowView(SimpleIoc.Default.GetInstance<Locator>().MainPage, args =>
{
//注册数据同步监听
LocalDataCenter.InitDataSync();
});
}
/// <summary>
/// 注册ViewModel
/// </summary>
private void RegistViewModel()
{
SimpleIoc.Default.Register<Locator>();
locator = SimpleIoc.Default.GetInstance<Locator>();
MainHandler.Regist();
HeadHandler.Regist();
}
/// <summary>
/// 获取并注册服务
/// </summary>
private void GetAndRegistServices()
{
//注册LogicShell插件
logicShellService = addonContext.GetFirstOrDefaultService<IViewHelperService>("GS.Terminal.LogicShell");
if (null == logicShellService)
{
addonContext.Logger.Error("GS.Terminal.LogicShell 插件服务未找到", null);
}
//注册DeviceManager的RegistCardCallback
deviceManagerService = addonContext.GetFirstOrDefaultService("GS.Terminal.DeviceManager", "GS.Terminal.DeviceManager.Service.DeviceCallControl");
if (null == deviceManagerService)
{
addonContext.Logger.Error("GS.Terminal.DeviceManager 插件 GS.Terminal.DeviceManager.Service.DeviceCallControl 服务未找到", null);
}
//注册MainShell插件
uIService = addonContext.GetFirstOrDefaultService("GS.Terminal.MainShell", "GS.Terminal.MainShell.Services.UIService");
if (null == uIService)
{
addonContext.Logger.Error("GS.Terminal.MainShell 的 GS.Terminal.MainShell.Services.UIService 服务未找到", null);
}
//语音
speakService = addonContext.GetFirstOrDefaultService("GS.Terminal.Speak", "GS.Terminal.Speak.Service");
//数据同步插件服务
syncService = addonContext.GetFirstOrDefaultService<IEasyTaskService>("GS.Remote.Synchronize");
if (syncService == null)
{
addonContext.Logger.Error("数据同步插件的EasyTaskService服务没有找到", null);
}
}
public void Stop(IAddonContext Context)
{
addonContext = null;
}
/// <summary>
/// 显示提示信息
/// </summary>
/// <param name="Msg">信息</param>
/// <param name="AutoCloseSeconds">显示时长(秒)</param>
public static void ShowPrompt(string Msg)
{
uIService.ShowPrompt(Msg);
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("GS.Terminal.Identification.Enterprise.Logic")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GS.Terminal.Identification.Enterprise.Logic")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("8adcb6fe-2682-4320-8524-05f0787e752e")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using GS.Unitive.Framework.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS.Terminal.Identification.Enterprise.Logic
{
public class Service
{
public Service()
{
Console.WriteLine("ctor in");
}
public void UpdateMedia(string msg)
{
MainHandler.ViewModel.Footer = msg;
}
}
}
#region << >>
/*----------------------------------------------------------------
* 项目名称 :GS.Terminal.Identification.Enterprise.Logic
* 项目描述 :
* 类 名 称 :Tools
* 类 描 述 :
* 所在的域 :DESKTOP-MNML8TD
* 命名空间 :GS.Terminal.Identification.Enterprise.Logic
* 机器名称 :DESKTOP-MNML8TD
* CLR 版本 :4.0.30319.42000
* 作 者 :栾凤杰
* 创建时间 :2018/11/27 10:51:27
* 更新时间 :2018/11/27 10:51:27
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ 青岛通软网络有限公司 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace GS.Terminal.Identification.Enterprise.Logic
{
public static class Tools
{
internal static string SaveFile(ImageSource imageSource)
{
try
{
string fileName = Guid.NewGuid().ToString() + ".jpg";
string filePath = Path.Combine("Photos", DateTime.Now.ToString("yyyyMMdd"));
string localPath = Path.Combine(Environment.CurrentDirectory, filePath);
if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)imageSource));
encoder.Save(ms);
Bitmap image = new Bitmap(ms);
ms.Close();
double width = image.Width / 2, height = image.Height / 2;
var newImg = new Bitmap((int)width, (int)height);
Graphics graphics = Graphics.FromImage(newImg);
graphics.DrawImage(image, new Rectangle(0, 0, (int)width, (int)height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);
ImageFormat tFormat = newImg.RawFormat;
EncoderParameters ep = new EncoderParameters();
long[] qy = new long[1];
qy[0] = 20;//设置压缩的比例1-100
EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
ep.Param[0] = eParam;
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICIinfo = null;
for (int x = 0; x < arrayICI.Length; x++)
{
if (arrayICI[x].FormatDescription.Equals("JPEG"))
{
jpegICIinfo = arrayICI[x];
break;
}
}
if (jpegICIinfo != null)
{
newImg.Save(Path.Combine(localPath, fileName), jpegICIinfo, ep);
return Path.Combine(filePath, fileName);
}
else
{
newImg.Save(Path.Combine(localPath, fileName), tFormat);
return Path.Combine(filePath, fileName);
}
}
catch (Exception)
{
return null;
}
}
internal static string SaveFile(byte[] value)
{
try
{
string fileName = Guid.NewGuid().ToString() + ".jpg";
string filePath = Path.Combine("Photos", DateTime.Now.ToString("yyyyMMdd"));
string localPath = Path.Combine(Environment.CurrentDirectory, filePath);
if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath);
using (FileStream file = new FileStream(Path.Combine(localPath, fileName), FileMode.Create))
{
file.Write(value, 0, value.Length);
}
return Path.Combine(filePath, fileName);
}
catch (Exception)
{
return string.Empty;
}
}
internal static byte[] ReadFile(string filePath)
{
try
{
using (FileStream fs = new FileStream(Path.Combine(Environment.CurrentDirectory, filePath), FileMode.Open))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
return buffer;
}
}
catch (Exception)
{
return null;
}
}
public static byte[] ImageSourcesToBytes(ImageSource imageSource)
{
BitmapSource m = (BitmapSource)imageSource;
Bitmap bmp = new Bitmap(m.PixelWidth, m.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); // 坑点:选Format32bppRgb将不带透明度
BitmapData data = bmp.LockBits(
new Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
m.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
bmp.UnlockBits(data);
MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Png);
byte[] bytes = ms.GetBuffer();
ms.Close();
ms.Dispose();
return bytes;
}
}
}
#region << >>
/*----------------------------------------------------------------
* 项目名称 :GS.Terminal.Identification.Enterprise.Logic.ViewModelHandler
* 项目描述 :
* 类 名 称 :HeadHandler
* 类 描 述 :
* 所在的域 :DESKTOP-MNML8TD
* 命名空间 :GS.Terminal.Identification.Enterprise.Logic.ViewModelHandler
* 机器名称 :DESKTOP-MNML8TD
* CLR 版本 :4.0.30319.42000
* 作 者 :栾凤杰
* 创建时间 :2018/10/25 8:54:15
* 更新时间 :2018/10/25 8:54:15
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ 青岛通软网络有限公司 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using IdentificationViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS.Terminal.Identification.Enterprise.Logic
{
public class HeadHandler
{
static HeadViewModel ViewModel => Program.locator.Head;
public static void Regist()
{
}
}
}
#region << >>
/*----------------------------------------------------------------
* 项目名称 :GS.Terminal.Identification.Enterprise.Logic
* 项目描述 :
* 类 名 称 :MainHandler
* 类 描 述 :
* 所在的域 :DESKTOP-MNML8TD
* 命名空间 :GS.Terminal.Identification.Enterprise.Logic
* 机器名称 :DESKTOP-MNML8TD
* CLR 版本 :4.0.30319.42000
* 作 者 :栾凤杰
* 创建时间 :2018/10/24 19:10:41
* 更新时间 :2018/10/24 19:10:41
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ 青岛通软网络有限公司 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using IdentificationViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using GalaSoft.MvvmLight.Ioc;
using System.Windows.Threading;
using System.Diagnostics;
using System.IO;
namespace GS.Terminal.Identification.Enterprise.Logic
{
public class MainHandler
{
internal static MainPageViewModel ViewModel => Program.locator.MainPage;
/// <summary>
/// 无人打卡待机定时器
/// </summary>
internal static System.Timers.Timer CleanViewTimer = new System.Timers.Timer(Program.config.LogicConfig.CleanViewDelay * 1000);
internal static void Regist()
{
CleanViewTimer.Elapsed += AutoResetTimer_Elapsed;
CleanViewTimer.Start();
//识别到人脸
Face.FaceRecognizationService.RegistArcFace2RecognizedEvent(new List<KeyValuePair<string, byte[]>>(), FaceHandler.OnRecognized);
//Program.faceRecognizationService.RegistRecognizedEvent(new Action<byte[]>(FaceHandler.Recognized));
//图像输出
Face.FaceRecognizationService.RegistArcFace2RecognizedVideoOutPutBufferWhitFaceInfoEvent(VideoOutPutBuffer);
//Face.FaceRecognizationService.RegistOutPutImageEvent(new Action<Bitmap>(VideoOutput));
//读卡回调
Program.deviceManagerService.RegistCardCallback(new Action<dynamic>(CardHandler.CardCallback));
ViewModel.Footer = "祝您工作愉快!";
}
private static void AutoResetTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ViewModel.Reset();
}
/// <summary>
/// 实时图像输出回调
/// </summary>
/// <param name="obj"></param>
private static void VideoOutput(Bitmap bitmap)
{
if (bitmap != null)
{
IntPtr ptr = bitmap.GetHbitmap();
var imageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
ptr,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
if (imageSource.CanFreeze) imageSource.Freeze();
DeleteObject(ptr);
//显示实时视频
ViewModel.ActiveVideo = imageSource;
}
}
private static void VideoOutPutBuffer(byte[] buffers)
{
var image =
ByteArrayToBitmapImage(buffers);
if (image != null)
{
if (image.CanFreeze) image.Freeze();
ViewModel.ActiveVideo = image;
}
}
private static BitmapImage ByteArrayToBitmapImage(byte[] byteArray)
{
BitmapImage bmp = null;
try
{
bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = new MemoryStream(byteArray);
bmp.EndInit();
}
catch
{
bmp = null;
}
return bmp;
}
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
}
}
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommonServiceLocator" version="2.0.2" targetFramework="net452" />
<package id="GS.Unitive.Framework" version="1.4.0.2" targetFramework="net452" />
<package id="log4net" version="2.0.8" targetFramework="net452" />
<package id="MvvmLightLibs" version="5.4.1.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net452" />
<package id="sqlSugar" version="5.0.1.4" targetFramework="net452" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net452" />
</packages>
\ No newline at end of file

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28315.86
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GS.Terminal.Identification.EnterpriseHost", "GS.Terminal.Identification.EnterpriseHost\GS.Terminal.Identification.EnterpriseHost.csproj", "{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}"
ProjectSection(ProjectDependencies) = postProject
{4E906653-4597-4140-8535-DE57582BB98D} = {4E906653-4597-4140-8535-DE57582BB98D}
{8ADCB6FE-2682-4320-8524-05F0787E752E} = {8ADCB6FE-2682-4320-8524-05F0787E752E}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ViewModelView", "ViewModelView", "{2D2369E5-C37C-4BBD-AEFC-658C661103FC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Logic", "Logic", "{B63AE5B3-341F-4C8F-9432-29AA85B2F153}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Synchronize", "Synchronize", "{972EAFD8-2C57-425F-9B85-922736270EF8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DB", "DB", "{45C88B7B-6438-410C-A3E7-B54E6865D245}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GS.Terminal.Identification.LocalDbModel", "GS.Terminal.Identification.LocalDbModel\GS.Terminal.Identification.LocalDbModel.csproj", "{D753A763-DA74-4697-99F5-8815F850A7D3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GS.Terminal.Identification.DbHandler", "GS.Terminal.Identification.DbHandler\GS.Terminal.Identification.DbHandler.csproj", "{55C05F45-1762-4EEE-AFD2-417610726759}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UDPCommand", "UDPCommand", "{B0F7C562-97F0-4BDB-BD7E-2C4E963EC87A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdentificationCommand", "IdentificationCommand\IdentificationCommand.csproj", "{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdentificationViews", "IdentificationViews\IdentificationViews.csproj", "{4E906653-4597-4140-8535-DE57582BB98D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GS.Terminal.Identification.Enterprise.Logic", "GS.Terminal.Identification.Enterprise.Logic\GS.Terminal.Identification.Enterprise.Logic.csproj", "{8ADCB6FE-2682-4320-8524-05F0787E752E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GS.EnterpriseIdentification.ServiceModel", "GS.EnterpriseIdentification.ServiceModel\GS.EnterpriseIdentification.ServiceModel.csproj", "{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdentificationViewModels", "IdentificationViewModels\IdentificationViewModels.csproj", "{A5C283A6-6D6E-4E2D-B186-02527E43053F}"
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
{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}.Debug|x64.ActiveCfg = Debug|Any CPU
{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}.Debug|x64.Build.0 = Debug|Any CPU
{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}.Release|Any CPU.Build.0 = Release|Any CPU
{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}.Release|x64.ActiveCfg = Release|Any CPU
{774AFBAC-3AD8-4272-82DE-1F8EE60254B7}.Release|x64.Build.0 = Release|Any CPU
{D753A763-DA74-4697-99F5-8815F850A7D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D753A763-DA74-4697-99F5-8815F850A7D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D753A763-DA74-4697-99F5-8815F850A7D3}.Debug|x64.ActiveCfg = Debug|Any CPU
{D753A763-DA74-4697-99F5-8815F850A7D3}.Debug|x64.Build.0 = Debug|Any CPU
{D753A763-DA74-4697-99F5-8815F850A7D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D753A763-DA74-4697-99F5-8815F850A7D3}.Release|Any CPU.Build.0 = Release|Any CPU
{D753A763-DA74-4697-99F5-8815F850A7D3}.Release|x64.ActiveCfg = Release|Any CPU
{D753A763-DA74-4697-99F5-8815F850A7D3}.Release|x64.Build.0 = Release|Any CPU
{55C05F45-1762-4EEE-AFD2-417610726759}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55C05F45-1762-4EEE-AFD2-417610726759}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55C05F45-1762-4EEE-AFD2-417610726759}.Debug|x64.ActiveCfg = Debug|Any CPU
{55C05F45-1762-4EEE-AFD2-417610726759}.Debug|x64.Build.0 = Debug|Any CPU
{55C05F45-1762-4EEE-AFD2-417610726759}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55C05F45-1762-4EEE-AFD2-417610726759}.Release|Any CPU.Build.0 = Release|Any CPU
{55C05F45-1762-4EEE-AFD2-417610726759}.Release|x64.ActiveCfg = Release|Any CPU
{55C05F45-1762-4EEE-AFD2-417610726759}.Release|x64.Build.0 = Release|Any CPU
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}.Debug|x64.ActiveCfg = Debug|Any CPU
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}.Debug|x64.Build.0 = Debug|Any CPU
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}.Release|Any CPU.Build.0 = Release|Any CPU
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}.Release|x64.ActiveCfg = Release|Any CPU
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE}.Release|x64.Build.0 = Release|Any CPU
{4E906653-4597-4140-8535-DE57582BB98D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E906653-4597-4140-8535-DE57582BB98D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E906653-4597-4140-8535-DE57582BB98D}.Debug|x64.ActiveCfg = Debug|Any CPU
{4E906653-4597-4140-8535-DE57582BB98D}.Debug|x64.Build.0 = Debug|Any CPU
{4E906653-4597-4140-8535-DE57582BB98D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E906653-4597-4140-8535-DE57582BB98D}.Release|Any CPU.Build.0 = Release|Any CPU
{4E906653-4597-4140-8535-DE57582BB98D}.Release|x64.ActiveCfg = Release|Any CPU
{4E906653-4597-4140-8535-DE57582BB98D}.Release|x64.Build.0 = Release|Any CPU
{8ADCB6FE-2682-4320-8524-05F0787E752E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8ADCB6FE-2682-4320-8524-05F0787E752E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8ADCB6FE-2682-4320-8524-05F0787E752E}.Debug|x64.ActiveCfg = Debug|Any CPU
{8ADCB6FE-2682-4320-8524-05F0787E752E}.Debug|x64.Build.0 = Debug|Any CPU
{8ADCB6FE-2682-4320-8524-05F0787E752E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8ADCB6FE-2682-4320-8524-05F0787E752E}.Release|Any CPU.Build.0 = Release|Any CPU
{8ADCB6FE-2682-4320-8524-05F0787E752E}.Release|x64.ActiveCfg = Release|Any CPU
{8ADCB6FE-2682-4320-8524-05F0787E752E}.Release|x64.Build.0 = Release|Any CPU
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}.Debug|x64.ActiveCfg = Debug|x64
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}.Debug|x64.Build.0 = Debug|x64
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}.Release|Any CPU.Build.0 = Release|Any CPU
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}.Release|x64.ActiveCfg = Release|x64
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A}.Release|x64.Build.0 = Release|x64
{A5C283A6-6D6E-4E2D-B186-02527E43053F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5C283A6-6D6E-4E2D-B186-02527E43053F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5C283A6-6D6E-4E2D-B186-02527E43053F}.Debug|x64.ActiveCfg = Debug|x64
{A5C283A6-6D6E-4E2D-B186-02527E43053F}.Debug|x64.Build.0 = Debug|x64
{A5C283A6-6D6E-4E2D-B186-02527E43053F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5C283A6-6D6E-4E2D-B186-02527E43053F}.Release|Any CPU.Build.0 = Release|Any CPU
{A5C283A6-6D6E-4E2D-B186-02527E43053F}.Release|x64.ActiveCfg = Release|x64
{A5C283A6-6D6E-4E2D-B186-02527E43053F}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D753A763-DA74-4697-99F5-8815F850A7D3} = {45C88B7B-6438-410C-A3E7-B54E6865D245}
{55C05F45-1762-4EEE-AFD2-417610726759} = {45C88B7B-6438-410C-A3E7-B54E6865D245}
{81672D50-66C3-4E3C-B3B9-5CB49D82EBEE} = {B0F7C562-97F0-4BDB-BD7E-2C4E963EC87A}
{4E906653-4597-4140-8535-DE57582BB98D} = {2D2369E5-C37C-4BBD-AEFC-658C661103FC}
{8ADCB6FE-2682-4320-8524-05F0787E752E} = {B63AE5B3-341F-4C8F-9432-29AA85B2F153}
{D9D132F9-E932-42B3-B6BC-1AA597B79A3A} = {972EAFD8-2C57-425F-9B85-922736270EF8}
{A5C283A6-6D6E-4E2D-B186-02527E43053F} = {2D2369E5-C37C-4BBD-AEFC-658C661103FC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B3A3A4D3-2CA4-46F9-AB18-B48AF9D31D50}
EndGlobalSection
EndGlobal
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- 头部-->
<Style x:Key="MainShell_HeaderBackground" TargetType="Grid">
<Setter Property="Height" Value="120"></Setter>
<Setter Property="Background" Value="#00456d"></Setter>
</Style>
<!-- 底部-->
<Style x:Key="MainShell_FootBackground" TargetType="Grid">
<Setter Property="Height" Value="0"></Setter>
<Setter Property="Background" Value="#006766"></Setter>
</Style>
<Style x:Key="LogoTextBlockStyle" TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="60"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Margin" Value="20,0,0,0"/>
<Setter Property="FontFamily" Value="/GS.Terminal.Theme;component/Fonts/#锐字云字库行草体1.0"/>
</Style>
</ResourceDictionary>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment