⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umulticat.pas

📁 一个队列的类,可以方便的进行队列的添加,删除,查询功能!
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit uMultiCat;

interface

uses
  ShouYan_SmsGate61_TLB,  Contnrs, uQueue, ThreadedTime, DBTables,Classes, uPubUnit;

{$DEFINE _RUN}

type

  //交费信息记录
  TPayInfo = record
    UserID:    string;
    Task:      string;
    TaskStatus: integer;  //任务状态  成功=0,处理=1,失败=-1
    PaymentID:  integer;  //交费记录号
    PhoneCode: string;
    Amt:       string;
    MsgCatID:  integer;  //对应短信猫的ID,1、2、...8
    CZML:      string;   //冲值命令KZCZ.....
    ServiceID: Integer;  //服务商序号。
  end;

  //返回消息
  TRetMsg = record
    ID:   Integer;  //消息ID
    Msg:  string[200];   //消息
    ReceiveTime:   TDateTime;  //消息日期
    ProcessID  :   Integer;    //处理设备ID(CatID)
    ProcessStatus: integer;    //处理的状态 0=未处理;1=处理过
  end;

  TCatParam = record
    Enable:      Boolean; //是否启用。
    ComSeting:   string;  //串口设置
    ComPort:     integer;  //串口端口
    ServiceCode: string;  //服务商(8613800290500)
    SPCode:      string;  //空中冲值中心号码
    SPPws:       string;  //空中冲值中心密码
    CZML:        string;  //冲值命令
  end;

  TMsgCat = class(TThread)
  private
    MsgCatID: Integer;      //短信猫的ID,1、2、...8
    FQuery: TQuery;
    Status: Integer;        //短信猫状态。0:空闲;1:发送中,-1:不可用
    FMsg: string;     //为了在主线程执行,给客户端发送的信息
    FUserID: string;
    Client : TSimpleClient;
    procedure SendMsgToClient();
  public
    SPCode:     WideString; //空中冲值中心号码
    SPPws:      string;     //空中冲值密码
    ServiceCode:string;     //服务商短信号码
    CZML:       string;     //冲值命令
    FReady:     Boolean;    //设备就绪
    FConnected: Boolean;    //设备连接成功
    FEnable:   Boolean;     //是否启用
    PayInfo:   TPayInfo;    //缴费记录

  protected
    MsgCat: TSmsgate;
    constructor Create;
    destructor Destroy;
    function Connect(Port:Word; Setints, sServiceCode:string; iMsgCatID:Integer): Boolean;
    function Disconnect(): Boolean;  //断开短信猫
    //procedure OnRecvMsg(Sender: TObject);//收到消息的处理。
    function SendMsg(Command: WideString; UserPhoneCode,Amt: string): Boolean;
    procedure Execute; override;   //执行发送短信
  published
    property Enable: Boolean read FEnable write FEnable;
    property Connected: Boolean read FConnected;
    property Ready: Boolean read FReady;
    property cat: TSmsgate  read MsgCat; //测试,测完就删除
  end;


  TManageMsgCat = class
  private
    FMsgCats: array[1..8] of TMsgCat;
    FQueryArr: array[1..8] of TQuery;     //负责处理读写数据库的功能

    FCount: integer;   //连接正常猫的数量
    FTaskCount:  Integer;  //任务数
    FRetMsgcount: Integer; //返回消息数
    FTasking:  Boolean;          //任务执行中
    FTaskStutas: Integer;    //任务执行状态。 0=空闲,1=执行中,2=暂停中
    //FthrTime: TThreadedTimer;  //多线程定时器
    function GetMsgCat(index: Integer):TMsgCat;
    function GetMsgCatID(PortID:  integer): integer;  //根据串口端口号返回短信猫ID  找不到返回-1
    //procedure thrTimeTimer(Sender: TObject);
  protected

  public
    FTaskQueue: TFFQueue;     //任务队列。
    FRetMsgQueue: TFFQueue;  //返回信息队列。

    procedure RecvMsgs(Sender: TObject);    //接收消息处理函数,吧消息添加到消息队列里。

    constructor Create();   //
    destructor  Destroy;    //
    function  SetCat(CatID: Integer; aCatParam: TCatParam):Boolean;  //设置猫。(启用/停止)
    procedure ExecuteSendMsgs(Sender: TObject);    //执行发送任务
    procedure ExecuteReceiveMsgs;  //执行接收消息任务
    procedure ClearTask;           //清除发送任务
    procedure PauseTask;           //暂停
    procedure StartTask;           //启动任务
    property MsgCats[index: integer]: TMsgCat read GetMsgCat;
    property RetMsgcount: Integer read FRetMsgcount;    //队列中消息数
    property TaskCount: Integer read FTaskCount;        //队列中任务数

  published

  end;


implementation
uses
  SysUtils, DM, uDBOperate, Dialogs, frmServerMain, IdTCPServer;




{ TMsgCat }

function TMsgCat.Connect(Port:Word; Setints, sServiceCode:string;
  iMsgCatID:Integer): Boolean;
var
  i: SmallInt;
  ret: string;
begin
  try
    MsgCat.CommPort := Port;
    MsgCat.Settings := Setints;
    ServiceCode := sServiceCode;
    MsgCatID := iMsgCatID;
    
    i:=1;
    {$IFDEF _TEST}  //为了测试进行的操作
    FConnected := True;
    FReady := True;
    result := true;
    {$ENDIF}

    {$IFDEF _RUN}  //正式运行版
    ret := MsgCat.Connect(i);
    if ret = 'y' then
    begin
      FConnected := True;
      MsgCat.RevAuto;
      FReady := True;
      result := true;
    end
    else
    begin
      FConnected := False;
      MsgCat.RevAutoClose;
      FReady := False;
      result := False;
    end;
    {$ENDIF}
  except
    FConnected := false;
    FReady := False;
  end;
end;

constructor TMsgCat.Create;
begin
  inherited Create(True);
  FConnected := false;
  FReady := False;
  MsgCat := TSmsgate.Create(nil);
  //MsgCat.OnRecvMsg := RecvMsgs;
  Suspended := True;   //线程挂起
  FQuery := TQuery.Create(nil);
  FQuery.DatabaseName := 'CSSZY';
  FreeOnTerminate := false;
end;

destructor TMsgCat.Destroy;
begin
  FConnected := false;
  FReady := False;
  if MsgCat <> nil then
    MsgCat.Free;
  if FQuery <> nil then
    FQuery.Free;
  inherited;
end;

function TMsgCat.Disconnect: Boolean;
begin
  if FConnected then
  begin
    try
      MsgCat.ClosePort;
      FConnected := False;
      FReady := false;
      Result := True;
    except
      Result := False;
    end;
  end
  else
    Result := False;
end;

procedure TMsgCat.Execute;
var
  i: integer;
  aPayInfo: TPayInfo;
  ret: Boolean;
  Balance,Amt,ServiceID, k: Integer;
  Msg: string;
begin
  inherited;
  if Status = 0 then
  begin
    try
      Status := 1;  //短信发送中
      if Enable then
      begin
        if Ready then
        begin
          FReady := false;
          PayInfo.MsgCatID := MsgCatID;     //处理时登记短信猫ID,默认是-1.
          if SendMsg(PayInfo.CZML, PayInfo.PhoneCode,PayInfo.Amt) then
            ret := True//成功后,记录数据库信息。
          else
            ret := false;
          if ret then
          begin
            if not aPhoneCost.AddBalance(PayInfo.UserID, -StrToInt(PayInfo.Amt)) then  //扣除用户话费
            begin
              ShowMessage('缴费失败!更新数据库出错');
              exit;
            end;
            Balance:= round(aPhoneCost.GetBalance(PayInfo.UserID));//交费后的余额
            FQuery.Close;
            FQuery.SQL.Clear;
            FQuery.SQL.Add('insert into PaymentLOG (UserID,PhoneCode,Amt,PostTime,'
              +'Task,TaskStatus,TaskTime,SuccessTime,ProcessID,PaymentID,ServiceID)') ;
            FQuery.SQL.Add(' values (:UserID,:PhoneCode,:amt,:PostTime,:Task,:TaskStatus,:TaskTime,:SuccessTime,:ProcessID,:PaymentID,:ServiceID)');
            FQuery.ParamByName('UserID').AsString:=PayInfo.UserID;      //用户名
            FQuery.ParamByName('PhoneCode').AsString:=PayInfo.PhoneCode; //缴费号码
            FQuery.ParamByName('Amt').AsFloat:=StrToFloat(PayInfo.Amt);
            FQuery.ParamByName('PostTime').AsDateTime:=now;
            FQuery.ParamByName('Task').AsString:='缴费';
            FQuery.ParamByName('TaskStatus').AsString:='处理';
            FQuery.ParamByName('TaskTime').AsString:='';
            FQuery.ParamByName('SuccessTime').AsString:='';
            FQuery.ParamByName('ProcessID').AsInteger:=i;
            FQuery.ParamByName('PaymentID').AsInteger:=PayInfo.PaymentID;
            FQuery.ParamByName('ServiceID').AsInteger:=PayInfo.ServiceID;
            FQuery.ExecSQL;

            Msg :='*'+PayInfo.UserID+'*#'+'YDJF#@'+PayInfo.PhoneCode+'@##'+PayInfo.Amt+'##&'+DateTimeToStr(Now)+
                  '&**CG**A'+inttostr(PayInfo.PaymentID)+'AB'+inttostr(Balance)+'BH'+inttostr(PayInfo.ServiceID)+'H';
            Msg := Trim(Msg);

            //短信回复确认表
            FQuery.Close;
            FQuery.SQL.Clear;
            FQuery.SQL.Add('insert into NewsRestoreVerif (UserID,Content,DeliveryTime) values (:UserID,:Content,:DeliveryTime)');
            FQuery.ParamByName('UserID').AsString:=PayInfo.UserID;
            FQuery.ParamByName('Content').AsString:=Msg;
            FQuery.ParamByName('DeliveryTime').AsDateTime:=Now;
            FQuery.ExecSQL;
            //给客户端发送信息
            FUserID := PayInfo.UserID;
            FMsg := Msg;
            //nchronize(SendMsgToClient);

            k:=GetClentIndex(ServerMain.Clients,PayInfo.UserID);
            if k>=0 then
            begin
              Client := ServerMain.Clients.Items[k];
              TIdPeerThread(Client.Thread).Connection.WriteLn(Msg);
            end;

          end
          else
          begin
            //交费失败  #功能#@返回内容@**XB**    把失败记录写入数据表  recordfailurezhong
            Msg :='#YDJF#**XB**' ;

            FUserID := PayInfo.UserID;
            FMsg := Msg;
            //nchronize(SendMsgToClient);

            k:=GetClentIndex(ServerMain.Clients,PayInfo.UserID);
            if k>=0 then
            begin
              Client := ServerMain.Clients.Items[k];
              TIdPeerThread(Client.Thread).Connection.WriteLn(Msg);
            end;
            
            FQuery.Close;
            FQuery.SQL.Clear;
            FQuery.SQL.Add('insert into recordfailure (UserID,PhoneCode,Amt,PostTime,'
              +'Task,TaskStatus,PaymentID)') ;
            FQuery.SQL.Add('values (:UserID,:PhoneCode,:amt,:PostTime,:Task,:TaskStatus,:PaymentID)');
            FQuery.ParamByName('UserID').AsString:=PayInfo.UserID;  //用户名
            FQuery.ParamByName('PhoneCode').AsString:=PayInfo.PhoneCode;   //缴费号码
            FQuery.ParamByName('Amt').AsFloat:=StrToFloat(PayInfo.Amt);
            FQuery.ParamByName('PostTime').AsDateTime:=now;
            FQuery.ParamByName('Task').AsString:='缴费';
            FQuery.ParamByName('TaskStatus').AsString:='失败';
            FQuery.ParamByName('PaymentID').AsInteger:=PayInfo.PaymentID;
            FQuery.ExecSQL ;
            {
            if not DelPaymentTask(yhm,PaymentID) then   //如果2次发送失败删除该条记录
            begin
              WaitAndPass(500);
              if not DelPaymentTask(yhm,PaymentID) then
                MsgCatReady := False;  //2次删除出错就停止短信猫缴费。
            end;
            MessageContent := yhm+'短信发送失败,请处理13909237799';
            dxcgf:=Smsgate1.Sendsms(MessageContent, mobile1,sReport);
            IF dxcgf ='y' then
            begin

            end
            else
            begin
              waitTime := 30;
              Smsgate1.CallPhone(mobile1,waitTime); //发短息失败后,电话通知
            end;
            }
          end;
        end;
      end;
    finally
      Status := 0;  //发送结束.
      FReady := true;
      Suspend;   //执行完后线程挂起
    end;
  end;
end;



function TMsgCat.SendMsg(Command: WideString; UserPhoneCode, Amt: string): Boolean;
var
  sreport: Smallint;
  ret: string;
  nr: WideString;
begin
  sreport := 0;
  try
    FReady  := false;
    if Command = 'KZCZ' then
    begin

      //测试时修改交费金额为1/10.
      //Amt := FloatToStr(StrToInt(Amt)/10);

      nr := Command+' '+UserPhoneCode+' '+Amt+' '+SPPws;
      ret := MsgCat.Sendsms(nr, SPCode, sreport);
      //t := 'y';
      if ret <> 'y' then
      begin
        Result := False;
        exit;
      end
      else
        Result := True;
    end
    else
    begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -