unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls,StrUtils, Buttons, ExtCtrls, DateUtils;

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    Button1: TButton;
    GroupBox2: TGroupBox;
    Label13: TLabel;
    Label16: TLabel;
    edt_LockNo: TEdit;
    edt_Dai: TEdit;
    Label5: TLabel;
    Label9: TLabel;
    DateTimePicker1: TDateTimePicker;
    DateTimePicker2: TDateTimePicker;
    GroupBox3: TGroupBox;
    Label2: TLabel;
    Label3: TLabel;
    Label20: TLabel;
    Label10: TLabel;
    edt_coID: TEdit;
    Button3: TButton;
    Label8: TLabel;
    Label7: TLabel;
    GroupBox4: TGroupBox;
    BitBtn1: TBitBtn;
    BitBtn3: TBitBtn;
    BitBtn2: TBitBtn;
    BitBtn5: TBitBtn;
    BitBtn6: TBitBtn;
    edt_CardData: TEdit;
    Label17: TLabel;
    Label1: TLabel;
    cmdExit: TBitBtn;
    BitBtn7: TBitBtn;
    BitBtn8: TBitBtn;
    BitBtn9: TBitBtn;
    Label6: TLabel;
    Label14: TLabel;
    Label4: TLabel;
    Button2: TButton;
    procedure cmdExitClick(Sender: TObject);
    procedure BitBtn6Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn5Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure BitBtn3Click(Sender: TObject);
    procedure BitBtn7Click(Sender: TObject);
    procedure BitBtn8Click(Sender: TObject);
    procedure BitBtn9Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    function rdCard: Boolean;
  public
    { Public declarations }
  end;

var
  Form1:        TForm1;
  st:           Integer;
  bufCard:      Array[0..128] of char;

implementation

  //读DLL版本号
  function GetDLLVersion(sDllVer:PChar):Integer; stdcall;
    external 'proRFL.DLL';
  //打开USB
  function initializeUSB(fUSB: Byte): Integer; stdcall;
    external 'proRFL.DLL';
  //关闭proUSB
  procedure CloseUSB(fUSB: Byte); stdcall;
    external 'proRFL.DLL';
  //蜂鸣器
  function Buzzer(fUSB:Byte;t: Integer):Integer; stdcall;
    external 'proRFL.DLL';
  //读卡数据
  function ReadCard(fUSB:Byte;Buffer:PChar):Integer; stdcall;
    external 'proRFL.DLL';
  //读取57卡固有的ID号
  function ReadCardID_T5557(fUSB:Byte;Buffer:PChar):Integer; stdcall;
    external 'proRFL.DLL';
  //客人卡
  //int __stdcall GuestCard(uchar fUSB,int dlsCoID,uchar CardNo,uchar dai,uchar LLock,uchar pdoors,uchar BDate[10],uchar EDate[10],uchar RoomNo[8],uchar *cardHexStr)
  function GuestCard(fUSB:Byte;dlsCoID:Integer;CardNo,dai,llock,pdoors:Byte;BDate,EDate,RoomNo:Pchar;CardHexStr:PChar):Integer; stdcall;
    external 'proRFL.DLL';
  //挂失卡
  //int __stdcall LimitCard(uchar d12,int dlsCoID,uchar CardNo,uchar dai,uchar BDate[10],uchar LCardNo[4],uchar *cardHexStr)
  function LimitCard(fUSB:Byte;dlsCoID:Integer;CardNo,dai:Byte;BDate,LCardNo:Pchar;CardHexStr:PChar):Integer; stdcall;
    external 'proRFL.DLL';
  //注销卡片
  //int __stdcall CardErase(uchar fUSB,int dlsCoID,unsigned char *cardHexStr)
  function CardErase(fUSB:Byte;dlsCoID:Integer;cardHexStr:PChar):Integer; stdcall;
    external 'proRFL.DLL';
  //HEX-ASC
  //__int16 __stdcall hex_a(unsigned char *hex,unsigned char *a,__int16 len)
  function hex_a(hex,asc:PChar;hLen:Integer):Integer; stdcall;
    external 'proRFL.DLL';
  //ASC-HEX
  //__int16 __stdcall a_hex(unsigned char *a,unsigned char *hex,__int16 len)
  function a_hex(asc,hex:PChar;aLen:Integer):Integer; stdcall;
    external 'proRFL.DLL';

  //读取卡片类型
  //int __stdcall GetCardTypeByCardDataStr(unsigned char *CardDataStr,unsigned char *CardType)
  function GetCardTypeByCardDataStr(cardHexStr,CardType:PChar):Integer; stdcall;
    external 'proRFL.DLL';

  //读取客人卡锁号
  //int __stdcall GetGuestLockNoByCardDataStr(int dlsCoID,unsigned char *CardDataStr,unsigned char *LockNo)
  function GetGuestLockNoByCardDataStr(dlsCoID: Integer;cardHexStr,LockNo:PChar):Integer; stdcall;
    external 'proRFL.DLL';

  //读取客人离店时间
  //int __stdcall GetGuestETimeByCardDataStr(int dlsCoID,unsigned char *CardDataStr,unsigned char *eTime)
  function GetGuestETimeByCardDataStr(dlsCoID: Integer;cardHexStr,eTime:PChar):Integer; stdcall;
    external 'proRFL.DLL';

  //读取开门记录
  //int __stdcall ReadRecord(uchar d12,unsigned char *buffData)
  function ReadRecord(fUSB:Byte;bufData:PChar):Integer; stdcall;
    external 'proRFL.DLL';

  //根据记录仪数据解析开门记录
  //int __stdcall GetOpenRecordByDataStr(unsigned char *DataStr,unsigned char *sOpen)
  function GetOpenRecordByDataStr(DataStr,sOpen:PChar):Integer; stdcall;
    external 'proRFL.DLL';

{$R *.dfm}

//读卡,有错误提示
//同时返回当前卡的ID（卡类型、卡号、发卡时间）--copy(bufCard,25,8)
function TForm1.rdCard: Boolean;
var
  st:  Integer;
Label
  Exit_rdCard;
begin
  Result:=False;
  Screen.Cursor:=crHourGlass;
  st:=ReadCard(1,bufCard);
  if st<>0 then begin
    if st=1 then
      Application.MessageBox(PCHAR('请放一张卡在发卡器上面，'
                                   +#10+'确保 门锁软件 可以正常发卡，然后调试接口'
                                   +#10+bufCard
                                   ),'读卡失败（返回值=1）'
                                   ,MB_OK+MB_ICONERROR)
    else
      Application.MessageBox(PCHAR('读卡失败'+#10+IntToStr(st)),'提示',MB_OK+MB_ICONERROR);
    goto Exit_rdCard;
  end;
  if copy(bufCard,5,2)<>'01' then begin
    Application.MessageBox(PCHAR('发卡器的感应区无卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING);
    goto Exit_rdCard;
  end;
  Result:=True;
Exit_rdCard:
  Screen.Cursor:=crDefault;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  DateTimePicker1.DateTime:=Now+1;
end;

procedure TForm1.cmdExitClick(Sender: TObject);
begin
  Close;
end;

//读DLL版本号
procedure TForm1.BitBtn6Click(Sender: TObject);
var
  st:     Integer;
  sa1:    Array[0..256] of char;
begin
  st:=GetDLLVersion(sa1);
  if st=0 then
    Application.MessageBox(Pchar('DLL版本号：'+StrPas(sa1)),'提示',MB_OK+MB_ICONINFORMATION);
end;

//打开USB
procedure TForm1.Button1Click(Sender: TObject);
var
  st:   Integer;
begin
  st:=initializeUSB(1);
  if st<>0 then
    Application.MessageBox(Pchar('打开USB失败'+#10+IntToStr(st)),'提示',MB_OK+MB_ICONWARNING)
  else begin
    Application.MessageBox('打开USB成功','提示',MB_OK+MB_ICONINFORMATION);
    Button3.Enabled:=True;
    GroupBox4.Enabled:=True;
  end;
end;

//蜂鸣器
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  Buzzer(1,50);   //发卡器鸣叫50x10毫秒
end;

//注销卡片
procedure TForm1.BitBtn5Click(Sender: TObject);
var
  st:     Integer;
  sa1:    Array[0..256] of char;
begin
  if not rdCard then Exit;   //先读卡
  Screen.Cursor:=crHourGlass;
  st:=CardErase(1,StrToIntDef(edt_coID.Text,0),sa1);
  edt_CardData.Text:=StrPas(sa1);
  Screen.Cursor:=crDefault;
  if st<>0 then
    Application.MessageBox(Pchar('注销失败'+#10+IntToStr(st)),'提示',MB_OK+MB_ICONWARNING)
  else begin
    Application.MessageBox('注销成功','提示',MB_OK+MB_ICONINFORMATION);
  end;
end;

//从现有卡片读取酒店标识
procedure TForm1.Button3Click(Sender: TObject);
var
  i:   Integer;
  s:   String;
begin
  if not rdCard then Exit;   //先读卡
  edt_CardData.Text:=StrPas(bufCard);
  if copy(bufCard,25,8)='FFFFFFFF' then begin
    edt_coID.Text:='';
    Application.MessageBox('此卡是空白卡，请换一张能开门的卡','提示',MB_OK+MB_ICONWARNING);
    Exit;
  end;
  s:=copy(bufCard,11,4);
  i:=StrToInt('$'+s) mod 16384;
  s:=copy(bufCard,9,2);
  i:=i+(StrToInt('$'+s) * 65536);
  edt_coID.Text:=IntToStr(i);
end;

//读卡
procedure TForm1.BitBtn3Click(Sender: TObject);
begin
  if not rdCard then Exit;   //读卡
  edt_CardData.Text:=StrPas(bufCard);
  if (copy(bufCard,77,4)='0400')
    OR (copy(bufCard,77,4)='0200') then
    Application.MessageBox(Pchar('发卡流水号：'+copy(bufCard,25,8)
                                 +#10+'M1卡的固有ID号：'+copy(bufCard,77,12)
                                 +#10+'白色框是完整卡数据'
                                 ),'提示',MB_OK+MB_ICONINFORMATION)
  else
    Application.MessageBox(Pchar('发卡流水号：'+copy(bufCard,25,8)
                                  +#10+'白色框是完整卡数据'
                                  ),'提示',MB_OK+MB_ICONINFORMATION);
end;

procedure TForm1.BitBtn7Click(Sender: TObject);
var
  CardType:      Array[0..32] of char;
begin
  if not rdCard then Exit;   //先读卡
  edt_CardData.Text:=StrPas(bufCard);
  st:=GetCardTypeByCardDataStr(pChar(edt_CardData.Text),CardType);
  if st<>0 then
    Application.MessageBox(Pchar(('卡数据串无效：'+IntToStr(st))),'提示',MB_OK+MB_ICONWARNING)
  else
    if CardType[0]='0' then
      Application.MessageBox('授权卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='1' then
      Application.MessageBox('记录卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='2' then
      Application.MessageBox('房号设置卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='3' then
      Application.MessageBox('时间设置卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='4' then
      Application.MessageBox('限制卡[挂失卡]','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='5' then
      Application.MessageBox('组号设置卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='6' then
      Application.MessageBox('客人卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='7' then
      Application.MessageBox('退房卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='8' then
      Application.MessageBox('组控卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='9' then
      Application.MessageBox('未知卡[无此类型]','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='A' then
      Application.MessageBox('应急卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='B' then
      Application.MessageBox('总控卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='C' then
      Application.MessageBox('楼栋卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='D' then
      Application.MessageBox('楼层卡','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='E' then
      Application.MessageBox('未知卡[无此类型]','提示',MB_OK+MB_ICONINFORMATION)
    else if CardType[0]='F' then
      Application.MessageBox('空白卡','提示',MB_OK+MB_ICONINFORMATION);
end;

procedure TForm1.BitBtn8Click(Sender: TObject);
var
  LockNo:      Array[0..32] of char;
begin
  if not rdCard then Exit;   //先读卡
  edt_CardData.Text:=StrPas(bufCard);
  st:=GetGuestLockNoByCardDataStr(StrToIntDef(edt_coID.Text,0),pChar(edt_CardData.Text),LockNo);
  if st=0 then
    Application.MessageBox(PChar('锁号:'+#10+LockNo),'提示',MB_OK+MB_ICONINFORMATION)
  else if st=1 then
    Application.MessageBox(PChar('卡数据串无效'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else if st=2 then
    Application.MessageBox(Pchar('非本酒店卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else if st=3 then
    Application.MessageBox(Pchar('不是客人卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else
    Application.MessageBox(Pchar('未知返回值'+#10+IntToStr(st)+#10+bufCard),'提示',MB_OK+MB_ICONWARNING);
end;

procedure TForm1.BitBtn9Click(Sender: TObject);
var
  ETime:      Array[0..32] of char;
begin
  if not rdCard then Exit;   //先读卡
  edt_CardData.Text:=StrPas(bufCard);

  if copy(bufCard,25,1)<>'6' then begin
    Application.MessageBox(Pchar('不是客人卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING);
    Exit;
  end;

  st:=GetGuestETimeByCardDataStr(StrToIntDef(edt_coID.Text,0),pChar(edt_CardData.Text),ETime);
  if st=0 then
    Application.MessageBox(PChar('离店时间:'+#10+ETime
                            +#10+copy(ETime,1,2)+'年'
                                +copy(ETime,3,2)+'月'
                                +copy(ETime,5,2)+'日  '
                                +copy(ETime,7,2)+':'
                                +copy(ETime,9,2)
          ),'提示',MB_OK+MB_ICONINFORMATION)
  else if st=1 then
    Application.MessageBox(PChar('卡数据串无效'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else if st=2 then
    Application.MessageBox(Pchar('非本酒店卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else if st=3 then
    Application.MessageBox(Pchar('不是客人卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else
    Application.MessageBox(Pchar('未知返回值'+#10+IntToStr(st)+#10+bufCard),'提示',MB_OK+MB_ICONWARNING);
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
var
  st:            Integer;
  llock:         Byte;
  sa1:           Array[0..256] of char;
begin
  if not rdCard then Exit;   //先读卡
  //退房时间
  DateTimePicker1.Time:=DateTimePicker2.Time;
  Screen.Cursor:=crHourGlass;
  st:=GuestCard(1,
                StrToIntDef(edt_coID.Text,0),    //酒店标识
                0,
                StrToIntDef(edt_Dai.Text,0) mod 256,     //DAI
                0,0,
                PCHAR(FormatDateTime('YYMMDDHHMM',Now())),   //发卡时间
                PCHAR(FormatDateTime('YYMMDDHHMM',DateTimePicker1.DateTime)),  //退房时间
                PCHAR(edt_LockNo.Text),      //锁号
                sa1);                        //返回 卡数据
  edt_CardData.Text:=StrPas(sa1);
  Screen.Cursor:=crDefault;
  if st<>0 then
    Application.MessageBox(Pchar('调用发卡函数失败'+#10+IntToStr(st)),'提示',MB_OK+MB_ICONWARNING)
  else begin
    Application.MessageBox('制卡后，请调用读卡函数，数据一致才是真正的制卡成功！','调用发卡函数成功',MB_OK+MB_ICONINFORMATION);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  ETime:      Array[0..32] of char;
  sss:        String;
begin
  if not rdCard then Exit;   //先读卡
  edt_CardData.Text:=StrPas(bufCard);

  if copy(bufCard,25,1)<>'6' then begin
    Application.MessageBox(Pchar('不是客人卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING);
    Exit;
  end;

  sss:=copy(edt_CardData.Text,1,32)+copy(edt_CardData.Text,27,6);  //把发卡时间 放到 退房时间
  st:=GetGuestETimeByCardDataStr(StrToIntDef(edt_coID.Text,0),pChar(sss),ETime);
  if st=0 then
    Application.MessageBox(PChar('发卡时间:'+#10+ETime
                            +#10+copy(ETime,1,2)+'年'
                                +copy(ETime,3,2)+'月'
                                +copy(ETime,5,2)+'日  '
                                +copy(ETime,7,2)+':'
                                +copy(ETime,9,2)
          ),'提示',MB_OK+MB_ICONINFORMATION)
  else if st=1 then
    Application.MessageBox(PChar('卡数据串无效'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else if st=2 then
    Application.MessageBox(Pchar('非本酒店卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else if st=3 then
    Application.MessageBox(Pchar('不是客人卡'+#10+bufCard),'提示',MB_OK+MB_ICONWARNING)
  else
    Application.MessageBox(Pchar('未知返回值'+#10+IntToStr(st)+#10+bufCard),'提示',MB_OK+MB_ICONWARNING);
end;

end.


