添加项目文件。

master
wenjy 8 months ago
commit 662cefd95d

63
.gitattributes vendored

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

363
.gitignore vendored

@ -0,0 +1,363 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd

@ -0,0 +1,26 @@
using System;
namespace SlnMesnac.RfidUpload.Analysis
{
/// <summary>
/// 标签信息解析
/// </summary>
public sealed class BufferAnalysis
{
#region 单例实现
private static readonly Lazy<BufferAnalysis> _lazy = new Lazy<BufferAnalysis>(() => new BufferAnalysis());
public static BufferAnalysis Instance
{
get
{
return _lazy.Value;
}
}
#endregion
private BufferAnalysis() { }
}
}

@ -0,0 +1,85 @@
using NLog;
using SlnMesnac.RfidUpload.Common;
using SlnMesnac.RfidUpload.Model;
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.RfidUpload.Analysis
{
/// <summary>
/// 指令适配器
/// </summary>
public class InstructionAdapter
{
private MsgUtil _msgUtil = MsgUtil.Instance;
private static Logger logger = LogManager.GetCurrentClassLogger();
#region 单例实现
private static readonly Lazy<InstructionAdapter> _lazy = new Lazy<InstructionAdapter>(() => new InstructionAdapter());
public static InstructionAdapter Instance
{
get
{
return _lazy.Value;
}
}
#endregion
private InstructionAdapter() { }
/// <summary>
/// 标签解析
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public InstructionInfo ParseInstruction(byte[] buffer)
{
logger.Info("开始解析标签信息");
byte[] m_length = new byte[2];
Array.Copy(buffer, 2, m_length, 0, 2);
int bufferLength = Convert.ToInt32(BitConverter.ToString(m_length).Replace("-", ""), 16);
if (buffer.Length != bufferLength)
{
throw new ArgumentException("指令长度不正确");
}
byte[] xorbuffer = new byte[buffer.Length - 3];
Array.Copy(buffer, 2, xorbuffer, 0, xorbuffer.Length);
string xorStr = _msgUtil.CalculateXORChecksum(xorbuffer);
string bufferXor = buffer[buffer.Length - 1].ToString("X2");
if (bufferXor != xorStr)
{
throw new ArgumentException($"XOR校验失败,指令XOR:{bufferXor},计算XOR:{xorStr}");
}
InstructionInfo instructionInfo = new InstructionInfo();
byte[] m_stx = new byte[2];
Array.Copy(buffer, 0, m_stx, 0, 2);
instructionInfo.stx = BitConverter.ToString(m_stx).Replace("-", "");
instructionInfo.len = bufferLength;
instructionInfo.cmd = buffer[4];
int status = Convert.ToInt32(buffer[5]);
instructionInfo.status = status;
byte[] m_data = new byte[bufferLength - 7];
Array.Copy(buffer, 6, m_data, 0, m_data.Length);
string dataValue = Encoding.ASCII.GetString(m_data);
instructionInfo.data = dataValue;
instructionInfo.xor = buffer[buffer.Length - 1];
instructionInfo.recordtime = DateTime.Now;
return instructionInfo;
}
}
}

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SlnMesnac.RfidUpload.Common\SlnMesnac.RfidUpload.Common.csproj" />
<ProjectReference Include="..\SlnMesnac.RfidUpload.Model\SlnMesnac.RfidUpload.Model.csproj" />
<ProjectReference Include="..\SlnMesnac.RfidUpload.NLog\SlnMesnac.RfidUpload.NLog.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,163 @@
using SlnMesnac.RfidUpload.Analysis;
using SlnMesnac.RfidUpload.Common;
using SlnMesnac.RfidUpload.Model;
using SlnMesnac.RfidUpload.TouchSocket;
using System;
using System.Collections.Generic;
using System.Linq;
namespace SlnMesnac.RfidUpload.Business
{
/// <summary>
/// 业务逻辑处理
/// </summary>
public class HandleBusiness
{
private JsonChange _jsonChange = JsonChange.Instance;
private InstructionAdapter adapter = InstructionAdapter.Instance;
private WebApiClientApp _webApiClientApp = WebApiClientApp.Instance;
private List<InstructionInfo> instructionInfoList = new List<InstructionInfo>();
#region 单例实现
private static readonly Lazy<HandleBusiness> _lazy = new Lazy<HandleBusiness>(() => new HandleBusiness());
public static HandleBusiness Instance
{
get
{
return _lazy.Value;
}
}
#endregion
#region 委托事件
/// <summary>
/// 刷新标签解析
/// </summary>
public delegate void RefreshInstructionInfoDataGrid(InstructionInfo instructionInfo);
public event RefreshInstructionInfoDataGrid InstructionInfoDataGridEvent;
/// <summary>
/// 刷新日志内容
/// </summary>
public delegate void RefreshLogMessage(string message);
public event RefreshLogMessage RefreshLogMessageEvent;
#endregion
private HandleBusiness() { }
/// <summary>
/// 标签处理
/// </summary>
/// <param name="buffer"></param>
/// <exception cref="ArgumentException"></exception>
public void LabelHandle(byte[] buffer)
{
//功能码判断
if (buffer[4] == 0x31)
{
try
{
InstructionInfo info = adapter.ParseInstruction(buffer);
if (info != null)
{
if (FilterTags(info))
{
instructionInfoList.Add(info);
RefreshLogMessageEvent?.Invoke($"标签解析数据:{_jsonChange.ModeToJson(info)}");
InstructionInfoDataGridEvent?.Invoke(info);
}
else
{
RefreshLogMessageEvent?.Invoke($"标签:{info.data};与前次读取间隔小于1分钟不进行逻辑处理");
}
}
}
catch (Exception e)
{
RefreshLogMessageEvent?.Invoke($"标签解析异常:{e.Message}");
}
}
}
/// <summary>
/// 粘包处理
/// </summary>
/// <param name="receivedData"></param>
/// <returns></returns>
public List<byte[]> SplitPackets(byte[] receivedData)
{
List<byte[]> packets = new List<byte[]>();
int index = 0;
while (index < receivedData.Length)
{
if (receivedData[index] == 0xAA && receivedData[index + 1] == 0x55)
{
int packetLength = (receivedData[index + 2] << 8) | receivedData[index + 3];
if (packetLength <= receivedData.Length - index)
{
byte[] packet = new byte[packetLength];
Array.Copy(receivedData, index, packet, 0, packetLength);
packets.Add(packet);
index += packetLength;
}
else
{
break;
}
}
else
{
index++;
}
}
return packets;
}
public void apiTest(string url)
{
//WebApiClientApp api = new WebApiClientApp();
_webApiClientApp.Upload(url);
}
/// <summary>
/// 标签过滤同一标签1分钟内不进行逻辑处理
/// </summary>
/// <param name="instructionInfo"></param>
/// <returns></returns>
private bool FilterTags(InstructionInfo instructionInfo)
{
InstructionInfo lastInstructionInfo = instructionInfoList.Where(x => x.data == instructionInfo.data).FirstOrDefault();
if(lastInstructionInfo == null)
{
return true;
}
else
{
TimeSpan timeDifference = instructionInfo.recordtime.Subtract(lastInstructionInfo.recordtime);
double minutesDifference = timeDifference.TotalMinutes;
if (minutesDifference < 1)
{
return false;
}
else
{
instructionInfoList.Remove(lastInstructionInfo);
return true;
}
}
}
}
}

@ -0,0 +1,124 @@
using System;
using System.IO.Ports;
using System.Linq;
using System.Threading;
namespace SlnMesnac.RfidUpload.Business
{
/// <summary>
/// 串口通讯类
/// </summary>
public class SerialPortBusiness
{
#region 单例实现
private static readonly Lazy<SerialPortBusiness> _lazy = new Lazy<SerialPortBusiness>(() => new SerialPortBusiness());
public static SerialPortBusiness Instance
{
get
{
return _lazy.Value;
}
}
#endregion
#region 委托事件
/// <summary>
/// 刷新标签解析
/// </summary>
public delegate void ReceivedData(byte[] buffer);
public event ReceivedData ReceivedDataEvent;
/// <summary>
/// 刷新日志内容
/// </summary>
public delegate void RefreshLogMessage(string message);
public event RefreshLogMessage RefreshLogMessageEvent;
#endregion
private SerialPort _serialPort;
private SerialPortBusiness()
{
}
/// <summary>
/// 打开串口
/// </summary>
public void Open()
{
string port = System.IO.Ports.SerialPort.GetPortNames().FirstOrDefault();
_serialPort = new SerialPort(port, 115200, Parity.None, 8, StopBits.One);
_serialPort.DataReceived += SerialPortDataReceived;
_serialPort.Open();
}
/// <summary>
/// 关闭串口
/// </summary>
public void Close()
{
if (_serialPort != null)
{
_serialPort.Close();
}
else
{
throw new ArgumentException("_serialPort == null");
}
}
/// <summary>
/// 接收数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
Thread.Sleep(200);
int bytesToRead = _serialPort.BytesToRead;
byte[] buffer = new byte[bytesToRead];
_serialPort.Read(buffer, 0, bytesToRead);
RefreshLogMessageEvent?.Invoke("Received data: " + BitConverter.ToString(buffer).Replace("-", " "));
if (CheckReceivedData(buffer))
{
ReceivedDataEvent?.Invoke(buffer);
}
else
{
RefreshLogMessageEvent?.Invoke("心跳指令不进行逻辑处理");
}
}
catch (Exception ex)
{
RefreshLogMessageEvent?.Invoke($"接收数据异常:{ex.Message}");
}
}
/// <summary>
/// 判断是否为业务数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private bool CheckReceivedData(byte[] data)
{
if (data.Length > 4)
{
return true;
}
return false;
}
}
}

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SlnMesnac.RfidUpload.Analysis\SlnMesnac.RfidUpload.Analysis.csproj" />
<ProjectReference Include="..\SlnMesnac.RfidUpload.Common\SlnMesnac.RfidUpload.Common.csproj" />
<ProjectReference Include="..\SlnMesnac.RfidUpload.TouchSocket\SlnMesnac.RfidUpload.TouchSocket.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
</ItemGroup>
</Project>

@ -0,0 +1,109 @@
using Nancy.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace SlnMesnac.RfidUpload.Common
{
public sealed class JsonChange
{
private static readonly Lazy<JsonChange> lazy = new Lazy<JsonChange>(() => new JsonChange());
public static JsonChange Instance
{
get
{
return lazy.Value;
}
}
private JsonChange() { }
/// <summary>
/// Model 实体转json
/// </summary>
/// <param name="Model">可以是单个实体也可是实体集ToList()</param>
/// <returns></returns>
public string ModeToJson(object Model)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
try
{
string str = serializer.Serialize(Model);
return str;
}
catch (Exception)
{
return "";
}
}
/// <summary>
/// json实体转Model
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonStr"></param>
/// <returns></returns>
public T JsonToMode<T>(string jsonStr)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
try
{
var info = serializer.Deserialize<T>(jsonStr);
return info;
}
catch (Exception)
{
return default(T);
}
}
/// <summary>
/// object转dictionary
/// </summary>
/// <param name="jsonData"></param>
/// <returns></returns>
public Dictionary<string, object> objectToDictionary(string jsonData)
{
Dictionary<string, object> result = new Dictionary<string, object>();
var inf = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonData);
foreach (KeyValuePair<string, object> item in inf)
{
if (item.Value != null)
{
var type = item.Value.GetType();
if (type == typeof(JObject))
{
var info = objectToDictionary(JsonConvert.SerializeObject(item.Value));
foreach (KeyValuePair<string, object> ite in info)
{
result.Add(ite.Key, ite.Value);
}
continue;
}
else if (type == typeof(JArray))
{
JArray array = (JArray)item.Value;
var info = objectToDictionary(JsonConvert.SerializeObject(array[0]));
foreach (KeyValuePair<string, object> ite in info)
{
result.Add(item.Key + ite.Key, ite.Value);
}
continue;
}
}
result.Add(item.Key, item.Value);
}
return result;
}
}
}

@ -0,0 +1,309 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace SlnMesnac.RfidUpload.Common
{
/// <summary>
/// 工具类
/// </summary>
public sealed class MsgUtil
{
private static readonly Lazy<MsgUtil> lazy = new Lazy<MsgUtil>(() => new MsgUtil());
public static MsgUtil Instance
{
get
{
return lazy.Value;
}
}
private MsgUtil() { }
#region 数据解析公共方法
/// <summary>
/// 字节数组转换成结构体
/// </summary>
/// <param name="buf"></param>
/// <param name="len"></param>
/// <param name="type"></param>
/// <returns></returns>
public static object BytesToStruct(byte[] buf, int len, Type type)
{
object rtn;
IntPtr buffer = Marshal.AllocHGlobal(len);
Marshal.Copy(buf, 0, buffer, len);
try
{
rtn = Marshal.PtrToStructure(buffer, type);
Marshal.FreeHGlobal(buffer);
}
catch (Exception)
{
return null;
}
return rtn;
}
public string StringToHexString(string s, Encoding encode)
{
byte[] b = encode.GetBytes(s); //按照指定编码将string编程字节数组
string result = string.Empty;
for (int i = 0; i < b.Length; i++) //逐字节变为16进制字符以%隔开
{
result += "%" + Convert.ToString(b[i], 16);
}
return result;
}
//// <summary>
/// 结构体转byte数组
/// </summary>
/// <param name="structObj">要转换的结构体</param>
/// <returns>转换后的byte数组</returns>
public static byte[] StructToBytes(object structObj)
{
//得到结构体的大小
int size = Marshal.SizeOf(structObj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(structObj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
}
#endregion
#region 消息验证方法
/// <summary>
/// CS和校验
/// </summary>
/// <param name="Abyte"></param>
/// <returns></returns>
public byte Check_CS(byte[] Abyte)
{
byte result = new byte();
try
{
int num = 0;
for (int i = 0; i < Abyte.Length; i++)
{
num = (num + Abyte[i]) % 256;
}
result = (byte)num;
}
catch
{
result = 0;
}
return result;
}
/// <summary>
/// BCC异或取反校验
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public string getBCC(byte[] data)
{
String ret = "";
byte[] BCC = new byte[1];
for (int i = 0; i < data.Length; i++)
{
BCC[0] = (byte)(BCC[0] ^ data[i]);
}
String hex = ((~BCC[0]) & 0xFF).ToString("X");//取反操作
if (hex.Length == 1)
{
hex = '0' + hex;
}
ret += hex.ToUpper();
return ret;
}
static int BytesToInt(byte[] b, int length)
{
int temp = 0;
for (int i = 0; i <= length - 1 && i < 4; i++)
{
temp += (int)(b[i] << (i * 8));
}
return temp;
}
public static byte[] CalculateVerify(byte[] pMessage, int iLength)
{
UInt16 i;
int iVerify = 0;
iVerify = pMessage[0];
for (i = 0; i < iLength - 1; i++)
{
iVerify = iVerify + pMessage[i + 1];
}
return BitConverter.GetBytes(Convert.ToUInt16(iVerify));
}
#endregion
public byte[] HexStrTorbytes(string strHex)//e.g. " 01 01" ---> { 0x01, 0x01}
{
strHex = strHex.Replace(" ", "");
if ((strHex.Length % 2) != 0)
strHex += " ";
byte[] returnBytes = new byte[strHex.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(strHex.Substring(i * 2, 2), 16);
return returnBytes;
}
/// <summary>
/// 将字符串强制转换成int转换失败则返回0
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public int ParseToInt(string str)
{
int returnInt = 0;
if (str == null || str.Trim().Length < 1)
{
return returnInt;
}
if (int.TryParse(str, out returnInt))
{
return returnInt;
}
else
{
return 0;
}
}
public byte[] HexToString(string Str)
{
byte[] str = new byte[Str.Length / 2];
for (int i = 0; i < str.Length; i++)
{
int temp = Convert.ToInt32(Str.Substring(i * 2, 2), 16);
str[i] = (byte)temp;
}
return str;
}
public string ConverToString(byte[] data)
{
string str;
StringBuilder stb = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
if ((int)data[i] > 15)
{
stb.Append(Convert.ToString(data[i], 16).ToUpper()); //添加字符串
}
else //如果是小于0F需要加个零
{
stb.Append("0" + Convert.ToString(data[i], 16).ToUpper());
}
}
str = stb.ToString();
return str;
}
public string bytesToHexStr(byte[] bytes, int iLen)
{
StringBuilder sb = new StringBuilder();
if (bytes != null)
{
for (int i = 0; i < iLen; i++)
{
sb.Append(bytes[i].ToString("X2"));
}
}
return sb.ToString();
}
/// <summary>
/// 从十进制转换到十六进制
/// </summary>
/// <param name="ten"></param>
/// <returns></returns>
public string Ten2Hex(string ten)
{
ulong tenValue = Convert.ToUInt64(ten);
ulong divValue, resValue;
string hex = "";
do
{
//divValue = (ulong)Math.Floor(tenValue / 16);
divValue = (ulong)Math.Floor((decimal)(tenValue / 16));
resValue = tenValue % 16;
hex = tenValue2Char(resValue) + hex;
tenValue = divValue;
}
while (tenValue >= 16);
if (tenValue != 0)
hex = tenValue2Char(tenValue) + hex;
return hex;
}
/// <summary>
/// 异或和校验
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public string CalculateXORChecksum(byte[] bytes)
{
byte checksum = bytes[0];
foreach (byte b in bytes)
{
checksum ^= b;
}
return checksum.ToString("X2");
}
public string tenValue2Char(ulong ten)
{
switch (ten)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
return ten.ToString();
case 10:
return "A";
case 11:
return "B";
case 12:
return "C";
case 13:
return "D";
case 14:
return "E";
case 15:
return "F";
default:
return "";
}
}
}
}

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nancy" Version="2.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>

@ -0,0 +1,28 @@
using System;
using Microsoft.Extensions.Options;
namespace SlnMesnac.RfidUpload.Config
{
/// <summary>
/// 系统配置
/// </summary>
public class AppConfig : IOptions<AppConfig>
{
/// <summary>
/// 日志文件路径
/// </summary>
public string logPath { get; set; }
/// <summary>
/// MES 数据库连接字符串
/// </summary>
public string mesConnStr { get; set; }
/// <summary>
/// MCS 数据库连接字符串
/// </summary>
public string mcsConnStr { get; set; }
public AppConfig Value => this;
}
}

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.0" />
</ItemGroup>
</Project>

@ -0,0 +1,43 @@
namespace SlnMesnac.RfidUpload.Model
{
/// <summary>
/// 容器入库
/// </summary>
public class ContainerInbound
{
/// <summary>
/// 入参1请求报文到消息头
/// </summary>
public string messageHeader { get; set; }
/// <summary>
/// 入参2将下列参数封装到batchOpenQuery
/// </summary>
public string batchOpenQuery { get; set; }
/// <summary>
/// 机构代码
/// </summary>
public string opOrgCode { get; set; }
/// <summary>
/// 登录人代码
/// </summary>
public string userCode { get; set; }
/// <summary>
/// 登录人名称
/// </summary>
public string userName { get; set; }
/// <summary>
/// 省份代码
/// </summary>
public string province { get; set; }
/// <summary>
/// 容器条码
/// </summary>
public string rqtm { get; set; }
}
}

@ -0,0 +1,83 @@
namespace SlnMesnac.RfidUpload.Model
{
/// <summary>
/// 容器封发扫描
/// </summary>
public class ContainerSealed
{
/// <summary>
/// 入参1请求报文到消息头
/// </summary>
public string messageHeader { get; set; }
/// <summary>
/// 入参2将下列参数封装到containerRegisterQuery
/// </summary>
public string containerRegisterQuery { get; set; }
/// <summary>
/// 机构代码
/// </summary>
public string opOrgCode { get; set; }
/// <summary>
/// 机构名称
/// </summary>
public string opOrgName { get; set; }
/// <summary>
/// 登录人代码
/// </summary>
public string userCode { get; set; }
/// <summary>
/// 登录人名称
/// </summary>
public string userName { get; set; }
/// <summary>
/// 省份代码
/// </summary>
public string province { get; set; }
/// <summary>
/// 容器种类名称
/// </summary>
public string rqzlmc { get; set; }
/// <summary>
/// 总包Id
/// </summary>
public string zbid { get; set; }
/// <summary>
/// 寄达局名称
/// </summary>
public string destinationOrgName { get; set; }
/// <summary>
/// 寄达局编号
/// </summary>
public string destinationOrgCode { get; set; }
/// <summary>
/// 容器种类
/// </summary>
public string rqzl { get; set; }
/// <summary>
/// 容器型号
/// </summary>
public string rqxh { get; set; }
/// <summary>
/// 容器型号名称
/// </summary>
public string rqxhmc { get; set; }
/// <summary>
/// 容器条码
/// </summary>
public string rqtm { get; set; }
}
}

@ -0,0 +1,55 @@
using MiniExcelLibs.Attributes;
using System;
namespace SlnMesnac.RfidUpload.Model
{
/// <summary>
/// 指令信息
/// </summary>
public class InstructionInfo
{
/// <summary>
///
/// </summary>
[ExcelColumn(Name = "stx",Index = 0),ExcelColumnWidth(23)]
public string stx { get; set; }
/// <summary>
/// 报文长度,包含帧头、校验
/// </summary>
[ExcelColumn(Name = "len", Index = 1), ExcelColumnWidth(23)]
public int len { get; set; }
/// <summary>
/// 报文类型0x31
/// </summary>
[ExcelColumn(Name = "cmd", Index = 2), ExcelColumnWidth(23)]
public byte cmd { get; set; }
/// <summary>
/// 擦除状态0-成功1-失败
/// </summary>
[ExcelColumn(Name = "status", Index = 3), ExcelColumnWidth(23)]
public int status { get; set; }
/// <summary>
/// 数据
/// </summary>
[ExcelColumn(Name = "data", Index = 4), ExcelColumnWidth(53)]
public string data { get; set; }
/// <summary>
/// 异或和校验10进制
/// </summary>
[ExcelColumn(Name = "xor", Index = 5), ExcelColumnWidth(23)]
public byte xor { get; set; }
/// <summary>
/// 记录时间
/// </summary>
[ExcelColumn(Name = "recordtime", Index = 6), ExcelColumnWidth(23)]
public DateTime recordtime { get; set; }
}
}

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MiniExcel" Version="1.31.2" />
</ItemGroup>
</Project>

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Remove="C:\Users\Administrator\.nuget\packages\nlog.config\4.7.15\contentFiles\any\any\NLog.config" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="C:\Users\Administrator\.nuget\packages\nlog.config\4.7.15\contentFiles\any\any\NLog.config" />
</ItemGroup>
<ItemGroup>
<None Include="C:\Users\Administrator\.nuget\packages\nlog.config\4.7.15\contentFiles\any\any\NLog.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NLog.Config" Version="4.7.15" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.7" />
</ItemGroup>
</Project>

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TouchSocket" Version="1.3.9" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SlnMesnac.RfidUpload.Model\SlnMesnac.RfidUpload.Model.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,57 @@
using SlnMesnac.RfidUpload.Model;
using System;
using TouchSocket.Rpc.WebApi;
namespace SlnMesnac.RfidUpload.TouchSocket
{
public sealed class WebApiClientApp
{
#region 单例实现
private static readonly Lazy<WebApiClientApp> _lazy = new Lazy<WebApiClientApp>(() => new WebApiClientApp());
public static WebApiClientApp Instance
{
get
{
return _lazy.Value;
}
}
#endregion
private WebApiClientApp() { }
private WebApiClient CreateWebApiClient(string url)
{
WebApiClient client = new WebApiClient();
client.Setup(url);
client.Connect();
Console.WriteLine("连接成功");
return client;
}
public void Upload(string url)
{
try
{
var client = CreateWebApiClient(url);
var param = new ContainerInbound()
{
messageHeader = Guid.NewGuid().ToString(),
batchOpenQuery = "OK",
opOrgCode = Guid.NewGuid().ToString()
};
var sum2 = client.Invoke<ActionResult>("POST:/Server/ContainerInboundApi", null, param);
Console.WriteLine($"Post调用成功结果{sum2.Message}");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}

@ -0,0 +1,14 @@
<Application x:Class="SlnMesnac.RfidUpload.UI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SlnMesnac.RfidUpload.UI"
StartupUri="MainWindow.xaml">
<Application.Resources>
<!--Button样式-->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="templates/style/resourceStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

@ -0,0 +1,11 @@
using System.Windows;
namespace SlnMesnac.RfidUpload.UI
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

@ -0,0 +1,134 @@
<Window x:Class="SlnMesnac.RfidUpload.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SlnMesnac.RfidUpload.UI"
mc:Ignorable="d"
Title="海威物联RFID移动盘点系统" Height="766" Width="1268" ResizeMode="NoResize" Topmost="False">
<!--<Window.Background>
<ImageBrush ImageSource="/templates/image/background.jpg" />
</Window.Background>-->
<Border Margin="5" Background="White" CornerRadius="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderThickness="2" CornerRadius="5" Background="White" Margin="5,0,5,0">
<Border.Effect>
<DropShadowEffect Color="Gray" ShadowDepth="0" BlurRadius="5" Opacity="0.3" Direction="0"></DropShadowEffect>
</Border.Effect>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Orientation="Horizontal">
<Button Content="打开串口" Command="{Binding OpenSerialPortCommand}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009900" BorderBrush="#009900" Margin="10,0,10,0"/>
<Button Content="关闭串口" Command="{Binding CloseSerialPortCommand}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#FF0033" BorderBrush="#FF0033" Margin="0,0,10,0"/>
<Button Content="导出文件" Command="{Binding ExportFilesCommand}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#007DFA" BorderBrush="#007DFA" Margin="0,0,10,0"/>
<Button Content="清空列表" Command="{Binding EmptyFilesCommand}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="Orange" BorderBrush="Orange" Margin="0,0,10,0"/>
<Label Content="数 量 :" FontSize="20" FontWeight="Black" Foreground="#00CC33" Margin="20,0,0,0"/>
<Label Content="{Binding LabelCountParam}" FontSize="20" FontWeight="Black" Foreground="#00CC33" Margin="5,0,10,0"/>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Text="串口连接状态" FontSize="20" FontWeight="Black" Foreground="#006699" Margin="2,0,10,0"/>
</StackPanel>
<StackPanel Grid.Column="1" Margin="0,0,20,0">
<Ellipse Width="30" Height="30">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Style.Triggers>
<DataTrigger Binding="{Binding RfidDeviceStatus}" Value="0">
<Setter Property="Shape.Fill" Value="Orange"/>
</DataTrigger>
<DataTrigger Binding="{Binding RfidDeviceStatus}" Value="1">
<Setter Property="Shape.Fill" Value="Green"/>
</DataTrigger>
<DataTrigger Binding="{Binding RfidDeviceStatus}" Value="2">
<Setter Property="Shape.Fill" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</StackPanel>
</Grid>
</StackPanel>
</Grid>
</Border>
<Border Grid.Row="1" BorderThickness="2" CornerRadius="5" Background="White" Margin="5">
<Border.Effect>
<DropShadowEffect Color="Gray" ShadowDepth="0" BlurRadius="5" Opacity="0.3" Direction="0"></DropShadowEffect>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="15*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="CadetBlue" BorderThickness="0,0,0,0" CornerRadius="0" Background="Transparent" Margin="1,1,5,5" >
<TextBlock Text="标签信息" FontSize="17" FontWeight="Bold" Foreground="#0288d1" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<!--日志信息-->
<DataGrid Grid.Row="1" Name="DG" ItemsSource="{Binding LabelInfoDataGrid}" Background="Transparent"
FontSize="15" ColumnHeaderHeight="35"
RowHeight="31" AutoGenerateColumns="False" RowHeaderWidth="0"
GridLinesVisibility="None" ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden" BorderThickness="0" CanUserAddRows="False"
Foreground="#0288d1" >
<!--resourceStyle 399行修改选中字体颜色-->
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding stx}" Header="stx" Width="80" IsReadOnly="True"/>
<DataGridTextColumn Binding="{Binding len}" Header="len" Width="150" IsReadOnly="True"/>
<DataGridTextColumn Binding="{Binding cmd}" Header="cmd" Width="150" IsReadOnly="True"/>
<DataGridTextColumn Binding="{Binding status}" Header="status" Width="150" IsReadOnly="True"/>
<DataGridTextColumn Binding="{Binding data}" Header="data" Width="290" IsReadOnly="True"/>
<DataGridTextColumn Binding="{Binding xor}" Header="xor" Width="150" IsReadOnly="True"/>
<DataGridTextColumn Binding="{Binding recordtime,StringFormat=\{0:MM月dd日 HH:mm.ss.ffff\}}" Header="时间" Width="230" IsReadOnly="True"/>
<!--<DataGridTextColumn Binding="{Binding recordTime,StringFormat=\{0:MM月dd日 HH:mm\}}" Header="时间" Width="150" IsReadOnly="True"/>-->
</DataGrid.Columns>
</DataGrid>
</Grid>
</Border>
<!--日志信息-->
<Border Grid.Row="2" BorderThickness="2" CornerRadius="5" Background="White" Margin="5,0,5,0">
<Border.Effect>
<DropShadowEffect Color="Gray" ShadowDepth="0" BlurRadius="5" Opacity="0.3" Direction="0"></DropShadowEffect>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2.5*"/>
<RowDefinition Height="9*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="CadetBlue" BorderThickness="0,0,0,0" CornerRadius="0" Background="Transparent" Margin="1,1,5,5" >
<TextBlock Text="设备监控" FontSize="17" FontWeight="Bold" Foreground="#0288d1" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<!--日志信息-->
<Border Grid.Row="1" BorderBrush="Green" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="1">
<ListBox x:Name="listBox" ItemsSource="{Binding LogInfoListBox}" FontSize="14" Foreground="Gray" Background="Transparent" BorderBrush="Transparent" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden"/>
</Border>
</Grid>
</Border>
</Grid>
</Border>
</Window>

@ -0,0 +1,17 @@
using SlnMesnac.RfidUpload.UI.viewModel;
using System.Windows;
namespace SlnMesnac.RfidUpload.UI
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
}
}
}

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MvvmLightLibs" Version="5.4.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SlnMesnac.RfidUpload.Business\SlnMesnac.RfidUpload.Business.csproj" />
<ProjectReference Include="..\SlnMesnac.RfidUpload.Model\SlnMesnac.RfidUpload.Model.csproj" />
<ProjectReference Include="..\SlnMesnac.RfidUpload.NLog\SlnMesnac.RfidUpload.NLog.csproj" />
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

@ -0,0 +1,424 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SlnMesnac.RfidPrint">
<Style x:Key="Window" TargetType="Window">
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style x:Key="BUTTON_MENUBAR" TargetType="Button">
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Grid Name="g" Opacity="0" Background="LightGray"/>
<Grid Name="grd" RenderTransformOrigin="0.5,0.5" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Background="{TemplateBinding Background}" VerticalAlignment="Center" HorizontalAlignment="Center" >
<Grid.RenderTransform>
<TransformGroup>
<!--<RotateTransform x:Name="rotate" Angle="0"-->
<ScaleTransform x:Name="scale" ScaleX="0.8" ScaleY="0.8"/>
</TransformGroup>
</Grid.RenderTransform>
</Grid>
<ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="0.2" Duration="0:0:0.2" Storyboard.TargetName="g" Storyboard.TargetProperty="Opacity" />
<DoubleAnimation To="1" Duration="0:0:0.2" Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" />
<DoubleAnimation To="1" Duration="0:0:0.2" Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="0" Duration="0:0:0.2" Storyboard.TargetName="g" Storyboard.TargetProperty="Opacity" />
<DoubleAnimation To="0.8" Duration="0:0:0.2" Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" />
<DoubleAnimation To="0.8" Duration="0:0:0.2" Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BUTTON_MENUBAR_PATH" TargetType="Button">
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Foreground" Value="Gray" />
<Setter Property="Height" Value="30"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Grid Name="g" Background="LightGray" Opacity="0" />
<Grid Name="grd" Width="22" Height="22" Background="{TemplateBinding Background}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
<Path Width="10" Height="30" HorizontalAlignment="Right" VerticalAlignment="Center" Data="M3,10 L7,15 L3,20" Stroke="Gray" StrokeThickness="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="0.4" Duration="0:0:0.2" Storyboard.TargetName="g" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetName="g" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BUTTON_MENUBAR_MINI" TargetType="Button">
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True">
<Border Name="bdr" BorderBrush="LightGray" BorderThickness="2" Opacity="0">
<Border.Effect>
<DropShadowEffect x:Name="effect" BlurRadius="20" Opacity="0.8" ShadowDepth="0" Color="LightGray"/>
</Border.Effect>
</Border>
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Background="{TemplateBinding Background}" VerticalAlignment="Center" HorizontalAlignment="Center" >
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="1" Duration="0:0:0.3" Storyboard.TargetName="bdr" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="0" Duration="0:0:0.3" Storyboard.TargetName="bdr" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BUTTON_AGREE" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="bdr" CornerRadius="3" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1">
<!--可使用ContentPresenter代替-->
<!--Foreground的值White可以替换为{TemplateBinding Foreground}-->
<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Foreground="White" Content="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="0.6" Duration="0:0:0.2" Storyboard.TargetName="bdr" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="1" Duration="0:0:0.2" Storyboard.TargetName="bdr" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BUTTON_DISAGREE" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="3" BorderBrush="#FFEBEBEB" BorderThickness="1">
<Grid>
<Border Name="bdr" CornerRadius="3" Background="Gray" Opacity="0"/>
<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Foreground="{TemplateBinding Foreground}" Content="{TemplateBinding Content}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="0.2" Duration="0:0:0.2" Storyboard.TargetName="bdr" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="0" Duration="0:0:0.2" Storyboard.TargetName="bdr" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="SOLIDCOLORBRUSH_LIGHT" Color="#FF6FD1FF"/>
<Color x:Key="COLOR_LIGHT" R="111" G="209" B="255" A="255" />
<Style x:Key="BUTTON_ELLIPSE" TargetType="{x:Type Button}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="ToolTip" Value="下一步"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="15" Width="30" Height="30" Background="{DynamicResource SOLIDCOLORBRUSH_LIGHT}">
<Border.Effect>
<DropShadowEffect x:Name="effect" BlurRadius="7" Opacity="0.6" ShadowDepth="0" Color="{DynamicResource COLOR_LIGHT}"/>
</Border.Effect>
<Grid>
<Path Name="path" HorizontalAlignment="Left" Margin="0,0,0,0" Data="M5,15 L 15,23 L24,9" Stroke="White" StrokeThickness="1"/>
<Path Name="path2" HorizontalAlignment="Left" Opacity="0" Margin="0,0,0,0" Data="M5,15 H25 L17,7 M25,15 L17,22 " Stroke="White" StrokeThickness="1"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation To="0.9" Duration="0:0:0.3" Storyboard.TargetName="effect" Storyboard.TargetProperty="Opacity" />
<DoubleAnimation To="15" Duration="0:0:0.3" Storyboard.TargetName="effect" Storyboard.TargetProperty="BlurRadius" />
<DoubleAnimation To="0" Duration="0:0:0.5" Storyboard.TargetName="path" Storyboard.TargetProperty="Opacity" />
<DoubleAnimation To="1" Duration="0:0:0.5" BeginTime="0:0:0.3" Storyboard.TargetName="path2" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation Duration="0:0:0.3" Storyboard.TargetName="effect" Storyboard.TargetProperty="Opacity" />
<DoubleAnimation Duration="0:0:0.3" Storyboard.TargetName="effect" Storyboard.TargetProperty="BlurRadius" />
<DoubleAnimation Duration="0:0:0.5" BeginTime="0:0:0.3" Storyboard.TargetName="path" Storyboard.TargetProperty="Opacity" />
<DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="path2" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--DataGrid样式-->
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderBrush" Value="#FF688CAF"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="AutoGenerateColumns" Value="False"/>
<Setter Property="ColumnHeaderHeight" Value="50"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="RowHeight" Value="50"/>
<Setter Property="AlternationCount" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Grid>
<Border Background="Transparent" CornerRadius="0">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Direction="0" Color="#FFDADADA"/>
</Border.Effect>
</Border>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Background="Transparent" Grid.Column="1">
<Grid.Effect>
<DropShadowEffect Direction="270" Color="#FFF3F3F3"/>
</Grid.Effect>
</Grid>
<Button Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" Grid.Row="1"/>
<ScrollBar x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Grid.Row="1" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
<Grid Grid.Column="1" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<Grid Background="{TemplateBinding Background}">
<!--<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>-->
<ContentPresenter Margin="20 0 0 0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
<!--<TextBlock Grid.Column="1" x:Name="SortArrow" Visibility="Visible" VerticalAlignment="Center" FontFamily="/DataGrid;component/Fonts/#FontAwesome"/>-->
</Grid>
<!--<ControlTemplate.Triggers>
<Trigger Property="SortDirection" Value="Ascending">
<Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
<Setter TargetName="SortArrow" Property="Text" Value="&#xf160;" />
</Trigger>
<Trigger Property="SortDirection" Value="Descending">
<Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
<Setter TargetName="SortArrow" Property="Text" Value="&#xf161;" />
</Trigger>
</ControlTemplate.Triggers>-->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="DataGridRow">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="DataGridRow">
<Grid >
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="Transparent"/>
<DataGridCellsPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="#00BCD4"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#00BCD4"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex"
Value="0">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex"
Value="1">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Foreground" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--TextBox样式-->
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border BorderThickness="1" Width="auto" Height="auto" BorderBrush="CadetBlue">
<Grid x:Name="grid" Background="Transparent">
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--RadioButton样式-->
</ResourceDictionary>

@ -0,0 +1,285 @@
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using MiniExcelLibs;
using NLog;
using SlnMesnac.RfidUpload.Business;
using SlnMesnac.RfidUpload.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
namespace SlnMesnac.RfidUpload.UI.viewModel
{
public class MainWindowViewModel : ViewModelBase
{
private readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly HandleBusiness _business = HandleBusiness.Instance;
private readonly SerialPortBusiness _serialPortBusiness = SerialPortBusiness.Instance;
private ObservableCollection<dynamic> listItems = new ObservableCollection<dynamic>();
private ObservableCollection<InstructionInfo> labelItems = new ObservableCollection<InstructionInfo>();
#region 参数定义
/// <summary>
/// 标签数量
/// </summary>
private int labelCountParam = 0;
public int LabelCountParam
{
get { return labelCountParam; }
set { labelCountParam = value;RaisePropertyChanged(() => LabelCountParam); }
}
private int rfidDeviceStatus = 0;
public int RfidDeviceStatus
{
get { return rfidDeviceStatus; }
set { rfidDeviceStatus = value; RaisePropertyChanged(nameof(RfidDeviceStatus)); }
}
/// <summary>
/// 日志打印ListBox
/// </summary>
private IEnumerable logInfoListBox;
public IEnumerable LogInfoListBox
{
get { return logInfoListBox; }
set { logInfoListBox = value; RaisePropertyChanged(() => LogInfoListBox); }
}
/// <summary>
/// 标签信息DataGrid
/// </summary>
private IEnumerable labelInfoDataGrid;
public IEnumerable LabelInfoDataGrid
{
get { return labelInfoDataGrid; }
set { labelInfoDataGrid = value; RaisePropertyChanged(() => LabelInfoDataGrid); }
}
#endregion
#region 事件定义
/// <summary>
/// 打开串口
/// </summary>
public RelayCommand OpenSerialPortCommand { get; set; }
/// <summary>
/// 关闭串口
/// </summary>
public RelayCommand CloseSerialPortCommand { get; set; }
/// <summary>
/// 导出文件
/// </summary>
public RelayCommand ExportFilesCommand { get; set; }
#endregion
/// <summary>
/// 清空列表
/// </summary>
public RelayCommand EmptyFilesCommand { get; set; }
public MainWindowViewModel()
{
logger.Info("初始化启动");
EmptyFilesCommand = new RelayCommand(EmptyFiles);
ExportFilesCommand = new RelayCommand(ExportFiles);
OpenSerialPortCommand = new RelayCommand(OpenSerialPort);
CloseSerialPortCommand = new RelayCommand(CloseSerialPort);
this.Init();
}
private void Init()
{
//加载标签信息
_business.InstructionInfoDataGridEvent += info =>
{
RefreshLabelInfoDataGrid(info);
};
//加载解析日志
_business.RefreshLogMessageEvent += message =>
{
logger.Info(message);
PrintMessageToListBox(message);
};
//接收串口数据
_serialPortBusiness.ReceivedDataEvent += buffer =>
{
//粘包数据处理
List<byte[]> dataPackages = _business.SplitPackets(buffer);
foreach (byte[] package in dataPackages)
{
_business.LabelHandle(package);
LabelCountParam += 1;
}
};
//加载串口通讯日志
_serialPortBusiness.RefreshLogMessageEvent += message =>
{
logger.Info(message);
PrintMessageToListBox(message);
};
}
/// <summary>
/// 打开串口通讯
/// </summary>
private void OpenSerialPort()
{
try
{
//LabelTest();
_serialPortBusiness.Open();
if (rfidDeviceStatus != 1)
{
RfidDeviceStatus = 1;
}
}
catch (Exception e)
{
PrintMessageToListBox($"串口通讯打开异常:{e.Message}");
}
}
/// <summary>
/// 关闭串口通讯
/// </summary>
private void CloseSerialPort()
{
try
{
_serialPortBusiness.Close();
if (rfidDeviceStatus != 2)
{
RfidDeviceStatus = 2;
}
}
catch (Exception e)
{
PrintMessageToListBox($"串口通讯关闭异常:{e.Message}");
}
}
/// <summary>
/// 导出文件
/// </summary>
private void ExportFiles()
{
try
{
var info = labelItems.ToList();
// 创建 SaveFileDialog 对象
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Excel文件 (*.xlsx)|*.xlsx|所有文件 (*.*)|*.*";
saveFileDialog.Title = "保存文件";
saveFileDialog.FileName = $"标签信息{DateTime.Now.Date:yyyy-MM-dd}.xlsx";
if (saveFileDialog.ShowDialog() == true)
{
string filePath = saveFileDialog.FileName;
MiniExcel.SaveAs(filePath, info);
PrintMessageToListBox($"标签数据导出成功:{filePath}");
}
}
catch(Exception ex)
{
PrintMessageToListBox($"标签数据导出异常:{ex.Message}");
logger.Error($"标签数据导出异常", ex);
}
}
/// <summary>
/// 清空标签信息列表
/// </summary>
private void EmptyFiles()
{
labelItems.Clear();
LabelCountParam = 0;
}
/// <summary>
/// 加载标签信息DataGrid
/// </summary>
/// <param name="labelInfos"></param>
private void RefreshLabelInfoDataGrid(InstructionInfo instructionInfo)
{
if (instructionInfo == null) return;
App.Current.Dispatcher.BeginInvoke((Action)(() =>
{
labelItems.Add(instructionInfo);
LabelInfoDataGrid = labelItems;
LabelCountParam += 1;
}));
}
/// <summary>
/// listBox绑定日志
/// </summary>
/// <param name="message"></param>
private void PrintMessageToListBox(string message)
{
lock (string.Empty)
{
try
{
listItems.Add($"{DateTime.Now.ToString("HH:mm:ss")}==>{message}");
LogInfoListBox = listItems.OrderByDescending(x => x);
}
catch (Exception ex)
{
logger.Error("日志数据绑定异常", ex);
}
}
}
/// <summary>
/// 标签解析测试
/// </summary>
private void LabelTest()
{
// 模拟接收到的粘包数据
byte[] receivedData = {
0xAA, 0x55, 0x00, 0x1F, 0x31, 0x03, 0x45, 0x32, 0x30, 0x30, 0x33, 0x30, 0x33, 0x32, 0x37, 0x38, 0x31, 0x30, 0x30, 0x31, 0x35, 0x30, 0x30, 0x35, 0x39, 0x30, 0x44, 0x35, 0x35, 0x36, 0x2C,
0xAA, 0x55, 0x00, 0x1F, 0x31, 0x03, 0x45, 0x32, 0x30, 0x30, 0x33, 0x30, 0x33, 0x32, 0x37, 0x38, 0x31, 0x30, 0x30, 0x31, 0x35, 0x30, 0x30, 0x35, 0x39, 0x30, 0x44, 0x35, 0x35, 0x36, 0x2C,
0xAA, 0x55, 0x00, 0x1F, 0x31, 0x03, 0x45, 0x32, 0x30, 0x30, 0x33, 0x30, 0x33, 0x32, 0x37, 0x38, 0x31, 0x30, 0x30, 0x31, 0x35, 0x30, 0x30, 0x35, 0x39, 0x30, 0x44, 0x35, 0x35, 0x36, 0x2C,
0xAA, 0x55, 0x00, 0x1F, 0x31, 0x03, 0x45, 0x32, 0x30, 0x30, 0x33, 0x30, 0x33, 0x32, 0x37, 0x38, 0x31, 0x30, 0x30, 0x31, 0x35, 0x30, 0x30, 0x35, 0x39, 0x30, 0x44, 0x35, 0x35, 0x36, 0x2C,
0xAA, 0x55, 0x00, 0x27, 0x31, 0x03, 0x46, 0x43, 0x31, 0x30, 0x30, 0x38, 0x32, 0x30, 0x32, 0x30, 0x30
};
//粘包数据的处理
List<byte[]> dataPackages = _business.SplitPackets(receivedData);
// 打印处理后的数据包
foreach (byte[] package in dataPackages)
{
_business.LabelHandle(package);
//LabelCountParam += 1;
}
}
}
}

@ -0,0 +1,61 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.34031.81
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.RfidUpload.Analysis", "SlnMesnac.RfidUpload.Analysis\SlnMesnac.RfidUpload.Analysis.csproj", "{774D0204-DA0E-4C3B-BD2B-E40657C8E895}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.RfidUpload.Model", "SlnMesnac.RfidUpload.Model\SlnMesnac.RfidUpload.Model.csproj", "{E387466F-73C3-42E4-A5BB-6E88225F73C3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.RfidUpload.Common", "SlnMesnac.RfidUpload.Common\SlnMesnac.RfidUpload.Common.csproj", "{B9C60040-62DC-4C88-AADA-C33C1900E54F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.RfidUpload.Business", "SlnMesnac.RfidUpload.Business\SlnMesnac.RfidUpload.Business.csproj", "{B71F1EAB-C9D3-407C-9B2A-968E18D6F03F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.RfidUpload.TouchSocket", "SlnMesnac.RfidUpload.TouchSocket\SlnMesnac.RfidUpload.TouchSocket.csproj", "{2ED3FBB5-DFE5-4557-B67B-3013F4E6649F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.RfidUpload.NLog", "SlnMesnac.RfidUpload.NLog\SlnMesnac.RfidUpload.NLog.csproj", "{6128090B-8F42-4F22-A27E-6F5FF6072D27}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.RfidUpload.UI", "SlnMesnac.RfidUpload.UI\SlnMesnac.RfidUpload.UI.csproj", "{600503B8-7174-4A34-A38F-F4CFFAA6764F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{774D0204-DA0E-4C3B-BD2B-E40657C8E895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{774D0204-DA0E-4C3B-BD2B-E40657C8E895}.Debug|Any CPU.Build.0 = Debug|Any CPU
{774D0204-DA0E-4C3B-BD2B-E40657C8E895}.Release|Any CPU.ActiveCfg = Release|Any CPU
{774D0204-DA0E-4C3B-BD2B-E40657C8E895}.Release|Any CPU.Build.0 = Release|Any CPU
{E387466F-73C3-42E4-A5BB-6E88225F73C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E387466F-73C3-42E4-A5BB-6E88225F73C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E387466F-73C3-42E4-A5BB-6E88225F73C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E387466F-73C3-42E4-A5BB-6E88225F73C3}.Release|Any CPU.Build.0 = Release|Any CPU
{B9C60040-62DC-4C88-AADA-C33C1900E54F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9C60040-62DC-4C88-AADA-C33C1900E54F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9C60040-62DC-4C88-AADA-C33C1900E54F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9C60040-62DC-4C88-AADA-C33C1900E54F}.Release|Any CPU.Build.0 = Release|Any CPU
{B71F1EAB-C9D3-407C-9B2A-968E18D6F03F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B71F1EAB-C9D3-407C-9B2A-968E18D6F03F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B71F1EAB-C9D3-407C-9B2A-968E18D6F03F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B71F1EAB-C9D3-407C-9B2A-968E18D6F03F}.Release|Any CPU.Build.0 = Release|Any CPU
{2ED3FBB5-DFE5-4557-B67B-3013F4E6649F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2ED3FBB5-DFE5-4557-B67B-3013F4E6649F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2ED3FBB5-DFE5-4557-B67B-3013F4E6649F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2ED3FBB5-DFE5-4557-B67B-3013F4E6649F}.Release|Any CPU.Build.0 = Release|Any CPU
{6128090B-8F42-4F22-A27E-6F5FF6072D27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6128090B-8F42-4F22-A27E-6F5FF6072D27}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6128090B-8F42-4F22-A27E-6F5FF6072D27}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6128090B-8F42-4F22-A27E-6F5FF6072D27}.Release|Any CPU.Build.0 = Release|Any CPU
{600503B8-7174-4A34-A38F-F4CFFAA6764F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{600503B8-7174-4A34-A38F-F4CFFAA6764F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{600503B8-7174-4A34-A38F-F4CFFAA6764F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{600503B8-7174-4A34-A38F-F4CFFAA6764F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E634670E-8F08-4B41-B9F5-4B2FF21EE441}
EndGlobalSection
EndGlobal
Loading…
Cancel
Save