change -人员登录页修改按钮互斥

main
frankiecao 1 year ago
commit 6959477a36

@ -38,15 +38,12 @@ namespace SlnMesnac.Business.@base
private readonly StringChange stringChange;
private readonly HIDMode hIDMode;
public BaseBusiness(List<PlcAbsractFactory> plcFactories, List<RfidAbsractFactory> rfidFactories, HIDMode hIDModes)
public BaseBusiness(List<PlcAbsractFactory> plcFactories, List<RfidAbsractFactory> rfidFactories)
{
_plcFactories = plcFactories;
_rfidFactories = rfidFactories;
//示例
//stringChange = stringChanges;
hIDMode = hIDModes;
}
/// <summary>

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Business.business
{
/// <summary>
/// 记录Rfid信息
/// </summary>
public class RecordRfidInfoBusniess
{
}
}

@ -1,14 +1,71 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using ConsoleApp;
using Microsoft.Extensions.DependencyInjection;
using SlnMesnac.Common;
namespace SlnMesnac.Business.business
{
/// <summary>
/// RFID打卡业务逻辑类
/// RFID打卡业务逻辑类
/// </summary>
public class RfidHandleBusniess
{
private readonly HidUtils _utils;
public RfidHandleBusniess(HidUtils utils)
{
this._utils = utils;
}
string staffInfo = "";
string tagInfoStr = "";
/// <summary>
/// 上班打卡
/// </summary>
public void CheckIn()
{
_utils.StartScan();
}
/// <summary>
/// 下班打卡
/// </summary>
public void CheckOut()
{
_utils.StartScan();
}
/// <summary>
/// 结束打卡
/// </summary>
public void CloseRfid()
{
_utils.StopScan();
}
///// <summary>
///// 获取标签信息
///// </summary>
//private void GetTagInfo()
//{
// utils.pushReceiveDataEvent += (bytes, str) =>
// {
// Console.WriteLine($"收到打卡信息:{str}");
// };
//}
///// <summary>
///// 获取员工信息
///// </summary>
//public string GetStaffInfo()
//{
// staffInfo = baseStaffInfoService.GetStaffByCardIdAsync(highRfid.GetTagInfo()).ToString();
// return staffInfo;
//}
}
}

@ -0,0 +1,262 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* T14-GEN3-7895
* ConsoleApp
* 156ff13b-84fd-4062-a001-afc6a5d185b2
*
* WenJY
*
* 2024-05-22 11:15:41
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace ConsoleApp
{
public class HIDInterface : IDisposable
{
public enum MessagesType
{
Message,
Error
}
public struct ReusltString
{
public bool Result;
public string message;
}
public struct HidDevice
{
public UInt16 vID;
public UInt16 pID;
public string serial;
}
HidDevice lowHidDevice = new HidDevice();
public delegate void DelegateDataReceived(object sender, byte[] data);
public DelegateDataReceived DataReceived;
public delegate void DelegateStatusConnected(object sender, bool isConnect);
public DelegateStatusConnected StatusConnected;
public bool bConnected = false;
public Hid oSp = new Hid();
private static HIDInterface m_oInstance;
public struct TagInfo
{
public string AntennaPort;
public string EPC;
}
public HIDInterface()
{
m_oInstance = this;
oSp.DataReceived = HidDataReceived;
oSp.DeviceRemoved = HidDeviceRemoved;
}
protected virtual void RaiseEventConnectedState(bool isConnect)
{
if (null != StatusConnected) StatusConnected(this, isConnect);
}
protected virtual void RaiseEventDataReceived(byte[] buf)
{
if (null != DataReceived) DataReceived(this, buf);
}
public void AutoConnect(HidDevice hidDevice)
{
lowHidDevice = hidDevice;
ContinueConnectFlag = true;
ReadWriteThread.DoWork += ReadWriteThread_DoWork;
ReadWriteThread.WorkerSupportsCancellation = true;
ReadWriteThread.RunWorkerAsync(); //Recommend performing USB read/write operations in a separate thread. Otherwise,
}
public void StopAutoConnect()
{
try
{
ContinueConnectFlag = false;
Dispose();
}
catch
{
}
}
~HIDInterface()
{
Dispose();
}
public bool Connect(HidDevice hidDevice)
{
ReusltString result = new ReusltString();
Hid.HID_RETURN hdrtn = oSp.OpenDevice(hidDevice.vID, hidDevice.pID, hidDevice.serial);
if (hdrtn == Hid.HID_RETURN.SUCCESS)
{
bConnected = true;
#region 消息通知
result.Result = true;
result.message = "Connect Success!";
RaiseEventConnectedState(result.Result);
#endregion
return true;
}
bConnected = false;
#region 消息通知
result.Result = false;
result.message = "Device Connect Error";
RaiseEventConnectedState(result.Result);
#endregion
return false;
}
public bool Send(byte[] byData)
{
byte[] sendtemp = new byte[byData.Length + 1];
sendtemp[0] = (byte)byData.Length;
Array.Copy(byData, 0, sendtemp, 1, byData.Length);
Hid.HID_RETURN hdrtn = oSp.Write(new report(0, sendtemp));
if (hdrtn != Hid.HID_RETURN.SUCCESS)
{
return false;
}
return true;
}
public bool Send(string strData)
{
//获得报文的编码字节
byte[] data = Encoding.Unicode.GetBytes(strData);
return Send(data);
}
public void DisConnect()
{
bConnected = false;
Thread.Sleep(200);
if (oSp != null)
{
oSp.CloseDevice();
}
}
void HidDeviceRemoved(object sender, EventArgs e)
{
bConnected = false;
#region 消息通知
ReusltString result = new ReusltString();
result.Result = false;
result.message = "Device Remove";
RaiseEventConnectedState(result.Result);
#endregion
if (oSp != null)
{
oSp.CloseDevice();
}
}
public void HidDataReceived(object sender, report e)
{
try
{
//第一个字节为数据长度因为Device 的HID数据固定长度为64字节取有效数据
byte[] buf = new byte[e.reportBuff[0]];
Array.Copy(e.reportBuff, 1, buf, 0, e.reportBuff[0]);
//推送数据
RaiseEventDataReceived(buf);
}
catch
{
#region 消息通知
ReusltString result = new ReusltString();
result.Result = false;
result.message = "Receive Error";
RaiseEventConnectedState(result.Result);
#endregion
}
}
public void Dispose()
{
try
{
this.DisConnect();
oSp.DataReceived -= HidDataReceived;
oSp.DeviceRemoved -= HidDeviceRemoved;
ReadWriteThread.DoWork -= ReadWriteThread_DoWork;
ReadWriteThread.CancelAsync();
ReadWriteThread.Dispose();
}
catch
{ }
}
Boolean ContinueConnectFlag = true;
private BackgroundWorker ReadWriteThread = new BackgroundWorker();
private void ReadWriteThread_DoWork(object sender, DoWorkEventArgs e)
{
while (ContinueConnectFlag)
{
try
{
if (!bConnected)
{
Connect(lowHidDevice);
}
Thread.Sleep(500);
}
catch { }
}
}
}
}

@ -1,42 +0,0 @@
using HighRFIDSendCardDemo;
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Common
{
public class HIDMode
{
public DeviceClass deviceClass = new DeviceClass();
public string ButtonText = "";
public HIDMode()
{
deviceClass.pushTagData = GetTag;
}
/// <summary>
/// 连接或断开打卡机
/// </summary>
public void ConnectRfidHid()
{
deviceClass.ConnectDevice();
}
/// <summary>
/// 断开打卡机
/// </summary>
public void DisconnectRfidHid()
{
deviceClass.Close();
}
/// <summary>
/// 获取标签
/// </summary>
public void GetTag(Tag tag)
{
string tagInfo = tag.ToString();
}
}
}

@ -0,0 +1,554 @@
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* T14-GEN3-7895
* ConsoleApp
* bda7394f-e114-4f8c-b573-8a6cecb7dcf7
*
* WenJY
*
* 2024-05-22 11:14:15
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace ConsoleApp
{
public class report : EventArgs
{
public readonly byte reportID;
public readonly byte[] reportBuff;
public report(byte id, byte[] arrayBuff)
{
reportID = id;
reportBuff = arrayBuff;
}
}
public class Hid : object
{
private IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private const int MAX_USB_DEVICES = 64;
private bool deviceOpened = false;
private FileStream hidDevice = null;
private IntPtr hHubDevice;
int outputReportLength;
public int OutputReportLength { get { return outputReportLength; } }
int inputReportLength;
public int InputReportLength { get { return inputReportLength; } }
/// <summary>
/// 打开指定信息的设备
/// </summary>
/// <param name="vID">设备的vID</param>
/// <param name="pID">设备的pID</param>
/// <param name="serial">设备的serial</param>
/// <returns></returns>
public HID_RETURN OpenDevice(UInt16 vID, UInt16 pID, string serial)
{
if (deviceOpened == false)
{
Guid hUSB = Guid.Empty;
HidD_GetHidGuid(ref hUSB);
List<string> deviceList = new List<string>();
GetHidDeviceList(ref deviceList);
if(deviceList.Count > 0)
{
foreach(string item in deviceList)
{
string deviceId = item.Replace("\\", "#");
string concatenatedPath = $"\\\\?\\{deviceId}#{hUSB.ToString("B").ToUpper()}";
IntPtr device = CreateFile(concatenatedPath,
DESIREDACCESS.GENERIC_READ | DESIREDACCESS.GENERIC_WRITE,
0,
0,
CREATIONDISPOSITION.OPEN_EXISTING,
FLAGSANDATTRIBUTES.FILE_FLAG_OVERLAPPED,
0);
if (device != INVALID_HANDLE_VALUE)
{
HIDD_ATTRIBUTES attributes;
IntPtr serialBuff = Marshal.AllocHGlobal(512);
HidD_GetAttributes(device, out attributes);
HidD_GetSerialNumberString(device, serialBuff, 512);
string deviceStr = Marshal.PtrToStringAuto(serialBuff);
Marshal.FreeHGlobal(serialBuff);
if (attributes.VendorID == vID && attributes.ProductID == pID && deviceStr.Contains(serial))
{
IntPtr preparseData;
HIDP_CAPS caps;
HidD_GetPreparsedData(device, out preparseData);
HidP_GetCaps(preparseData, out caps);
HidD_FreePreparsedData(preparseData);
outputReportLength = caps.OutputReportByteLength;
inputReportLength = caps.InputReportByteLength;
hidDevice = new FileStream(new SafeFileHandle(device, false), FileAccess.ReadWrite, inputReportLength, true);
deviceOpened = true;
BeginAsyncRead();
hHubDevice = device;
return HID_RETURN.SUCCESS;
}
}
}
}
return HID_RETURN.DEVICE_NOT_FIND;
}
else
return HID_RETURN.DEVICE_OPENED;
}
/// <summary>
/// 获取所有连接的hid的设备路径
/// </summary>
/// <returns>包含每个设备路径的字符串数组</returns>
public static void GetHidDeviceList(ref List<string> deviceList)
{
deviceList.Clear();
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity");
foreach (ManagementObject obj in searcher.Get())
{
deviceList.Add(obj["DeviceID"].ToString());
}
}
/// <summary>
/// 关闭打开的设备
/// </summary>
public void CloseDevice()
{
if (deviceOpened == true)
{
deviceOpened = false;
hidDevice.Close();
}
}
/// <summary>
/// 开始一次异步读
/// </summary>
private void BeginAsyncRead()
{
byte[] inputBuff = new byte[InputReportLength];
hidDevice.BeginRead(inputBuff, 0, InputReportLength, new AsyncCallback(ReadCompleted), inputBuff);
}
/// <summary>
/// 异步读取结束,发出有数据到达事件
/// </summary>
/// <param name="iResult">这里是输入报告的数组</param>
private void ReadCompleted(IAsyncResult iResult)
{
byte[] readBuff = (byte[])(iResult.AsyncState);
try
{
hidDevice.EndRead(iResult);//读取结束,如果读取错误就会产生一个异常
byte[] reportData = new byte[readBuff.Length - 1];
for (int i = 1; i < readBuff.Length; i++)
reportData[i - 1] = readBuff[i];
report e = new report(readBuff[0], reportData);
OnDataReceived(e); //发出数据到达消息
if (!deviceOpened) return;
BeginAsyncRead();//启动下一次读操作
}
catch //读写错误,设备已经被移除
{
//MyConsole.WriteLine("设备无法连接,请重新插入设备");
EventArgs ex = new EventArgs();
OnDeviceRemoved(ex);//发出设备移除消息
CloseDevice();
}
}
public delegate void DelegateDataReceived(object sender, report e);
//public event EventHandler<ConnectEventArg> StatusConnected;
public DelegateDataReceived DataReceived;
/// <summary>
/// 事件:数据到达,处理此事件以接收输入数据
/// </summary>
protected virtual void OnDataReceived(report e)
{
if (DataReceived != null) DataReceived(this, e);
}
/// <summary>
/// 事件:设备断开
/// </summary>
public delegate void DelegateStatusConnected(object sender, EventArgs e);
public DelegateStatusConnected DeviceRemoved;
protected virtual void OnDeviceRemoved(EventArgs e)
{
if (DeviceRemoved != null) DeviceRemoved(this, e);
}
/// <summary>
///
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public HID_RETURN Write(report r)
{
if (deviceOpened)
{
try
{
byte[] buffer = new byte[outputReportLength];
buffer[0] = r.reportID;
int maxBufferLength = 0;
if (r.reportBuff.Length < outputReportLength - 1)
maxBufferLength = r.reportBuff.Length;
else
maxBufferLength = outputReportLength - 1;
for (int i = 0; i < maxBufferLength; i++)
buffer[i + 1] = r.reportBuff[i];
hidDevice.Write(buffer, 0, OutputReportLength);
return HID_RETURN.SUCCESS;
}
catch
{
EventArgs ex = new EventArgs();
OnDeviceRemoved(ex);//发出设备移除消息
CloseDevice();
return HID_RETURN.NO_DEVICE_CONECTED;
}
}
return HID_RETURN.WRITE_FAILD;
}
#region<连接USB返回的结构体信息>
/// <summary>
/// 连接USB返回的结构体信息
/// </summary>
public enum HID_RETURN
{
SUCCESS = 0,
NO_DEVICE_CONECTED,
DEVICE_NOT_FIND,
DEVICE_OPENED,
WRITE_FAILD,
READ_FAILD
}
#endregion
// 以下是调用windows的API的函数
/// <summary>
/// The HidD_GetHidGuid routine returns the device interface GUID for HIDClass devices.
/// </summary>
/// <param name="HidGuid">a caller-allocated GUID buffer that the routine uses to return the device interface GUID for HIDClass devices.</param>
[DllImport("hid.dll")]
private static extern void HidD_GetHidGuid(ref Guid HidGuid);
/// <summary>
/// The SetupDiGetClassDevs function returns a handle to a device information set that contains requested device information elements for a local machine.
/// </summary>
/// <param name="ClassGuid">GUID for a device setup class or a device interface class. </param>
/// <param name="Enumerator">A pointer to a NULL-terminated string that supplies the name of a PnP enumerator or a PnP device instance identifier. </param>
/// <param name="HwndParent">A handle of the top-level window to be used for a user interface</param>
/// <param name="Flags">A variable that specifies control options that filter the device information elements that are added to the device information set. </param>
/// <returns>a handle to a device information set </returns>
[DllImport("setupapi.dll", SetLastError = true)]
private static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, uint Enumerator, IntPtr HwndParent, DIGCF Flags);
/// <summary>
/// The SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory.
/// </summary>
/// <param name="DeviceInfoSet">A handle to the device information set to delete.</param>
/// <returns>returns TRUE if it is successful. Otherwise, it returns FALSE </returns>
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern Boolean SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);
/// <summary>
/// The SetupDiEnumDeviceInterfaces function enumerates the device interfaces that are contained in a device information set.
/// </summary>
/// <param name="deviceInfoSet">A pointer to a device information set that contains the device interfaces for which to return information</param>
/// <param name="deviceInfoData">A pointer to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet</param>
/// <param name="interfaceClassGuid">a GUID that specifies the device interface class for the requested interface</param>
/// <param name="memberIndex">A zero-based index into the list of interfaces in the device information set</param>
/// <param name="deviceInterfaceData">a caller-allocated buffer that contains a completed SP_DEVICE_INTERFACE_DATA structure that identifies an interface that meets the search parameters</param>
/// <returns></returns>
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet, IntPtr deviceInfoData, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
/// <summary>
/// The SetupDiGetDeviceInterfaceDetail function returns details about a device interface.
/// </summary>
/// <param name="deviceInfoSet">A pointer to the device information set that contains the interface for which to retrieve details</param>
/// <param name="deviceInterfaceData">A pointer to an SP_DEVICE_INTERFACE_DATA structure that specifies the interface in DeviceInfoSet for which to retrieve details</param>
/// <param name="deviceInterfaceDetailData">A pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA structure to receive information about the specified interface</param>
/// <param name="deviceInterfaceDetailDataSize">The size of the DeviceInterfaceDetailData buffer</param>
/// <param name="requiredSize">A pointer to a variable that receives the required size of the DeviceInterfaceDetailData buffer</param>
/// <param name="deviceInfoData">A pointer buffer to receive information about the device that supports the requested interface</param>
/// <returns></returns>
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, IntPtr deviceInterfaceDetailData, int deviceInterfaceDetailDataSize, ref int requiredSize, SP_DEVINFO_DATA deviceInfoData);
/// <summary>
/// The HidD_GetAttributes routine returns the attributes of a specified top-level collection.
/// </summary>
/// <param name="HidDeviceObject">Specifies an open handle to a top-level collection</param>
/// <param name="Attributes">a caller-allocated HIDD_ATTRIBUTES structure that returns the attributes of the collection specified by HidDeviceObject</param>
/// <returns></returns>
[DllImport("hid.dll")]
private static extern Boolean HidD_GetAttributes(IntPtr hidDeviceObject, out HIDD_ATTRIBUTES attributes);
/// <summary>
/// The HidD_GetSerialNumberString routine returns the embedded string of a top-level collection that identifies the serial number of the collection's physical device.
/// </summary>
/// <param name="HidDeviceObject">Specifies an open handle to a top-level collection</param>
/// <param name="Buffer">a caller-allocated buffer that the routine uses to return the requested serial number string</param>
/// <param name="BufferLength">Specifies the length, in bytes, of a caller-allocated buffer provided at Buffer</param>
/// <returns></returns>
[DllImport("hid.dll")]
private static extern Boolean HidD_GetSerialNumberString(IntPtr hidDeviceObject, IntPtr buffer, int bufferLength);
/// <summary>
/// The HidD_GetPreparsedData routine returns a top-level collection's preparsed data.
/// </summary>
/// <param name="hidDeviceObject">Specifies an open handle to a top-level collection. </param>
/// <param name="PreparsedData">Pointer to the address of a routine-allocated buffer that contains a collection's preparsed data in a _HIDP_PREPARSED_DATA structure.</param>
/// <returns>HidD_GetPreparsedData returns TRUE if it succeeds; otherwise, it returns FALSE.</returns>
[DllImport("hid.dll")]
private static extern Boolean HidD_GetPreparsedData(IntPtr hidDeviceObject, out IntPtr PreparsedData);
[DllImport("hid.dll")]
private static extern Boolean HidD_FreePreparsedData(IntPtr PreparsedData);
[DllImport("hid.dll")]
private static extern uint HidP_GetCaps(IntPtr PreparsedData, out HIDP_CAPS Capabilities);
/// <summary>
/// This function creates, opens, or truncates a file, COM port, device, service, or console.
/// </summary>
/// <param name="fileName">a null-terminated string that specifies the name of the object</param>
/// <param name="desiredAccess">Type of access to the object</param>
/// <param name="shareMode">Share mode for object</param>
/// <param name="securityAttributes">Ignored; set to NULL</param>
/// <param name="creationDisposition">Action to take on files that exist, and which action to take when files do not exist</param>
/// <param name="flagsAndAttributes">File attributes and flags for the file</param>
/// <param name="templateFile">Ignored</param>
/// <returns>An open handle to the specified file indicates success</returns>
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateFile(string fileName, uint desiredAccess, uint shareMode, uint securityAttributes, uint creationDisposition, uint flagsAndAttributes, uint templateFile);
/// <summary>
/// This function closes an open object handle.
/// </summary>
/// <param name="hObject">Handle to an open object</param>
/// <returns></returns>
[DllImport("kernel32.dll")]
private static extern int CloseHandle(IntPtr hObject);
/// <summary>
/// This function reads data from a file, starting at the position indicated by the file pointer.
/// </summary>
/// <param name="file">Handle to the file to be read</param>
/// <param name="buffer">Pointer to the buffer that receives the data read from the file </param>
/// <param name="numberOfBytesToRead">Number of bytes to be read from the file</param>
/// <param name="numberOfBytesRead">Pointer to the number of bytes read</param>
/// <param name="lpOverlapped">Unsupported; set to NULL</param>
/// <returns></returns>
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern bool ReadFile(IntPtr file, byte[] buffer, uint numberOfBytesToRead, out uint numberOfBytesRead, IntPtr lpOverlapped);
/// <summary>
/// This function writes data to a file
/// </summary>
/// <param name="file">Handle to the file to be written to</param>
/// <param name="buffer">Pointer to the buffer containing the data to write to the file</param>
/// <param name="numberOfBytesToWrite">Number of bytes to write to the file</param>
/// <param name="numberOfBytesWritten">Pointer to the number of bytes written by this function call</param>
/// <param name="lpOverlapped">Unsupported; set to NULL</param>
/// <returns></returns>
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern bool WriteFile(IntPtr file, byte[] buffer, uint numberOfBytesToWrite, out uint numberOfBytesWritten, IntPtr lpOverlapped);
/// <summary>
/// Registers the device or type of device for which a window will receive notifications
/// </summary>
/// <param name="recipient">A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter</param>
/// <param name="notificationFilter">A pointer to a block of data that specifies the type of device for which notifications should be sent</param>
/// <param name="flags">A Flags that specify the handle type</param>
/// <returns>If the function succeeds, the return value is a device notification handle</returns>
[DllImport("User32.dll", SetLastError = true)]
private static extern IntPtr RegisterDeviceNotification(IntPtr recipient, IntPtr notificationFilter, int flags);
/// <summary>
/// Closes the specified device notification handle.
/// </summary>
/// <param name="handle">Device notification handle returned by the RegisterDeviceNotification function</param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnregisterDeviceNotification(IntPtr handle);
}
#region
/// <summary>
/// SP_DEVICE_INTERFACE_DATA structure defines a device interface in a device information set.
/// </summary>
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public Guid interfaceClassGuid;
public int flags;
public int reserved;
}
/// <summary>
/// SP_DEVICE_INTERFACE_DETAIL_DATA structure contains the path for a device interface.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
internal int cbSize;
internal short devicePath;
}
/// <summary>
/// SP_DEVINFO_DATA structure defines a device instance that is a member of a device information set.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINFO_DATA
{
public int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
public Guid classGuid = Guid.Empty; // temp
public int devInst = 0; // dumy
public int reserved = 0;
}
/// <summary>
/// Flags controlling what is included in the device information set built by SetupDiGetClassDevs
/// </summary>
public enum DIGCF
{
DIGCF_DEFAULT = 0x00000001, // only valid with DIGCF_DEVICEINTERFACE
DIGCF_PRESENT = 0x00000002,
DIGCF_ALLCLASSES = 0x00000004,
DIGCF_PROFILE = 0x00000008,
DIGCF_DEVICEINTERFACE = 0x00000010
}
/// <summary>
/// The HIDD_ATTRIBUTES structure contains vendor information about a HIDClass device
/// </summary>
public struct HIDD_ATTRIBUTES
{
public int Size;
public ushort VendorID;
public ushort ProductID;
public ushort VersionNumber;
}
public struct HIDP_CAPS
{
public ushort Usage;
public ushort UsagePage;
public ushort InputReportByteLength;
public ushort OutputReportByteLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public ushort[] Reserved;
public ushort NumberLinkCollectionNodes;
public ushort NumberInputButtonCaps;
public ushort NumberInputValueCaps;
public ushort NumberInputDataIndices;
public ushort NumberOutputButtonCaps;
public ushort NumberOutputValueCaps;
public ushort NumberOutputDataIndices;
public ushort NumberFeatureButtonCaps;
public ushort NumberFeatureValueCaps;
public ushort NumberFeatureDataIndices;
}
/// <summary>
/// Type of access to the object.
///</summary>
static class DESIREDACCESS
{
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint GENERIC_EXECUTE = 0x20000000;
public const uint GENERIC_ALL = 0x10000000;
}
/// <summary>
/// Action to take on files that exist, and which action to take when files do not exist.
/// </summary>
static class CREATIONDISPOSITION
{
public const uint CREATE_NEW = 1;
public const uint CREATE_ALWAYS = 2;
public const uint OPEN_EXISTING = 3;
public const uint OPEN_ALWAYS = 4;
public const uint TRUNCATE_EXISTING = 5;
}
/// <summary>
/// File attributes and flags for the file.
/// </summary>
static class FLAGSANDATTRIBUTES
{
public const uint FILE_FLAG_WRITE_THROUGH = 0x80000000;
public const uint FILE_FLAG_OVERLAPPED = 0x40000000;
public const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
public const uint FILE_FLAG_RANDOM_ACCESS = 0x10000000;
public const uint FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000;
public const uint FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
public const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
public const uint FILE_FLAG_POSIX_SEMANTICS = 0x01000000;
public const uint FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000;
public const uint FILE_FLAG_OPEN_NO_RECALL = 0x00100000;
public const uint FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000;
}
/// <summary>
/// Serves as a standard header for information related to a device event reported through the WM_DEVICECHANGE message.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_HDR
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
}
/// <summary>
/// Contains information about a class of devices
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
public Guid dbcc_classguid;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
public string dbcc_name;
}
#endregion
}

@ -0,0 +1,357 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* T14-GEN3-7895
* ConsoleApp
* 988d1fd9-7907-40bb-9147-51a2c953d9f8
*
* WenJY
*
* 2024-05-22 11:19:23
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace ConsoleApp
{
public class HidUtils
{
#region parameter Define
HIDInterface hid = new HIDInterface();
struct connectStatusStruct
{
public bool preStatus;
public bool curStatus;
}
connectStatusStruct connectStatus = new connectStatusStruct();
/// <summary>
/// 推送连接状态信息
/// </summary>
/// <param name="isConnected"></param>
public delegate void PushConnectedDelegate(bool isConnected);
public PushConnectedDelegate pushConnectedDelegateEvent;
/// <summary>
/// 推送接收数据信息
/// </summary>
/// <param name="datas"></param>
/// <param name="str"></param>
public delegate void PushReceiveDataDele(byte[] datas,string str);
public PushReceiveDataDele pushReceiveDataEvent;
/// <summary>
/// 推送设备状态修改
/// </summary>
/// <param name="isFlag"></param>
public delegate void PushDeviceStatusDelegate(bool isFlag);
public PushDeviceStatusDelegate pushDeviceStatusDelegateEvent;
/// <summary>
/// ReadBlock
/// </summary>
/// <param name="isConnected"></param>
public delegate void PushReadBlockDelegate(TagBlock tagBlock);
public PushReadBlockDelegate pushReadBlockDelegateEvent;
#endregion
public void Initial()
{
hid.StatusConnected = StatusConnected;
hid.DataReceived = DataReceived;
HIDInterface.HidDevice hidDevice = new HIDInterface.HidDevice();
hidDevice.vID = (ushort)1285;
hidDevice.pID = (ushort)20560;
hidDevice.serial = "";
hid.AutoConnect(hidDevice);
}
public void Close()
{
hid.StopAutoConnect();
}
public bool SendBytes(byte[] data)
{
return hid.Send(data);
}
public void StartScan()
{
byte[] array = new byte[12]
{
12, 87, 89, 8, 0, 0, 255, 255, 1, 0,
210, 15
};
ushort value = CalculateCRC(array);
byte[] bytes = BitConverter.GetBytes(value);
array[array.Length - 2] = bytes[0];
array[array.Length - 1] = bytes[1];
SendBytes(array);
}
public void StopScan()
{
byte[] array = new byte[12]
{
12, 87, 89, 8, 0, 0, 255, 255, 0, 0,
210, 15
};
ushort value = CalculateCRC(array);
byte[] bytes = BitConverter.GetBytes(value);
array[array.Length - 2] = bytes[0];
array[array.Length - 1] = bytes[1];
SendBytes(array);
}
public void ReadBlockData(string BlockAddr, string BlockNum)
{
byte[] data = Get_Order(0, 0, 16, 0, 36, new byte[10]
{
112,
105,
180,
242,
80,
1,
4,
224,
Convert.ToByte(BlockAddr, 16),
Convert.ToByte(BlockNum, 16)
});
SendBytes(data);
}
public void WriteBlock(string BlockAddr, string BlockNum, List<string> BlockList)
{
int num = int.Parse(BlockNum);
if (num / 2 > BlockList.Count)
{
Console.WriteLine( "输入数据有误!");
return;
}
int num2 = 10 + num * 2;
byte[] array = new byte[num2];
int num3 = 0;
array[num3++] = 138;
array[num3++] = 138;
array[num3++] = 186;
array[num3++] = 242;
array[num3++] = 80;
array[num3++] = 1;
array[num3++] = 4;
array[num3++] = 224;
array[num3++] = Convert.ToByte(BlockAddr, 16);
array[num3++] = Convert.ToByte(BlockNum, 16);
if (num % 2 != 0)
{
num++;
}
for (int i = 0; i < num / 2; i++)
{
string text = BlockList[i];
if (text.Length != 8 && text.Length != 4)
{
Console.WriteLine("长度不符合!");
return;
}
foreach (char c in text)
{
if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
{
Console.WriteLine("数据含有不合法字符!");
return;
}
}
for (int k = 0; k < text.Length / 2; k++)
{
array[num3++] = Convert.ToByte(text.Substring(k * 2, 2), 16);
}
}
byte[] data = Get_Order(0, 0, 1, 0, 37, array);
SendBytes(data);
}
public void DataReceived(object sender, byte[] bytes)
{
if (bytes[7] == 31 && (bytes[8] == 0 || bytes[8] == 1)) //修改设备返回信息
{
bool isFlag = false;
if (bytes[10] == 1 && bytes[11] == 1)
{
isFlag = false;
}
else
{
isFlag = true;
}
if (pushDeviceStatusDelegateEvent != null)
pushDeviceStatusDelegateEvent(isFlag);
}
if (bytes[7] == 31 && bytes[8] == 36)
{
TagBlock tagBlock = new TagBlock();
tagBlock.Block = new List<string>();
int num = 0;
int num2 = 0;
string text = "";
if (bytes[bytes.Length - 3] == 1 && bytes[bytes.Length - 4] == 1)
{
tagBlock.State = false;
return;
}
for (int i = 10; i < bytes.Length - 4; i++)
{
text += bytes[i].ToString("X2");
num2++;
if (num2 == 4)
{
tagBlock.Block.Add(text);
num++;
num2 = 0;
text = "";
}
}
if (text.Length > 0)
{
tagBlock.Block.Add(text);
num++;
num2 = 0;
text = "";
}
if (pushReadBlockDelegateEvent != null)
pushReadBlockDelegateEvent(tagBlock);
}
if (bytes[7] == 31 && bytes[8] == 37) //写入结果
{
bool isFlag = false;
if (bytes[10] == 1 && bytes[11] == 1)
{
isFlag = false;
}
else
{
isFlag = true;
}
}
if (bytes[7] == 31 && bytes[8] == 17)
{
string str = "";
for (int index = 10; index <= bytes.Length - 6; ++index)
{
str += bytes[index].ToString("X2");
if (index != bytes.Length - 6)
str += " ";
}
if (pushReceiveDataEvent != null)
pushReceiveDataEvent(bytes, str);
}
}
public void StatusConnected(object sender, bool isConnect)
{
connectStatus.curStatus = isConnect;
if (connectStatus.curStatus == connectStatus.preStatus) //connect
return;
connectStatus.preStatus = connectStatus.curStatus;
if (connectStatus.curStatus)
{
Console.WriteLine("连接成功");
}
else
{
Console.WriteLine("无法连接");
}
if (pushConnectedDelegateEvent != null)
pushConnectedDelegateEvent(connectStatus.curStatus);
}
private byte[] Get_Order(byte Source_Address_0, byte Source_Address_1, byte Destination_Address_0, byte Destination_Address_1, byte Type, byte[] data)
{
int num = 12 + data.Length;
byte[] array = new byte[num];
int num2 = 0;
array[num2++] = (byte)num;
array[num2++] = 87;
array[num2++] = 89;
array[num2++] = (byte)(num - 4);
array[num2++] = Source_Address_0;
array[num2++] = Source_Address_1;
array[num2++] = Destination_Address_0;
array[num2++] = Destination_Address_1;
array[num2++] = Type;
array[num2++] = 0;
for (int i = 0; i < data.Length; i++)
{
array[num2++] = data[i];
}
ushort value = CalculateCRC(array);
byte[] bytes = BitConverter.GetBytes(value);
array[num2++] = bytes[0];
array[num2++] = bytes[1];
return array;
}
private ushort CalculateCRC(byte[] data)
{
ushort num1 = ushort.MaxValue;
foreach (byte num2 in data)
{
num1 ^= (ushort)num2;
for (int index = 0; index < 8; ++index)
{
if (((int)num1 & 1) == 1)
num1 = (ushort)((int)num1 >> 1 ^ 33800);
else
num1 >>= 1;
}
}
return num1;
}
}
}

@ -8,11 +8,12 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="HighRFIDSendCardDLL">
<HintPath>C:\Users\Administrator\Desktop\信明橡塑\Tool For HID Mode_V1.0.0\Tool For HID Mode_V1.0.0\HighRFIDSendCardDLL.dll</HintPath>
<HintPath>C:\Users\Administrator\Desktop\信明橡塑\测试文件\ConsoleApp\Library\HighRFIDSendCardDLL.dll</HintPath>
</Reference>
</ItemGroup>

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* T14-GEN3-7895
* ConsoleApp
* 7c94ad53-5ae7-4c24-98b7-6b6296ccdbb4
*
* WenJY
*
* 2024-05-22 17:48:43
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace ConsoleApp
{
public class TagBlock
{
public List<string> Block { get; set; }
public bool State { get; set; }
}
}

@ -49,7 +49,7 @@ namespace SlnMesnac.Ioc
RegisterTypeTransient(builder, Assembly.LoadFrom("SlnMesnac.Rfid.dll"));
//注入通用类
RegisterType(builder, Assembly.LoadFrom("SlnMesnac.Common.dll"));
//RegisterType(builder, Assembly.LoadFrom("SlnMesnac.Common.dll"));
//注入MQTT
RegisterType(builder, Assembly.LoadFrom("SlnMesnac.Mqtt.dll"));

@ -0,0 +1,98 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace SlnMesnac.Model.domain
{
[SugarTable("base_staff_info"), TenantAttribute("mes")]
[DataContract(Name = "BaseStaffInfo 员工信息")]
#pragma warning disable CS8618
public class BaseStaffInfo
{
/// <summary>
///
/// </summary>
[SugarColumn(ColumnName = "obj_id", IsPrimaryKey = true)]
public int ObjId { get; set; }
/// <summary>
/// 员工id
/// </summary>
[SugarColumn(ColumnName = "staff_id")]
public string StaffId { get; set; }
/// <summary>
/// 员工名称
/// </summary>
[SugarColumn(ColumnName = "staff_name")]
public string StaffName { get; set; }
/// <summary>
/// 卡号1
/// </summary>
[SugarColumn(ColumnName = "card_id")]
public string CardId { get; set; }
/// <summary>
/// 班组编号
/// </summary>
[SugarColumn(ColumnName = "team_code")]
public string TeamCode { get; set; }
/// <summary>
/// 手机号
/// </summary>
[SugarColumn(ColumnName = "phone_number")]
public string PhoneNumber { get; set; }
/// <summary>
/// 用户性别
/// </summary>
[SugarColumn(ColumnName = "sex")]
public string Sex { get; set; }
/// <summary>
/// 卡密
/// </summary>
[SugarColumn(ColumnName = "pass_word")]
public string Password { get; set; }
/// <summary>
/// 删除标志
/// </summary>
[SugarColumn(ColumnName = "del_flag")]
public string DelFlag { get; set; }
/// <summary>
/// 创建者
/// </summary>
[SugarColumn(ColumnName = "create_by")]
public string CreateBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnName = "create_time")]
public string CreateTime { get; set; }
/// <summary>
/// 更新者
/// </summary>
[SugarColumn(ColumnName = "update_by")]
public string UpdateBy { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnName = "update_time")]
public string UpdateTime { get; set; }
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnName = "remark")]
public string Remark { get; set; }
}
}

@ -0,0 +1,116 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace SlnMesnac.Model.domain
{
[SugarTable("prod_plan_info"), TenantAttribute("mes")]
[DataContract(Name = "ProdPLanInfo 员工信息")]
public class ProdPLanInfo
{
/// <summary>
///
/// </summary>
[SugarColumn(ColumnName = "obj_id", IsPrimaryKey = true)]
public int ObjId { get; set; }
/// <summary>
/// 工单编号
/// </summary>
[SugarColumn(ColumnName = "plan_code")]
public string PlanCode { get; set; }
/// <summary>
/// ERP订单编号
/// </summary>
[SugarColumn(ColumnName = "order_code")]
public string StaffId { get; set; }
/// <summary>
/// 物料编号
/// </summary>
[SugarColumn(ColumnName = "material_code")]
public string MaterialCode { get; set; }
/// <summary>
/// 物料名称
/// </summary>
[SugarColumn(ColumnName = "material_name")]
public string MaterialName { get; set; }
/// <summary>
/// 计划工位
/// </summary>
[SugarColumn(ColumnName = "product_line_code")]
public string ProductLineCode { get; set; }
/// <summary>
/// 计划班组
/// </summary>
[SugarColumn(ColumnName = "team_code")]
public string TeamCode { get; set; }
/// <summary>
/// 计划数量
/// </summary>
[SugarColumn(ColumnName = "plan_amount")]
public string PlanAmount { get; set; }
/// <summary>
/// 完成数量
/// </summary>
[SugarColumn(ColumnName = "complete_amount")]
public string CompleteAmount { get; set; }
/// <summary>
/// 实际开始时间
/// </summary>
[SugarColumn(ColumnName = "begin_time")]
public string BeginTIme { get; set; }
/// <summary>
/// 实际完成时间
/// </summary>
[SugarColumn(ColumnName = "end_time")]
public string EndTime { get; set; }
/// <summary>
/// 完成标识
/// </summary>
[SugarColumn(ColumnName = "comp_flag")]
public string CompFlag { get; set; }
/// <summary>
/// 创建人
/// </summary>
[SugarColumn(ColumnName = "created_by")]
public string CreatedBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnName = "created_time")]
public string CreatedTime { get; set; }
/// <summary>
/// 更新人
/// </summary>
[SugarColumn(ColumnName = "updated_by")]
public string UpdatedBy { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnName = "updated_time")]
public string UpdatedTime { get; set; }
/// <summary>
/// 设备编号
/// </summary>
[SugarColumn(ColumnName = "device_code")]
public string DeviceCode { get; set; }
}
}

@ -0,0 +1,80 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace SlnMesnac.Model.domain
{
[SugarTable("record_staff_attendance"), TenantAttribute("mes")]
[DataContract(Name = "RecordStaffAttendance 记录员工打卡")]
public class RecordStaffAttendance
{
/// <summary>
///
/// </summary>
[SugarColumn(ColumnName = "obj_id", IsPrimaryKey = true)]
public int ObjId { get; set; }
/// <summary>
/// 员工id
/// </summary>
[SugarColumn(ColumnName = "staff_id")]
public string StaffId { get; set; }
/// <summary>
/// 打卡类型
/// </summary>
[SugarColumn(ColumnName = "attendance_type")]
public string AttendanceType { get; set; }
/// <summary>
/// 班组编号
/// </summary>
[SugarColumn(ColumnName = "team_code")]
public string TeamCode { get; set; }
/// <summary>
/// 班次
/// </summary>
[SugarColumn(ColumnName = "classes")]
public string Classes { get; set; }
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnName = "remark")]
public string Remark { get; set; }
/// <summary>
/// 是否标识
/// </summary>
[SugarColumn(ColumnName = "is_flag")]
public string IsFlag { get; set; }
/// <summary>
/// 创建人
/// </summary>
[SugarColumn(ColumnName = "created_by")]
public string CreatedBy { get; set; }
/// <summary>
/// 打卡时间
/// </summary>
[SugarColumn(ColumnName = "created_time")]
public string CreatedTime { get; set; }
/// <summary>
/// 更新人
/// </summary>
[SugarColumn(ColumnName = "updated_by")]
public string UpdatedBy { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnName = "updated_time")]
public string UpdatedTime { get; set; }
}
}

@ -0,0 +1,25 @@
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Repository.service
{
public interface IBaseStaffService : IBaseService<BaseStaffInfo>
{
/// <summary>
/// 获取所有员工信息
/// </summary>
/// <returns></returns>
List<BaseStaffInfo> GetStaffInfos();
/// <summary>
/// 通过卡号获取员工信息
/// </summary>
/// <param name="cardId"></param>
/// <returns></returns>
BaseStaffInfo GetStaffInfoByCardId(string cardId);
}
}

@ -0,0 +1,24 @@
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Repository.service
{
public interface IRecordStaffAttendanceService : IBaseService<RecordStaffAttendance>
{
/// <summary>
/// 获取记录员工打卡信息
/// </summary>
/// <returns></returns>
List<RecordStaffAttendance> GetRecordStaffAttendances();
/// <summary>
/// 验证添加用户信息,有一个错误时进行回滚
/// </summary>
/// <param name="recordStaffAttendances"></param>
/// <returns></returns>
bool InsertRecordStaffAttendance(List<RecordStaffAttendance> recordStaffAttendances);
}
}

@ -0,0 +1,55 @@
using Microsoft.Extensions.Logging;
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Repository.service.Impl
{
public class BaseStaffServiceImpl : BaseServiceImpl<BaseStaffInfo>, IBaseStaffService
{
private ILogger<BaseStaffServiceImpl> _logger;
public BaseStaffServiceImpl(Repository<BaseStaffInfo> repository, ILogger<BaseStaffServiceImpl> logger) : base(repository)
{
_logger = logger;
}
/// <summary>
/// 通过卡号获取员工信息
/// </summary>
/// <param name="cardId"></param>
/// <returns></returns>
public BaseStaffInfo GetStaffInfoByCardId(string cardId)
{
BaseStaffInfo staffInfo = null;
try
{
staffInfo = base._rep.GetFirst(x => x.CardId == cardId);
}
catch (Exception ex)
{
_logger.LogError($"根据卡号获取员工信息异常:{ex.Message}");
}
return staffInfo;
}
/// <summary>
/// 获取所有的员工信息
/// </summary>
/// <returns></returns>
public List<BaseStaffInfo> GetStaffInfos()
{
List<BaseStaffInfo> staffInfos = null;
try
{
staffInfos = base._rep.GetList();
}
catch (Exception ex)
{
_logger.LogError($"获取员工信息异常:{ex.Message}");
}
return staffInfos;
}
}
}

@ -0,0 +1,50 @@
using Microsoft.Extensions.Logging;
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Repository.service.Impl
{
public class RecordStaffAttendanceServiceImpl : BaseServiceImpl<RecordStaffAttendance>,IRecordStaffAttendanceService
{
private readonly ILogger<RecordStaffAttendance> _logger;
public RecordStaffAttendanceServiceImpl(Repository<RecordStaffAttendance> rep, ILogger<RecordStaffAttendance> logger) : base(rep)
{
_logger = logger;
}
public List<RecordStaffAttendance> GetRecordStaffAttendances()
{
List<RecordStaffAttendance> records = null;
try
{
records = base._rep.GetList();
}
catch (Exception ex)
{
_logger.LogError($"获取员工打卡信息异常{ex.Message}");
}
return records;
}
public bool InsertRecordStaffAttendance(List<RecordStaffAttendance> records)
{
bool result = false;
try
{
base._rep.AsTenant().BeginTran();
result = base._rep.InsertRange(records);
base._rep.AsTenant().CommitTran();
}
catch (Exception ex)
{
base._rep.AsTenant().RollbackTran();
_logger.LogError($"员工打卡信息添加异常:{ex.Message}");
}
return result;
}
}
}

@ -0,0 +1,17 @@
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Repository.service
{
public interface ProdPlanInfoService : IBaseService<ProdPLanInfo>
{
/// <summary>
/// 获取工单信息
/// </summary>
/// <returns></returns>
List<RecordStaffAttendance> GetRecordStaffAttendances();
}
}

@ -10,6 +10,8 @@ using Autofac.Extensions.DependencyInjection;
using SlnMesnac.Plc;
using System.Collections.Generic;
using SlnMesnac.Rfid;
using SlnMesnac.Common;
using ConsoleApp;
namespace SlnMesnac.WPF
{
@ -46,6 +48,13 @@ namespace SlnMesnac.WPF
var logPath = $"{appConfig.logPath}/Logs/{DateTime.UtcNow:yyyy-MM-dd}/";
Log.Information($"系统初始化完成,日志存放路径:{appConfig.logPath}");
var hidUtils = ServiceProvider.GetService<HidUtils>();
hidUtils.Initial();
hidUtils.pushReceiveDataEvent += (bytes, str) =>
{
Console.WriteLine($"收到打卡信息:{str}");
};
}
/// <summary>
@ -67,6 +76,10 @@ namespace SlnMesnac.WPF
{
base.OnExit(e);
var hidUtils = ServiceProvider.GetService<HidUtils>();
hidUtils.Close();
//hidUtils.StopScan();
Log.Information($"系统退出,当前时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
// 释放资源
// ...

@ -45,7 +45,7 @@
<ItemGroup>
<Reference Include="HighRFIDSendCardDLL">
<HintPath>C:\Users\Administrator\Desktop\信明橡塑\Tool For HID Mode_V1.0.0\Tool For HID Mode_V1.0.0\HighRFIDSendCardDLL.dll</HintPath>
<HintPath>C:\Users\Administrator\Desktop\信明橡塑\测试文件\ConsoleApp\Library\HighRFIDSendCardDLL.dll</HintPath>
</Reference>
</ItemGroup>

@ -12,6 +12,9 @@ using SlnMesnac.Rfid;
using SlnMesnac.Ioc;
using SlnMesnac.Plc;
using SlnMesnac.Extensions;
using SlnMesnac.Common;
using HighRFIDSendCardDemo;
using ConsoleApp;
namespace SlnMesnac.WPF
{
@ -45,6 +48,12 @@ namespace SlnMesnac.WPF
//注册RFID工厂
services.AddRfidFactorySetup();
services.AddSingleton<DeviceClass>();
//services.AddSingleton<HighRfid>();
services.AddSingleton<HidUtils>();
}
/// <summary>

@ -91,6 +91,7 @@
<Border.Effect>
<DropShadowEffect Color="#1254AB" Direction="270" BlurRadius="10" ShadowDepth="5" Opacity="0.5"/>
</Border.Effect>
<TextBlock Text="{Binding StaffInfo}" FontSize="20" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<Border Grid.Column="2">
<TextBlock Text="打卡状态" FontSize="20" FontWeight="Bold" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,20,0"/>
@ -114,10 +115,10 @@
<TextBlock Text="打卡类型" FontSize="20" FontWeight="Bold" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<Border Grid.Column="1">
<Button Content="上班打卡" x:Name="On" Command="{Binding CheckInCommand}" CommandParameter="{Binding Name,ElementName=On}" Style="{StaticResource BUTTON_AGREE}" FontSize="15" FontWeight="Bold" Background="#009999" BorderBrush="#FF36B5C1" Margin="40,10,40,10" Click="On_Click"/>
<Button Content="{Binding CheckInButtonText}" x:Name="On" Command="{Binding CheckInCommand}" Style="{StaticResource BUTTON_AGREE}" IsEnabled="{Binding IsCheckInButtonEnabled}" FontSize="15" FontWeight="Bold" Background="{Binding CheckInButtonColor}" BorderBrush="#FF36B5C1" Margin="40,10,40,10" Click="On_Click"/>
</Border>
<Border Grid.Column="2">
<Button Content="下班打卡" x:Name="Off" Command="{Binding ControlOnClickCommand}" CommandParameter="{Binding Name,ElementName=Off}" Style="{StaticResource BUTTON_AGREE}" FontSize="15" FontWeight="Bold" Background="#009999" BorderBrush="#FF36B5C1" Margin="40,10,40,10"/>
<Button Content="{Binding CheckOutButtonText}" x:Name="Off" Command="{Binding CheckOutCommand}" Style="{StaticResource BUTTON_AGREE}" IsEnabled="{Binding IsCheckOutButtonEnabled}" FontSize="15" FontWeight="Bold" Background="{Binding CheckOutButtonColor}" BorderBrush="#FF36B5C1" Margin="40,10,40,10"/>
</Border>
</Grid>
</Border>

@ -1,5 +1,4 @@
using HighRFIDSendCardDemo;
using SlnMesnac.Common;
using SlnMesnac.Common;
using SlnMesnac.WPF.ViewModel;
using System;
using System.Collections.Generic;
@ -25,20 +24,23 @@ namespace SlnMesnac.WPF.Page
/// </summary>
public partial class EmployeeLoginPage : UserControl
{
HIDMode hIDMode = new HIDMode();
DeviceClass deviceClass = new DeviceClass();
//HIDMode hIDMode = new HIDMode();
//DeviceClass deviceClass = new DeviceClass();
DispatcherTimer timer;
public EmployeeLoginPage()
{
InitializeComponent();
//timer = new DispatcherTimer();
//timer.Interval = TimeSpan.FromSeconds(5);
//timer.Tick += Timer_Tick;
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(5);
timer.Tick += Timer_Tick;
this.DataContext = new EmployeeLoginViewModel();
}
/// <summary>
/// 定时器
/// </summary>
@ -55,7 +57,5 @@ namespace SlnMesnac.WPF.Page
//hIDMode.ConnectRfidHid();
//timer.Start();
}
}
}

@ -2,51 +2,199 @@
using GalaSoft.MvvmLight.Command;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SlnMesnac.Business.business;
using SlnMesnac.Common;
using SlnMesnac.Repository.service;
using SlnMesnac.Repository.service.Impl;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace SlnMesnac.WPF.ViewModel
{
public class EmployeeLoginViewModel : ViewModelBase
public class EmployeeLoginViewModel : ViewModelBase,INotifyPropertyChanged
{
private readonly RfidHandleBusniess rfidHandle;
private readonly ILogger<EmployeeLoginViewModel> _logger;
public EmployeeLoginViewModel()
{
CheckInCommand = new RelayCommand(CheckIn);
}
private IBaseStaffService baseStaffService;
public string _isCheckInButtonEnabled;
private string _isCheckOutButtonEnabled;
private string _checkInButtonColor;
private string _checkOutButtonColor = "#009999";
/// <summary>
/// 获取标签信息
/// 按钮文字转换事件
/// </summary>
private void GetTagInfo()
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 上班命令
/// </summary>
public ICommand CheckInCommand { get; private set; }
/// <summary>
/// 下班命令
/// </summary>
public ICommand CheckOutCommand { get; private set; }
/// <summary>
/// 结束命令
/// </summary>
public ICommand OverCommand { get; private set; }
private string _checkInButtonText = "上班打卡";
private string _checkOutButtonText = "下班打卡";
/// <summary>
/// 上班打卡文本
/// </summary>
public string CheckInButtonText
{
get { return _checkInButtonText; }
set
{
_checkInButtonText = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CheckInButtonText)));
}
}
#region 事件定义
/// <summary>
/// 上班打卡
/// </summary>
public RelayCommand CheckInCommand { get; set; }
public string IsCheckInButtonEnabled
{
get { return _isCheckInButtonEnabled; }
set
{
_isCheckInButtonEnabled = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsCheckInButtonEnabled)));
}
}
/// <summary>
///下班打卡文本
/// </summary>
public string CheckOutButtonText
{
get { return _checkOutButtonText; }
set
{
_checkOutButtonText = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CheckOutButtonText)));
}
}
/// <summary>
/// 下班打卡
/// </summary>
public RelayCommand CheckOutCommand { get; set; }
#endregion
public void CheckIn()
public string IsCheckOutButtonEnabled
{
var str = "";
get { return _isCheckOutButtonEnabled; }
set
{
_isCheckOutButtonEnabled = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsCheckOutButtonEnabled)));
}
}
var hid = App.ServiceProvider.GetService<HIDMode>();
/// <summary>
/// 上班打卡按钮颜色
/// </summary>
public string CheckInButtonColor
{
get { return _checkInButtonColor; }
set
{
_checkInButtonColor = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CheckInButtonColor)));
}
}
hid.ConnectRfidHid();
/// <summary>
/// 下班打卡按钮颜色
/// </summary>
public string CheckOutButtonColor
{
get { return _checkOutButtonColor; }
set
{
_checkOutButtonColor = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CheckOutButtonColor)));
}
}
public EmployeeLoginViewModel()
{
CheckInCommand = new RelayCommand(CheckIn);
CheckOutCommand = new RelayCommand(CheckOut);
OverCommand = new RelayCommand(Over);
rfidHandle = App.ServiceProvider.GetService<RfidHandleBusniess>();
baseStaffService = App.ServiceProvider.GetService<IBaseStaffService>();
IsCheckInButtonEnabled = "True";
IsCheckOutButtonEnabled = "True";
CheckInButtonColor = "#009999";
CheckOutButtonColor = "#009999";
}
/// <summary>
/// 上班打卡事件
/// </summary>
private void CheckIn()
{
if (CheckInButtonText == "上班打卡")
{
// 执行上班打卡逻辑
CheckInButtonText = "结束打卡";
IsCheckOutButtonEnabled = "False"; // Disable CheckOutButton
CheckOutButtonColor = "Gray";
rfidHandle.CheckIn();
}
else
{
// 执行结束打卡逻辑
CheckInButtonText = "上班打卡";
IsCheckOutButtonEnabled = "True"; // Enable CheckOutButton
CheckOutButtonColor = "#009999";
rfidHandle.CloseRfid();
}
}
/// <summary>
/// 下班打卡事件
/// </summary>
private void CheckOut()
{
if (CheckOutButtonText == "下班打卡")
{
// 执行下班打卡逻辑
CheckOutButtonText = "结束打卡";
IsCheckInButtonEnabled = "False"; // Disable CheckInButton
//IsCheckOutButtonEnabled = "True";
CheckInButtonColor = "Gray";
rfidHandle.CheckOut();
}
else
{
// 执行结束打卡逻辑
CheckOutButtonText = "下班打卡";
IsCheckInButtonEnabled = "True"; // Enable CheckInButton
//IsCheckOutButtonEnabled="False";
CheckInButtonColor = "#009999";
rfidHandle.CloseRfid();
}
}
/// <summary>
/// 结束打卡事件
/// </summary>
private void Over()
{
// 执行结束打卡的逻辑
CheckInButtonText = "上班打卡";
CheckOutButtonText = "下班打卡";
}
}
}

@ -13,13 +13,13 @@
{
"configId": "mes",
"dbType": 1,
"connStr": "server=.;uid=sa;pwd=123456;database=JiangYinMENS"
},
{
"configId": "mcs",
"dbType": 3,
"connStr": "Data Source=175.27.215.92/helowin;User ID=aucma_scada;Password=aucma"
"connStr": "server=121.37.164.0;uid=sa;pwd=Yq123456;database=xmxs_os"
}
//{
// "configId": "mcs",
// "dbType": 3,
// "connStr": "Data Source=121.37.164.0/helowin;User ID=aucma_scada;Password=aucma"
//}
],
"PlcConfig": [
{

@ -33,9 +33,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Ioc", "SlnMesnac.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Generate", "SlnMesnac.Generate\SlnMesnac.Generate.csproj", "{00FC9358-2381-4C1B-BD45-6D31DD1DB7D3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Extensions", "SlnMesnac.Extensions\SlnMesnac.Extensions.csproj", "{6D929802-24AA-42A7-92C5-303C3D59A990}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Extensions", "SlnMesnac.Extensions\SlnMesnac.Extensions.csproj", "{6D929802-24AA-42A7-92C5-303C3D59A990}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Redis", "SlnMesnac.Redis\SlnMesnac.Redis.csproj", "{0E041719-E755-43CD-8A0E-DF62E0B2E463}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Redis", "SlnMesnac.Redis\SlnMesnac.Redis.csproj", "{0E041719-E755-43CD-8A0E-DF62E0B2E463}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "TestProject\TestProject.csproj", "{3B9521EC-E6B7-4372-B62B-848F9DC9EB04}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -111,6 +113,10 @@ Global
{0E041719-E755-43CD-8A0E-DF62E0B2E463}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E041719-E755-43CD-8A0E-DF62E0B2E463}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E041719-E755-43CD-8A0E-DF62E0B2E463}.Release|Any CPU.Build.0 = Release|Any CPU
{3B9521EC-E6B7-4372-B62B-848F9DC9EB04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B9521EC-E6B7-4372-B62B-848F9DC9EB04}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B9521EC-E6B7-4372-B62B-848F9DC9EB04}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B9521EC-E6B7-4372-B62B-848F9DC9EB04}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -0,0 +1 @@
global using NUnit.Framework;

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SlnMesnac.Common\SlnMesnac.Common.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,25 @@
using SlnMesnac.Common;
namespace TestProject
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
while (true)
{
Thread.Sleep(1000);
}
// Assert.Pass();
}
}
}
Loading…
Cancel
Save