📄 umulticat.pas
字号:
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 + -