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

📄 channels.pas

📁 东进D160A板卡自动外呼程序代码
💻 PAS
字号:
unit Channels;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ExtCtrls;
  
const 
  maxchannel = 100;
  
type 
  channel_state =
    (Free,  //空闲
    occupy, //占用
    disabled //禁止使用
    );
type 
  channel_type =   //通道内型
    (user,
    trunk,
    nothing
    );

type
  TDunInfo = class
    public
      Sbbh: string;
      //Dialnumlst: TStringList;
      Dialnum: string;
  end;
    
type 
  channel_structure = record
    State: channel_state;      // 通道状态
    Ringing: boolean;          // 通道是否正在振铃
    Channeltype: channel_type; // 通道类型
    Connectchannel: Integer;   // 与本通道连接的通道
    dtmf: string;              // 本通道收到的DTMF码
    Step: integer;             // 本通道当前所处流程
    PlayingWaterfee: Boolean;  // 是否正在播放语音流
    MeterID: string;           // 存储客户的水表编号
  end;

procedure AddItemtoTellist(Achnl: Integer);
procedure InitSystem();
procedure ReleSystem();
procedure DunWaterfee(channelno: Integer);//主程序
procedure ResetChannel(channelno: Integer); //
procedure drawgrid();
function  HangupCheck(Achnl: Integer): Boolean;

var
  Channel: array [0..maxchannel] of channel_STRUCture;
  Totalchannel: Integer;
  TTSChannel: Integer;

implementation

uses tc08a32, Mainform, filectrl, DJTTS3, CallerDM;

{-------------------------------------------------------------------------------
  Procedure: HangupCheck
  Author:    Xsp
  DateTime:  2006.04.28
  Arguments: Achnl: Integer
  Result:    Boolean
  Popose:    挂机检测
-------------------------------------------------------------------------------}
function  HangupCheck(Achnl: Integer): Boolean;
begin
  if Channel[Achnl].Channeltype = trunk then
    Result := (ReadCheckResult(Achnl, PLAY_CHECK) = R_BUSY) and (ReadBusyCount() >= 2)
  else
    Result := not RingDetect(Achnl);
end;

{-------------------------------------------------------------------------------
  Procedure: InitSystem
  Author:    Xsp
  DateTime:  2006.05.09
  Arguments: 
  Result:    None
  Popose:    初始化语音卡
-------------------------------------------------------------------------------}
procedure InitSystem();
var
  i, t: Integer;
begin
  if loaddrv > 0 then
  begin
    ShowMessage('驱动加载失败!');
    application.Terminate;
  end;
  
  totalchannel := checkvalidch();
  if enablecard(totalchannel, 1024 * 50) > 0 then
  begin
    ShowMessage('初始化卡失败!');
    application.Terminate;
  end;
  sig_init(0);

  //初始化stategrid
  Mainfrm.stategrid.RowCount     := totalchannel + 1;
  Mainfrm.stategrid.ColCount     := 4;
  Mainfrm.stategrid.Cells[0, 0]  := '序号';
  Mainfrm.stategrid.Cells[1, 0]  := '通道类型';
  Mainfrm.stategrid.Cells[2, 0]  := '状态';
  Mainfrm.stategrid.Cells[3, 0]  := '当前操作内容';
  Mainfrm.stategrid.ColWidths[1] := 60;
  Mainfrm.stategrid.ColWidths[2] := 60;
  Mainfrm.stategrid.ColWidths[3] := 402;
  for i := 0 to totalchannel do
  begin
    startsigcheck(i);
    initdtmfbuf(i);
    Mainfrm.stategrid.Cells[0, i + 1] := IntToStr(i);
    t := checkchtype(i);
    if t = 0 then
    begin
      Mainfrm.stategrid.Cells[1, i + 1] := '内线通道';
      channel[i].channeltype := user;
      channel[i].state := disabled; //由于是呼出系统,因此这里的内线全部给屏蔽
      Mainfrm.stategrid.Cells[3, i + 1] := '本通道不能作为呼出通道';
    end
    else if t = 1 then
    begin
      Mainfrm.stategrid.Cells[1, i + 1] := '外线通道';
      channel[i].channeltype := trunk;
      channel[i].state := Free;
    end
    else 
    begin
      Mainfrm.stategrid.Cells[1, i + 1] := '通道悬空';
      channel[i].channeltype := nothing;
      channel[i].state := disabled;
      Mainfrm.stategrid.Cells[3, i + 1] := '本通道不能作为呼出通道';
    end;
    channel[i].connectchannel := -1;
    channel[i].dtmf := '';
  end;// end of for

  // 初始化TTS功能
  DJTTS3_Init();
  TTSChannel := DJTTS3_GetTotalTTSChannel();
  for i := 0 to TTSChannel - 1 do
  begin
    if channel[i].channeltype = trunk then
      DJTTS3_AddTTSToChannel(i);
  end;
  Mainfrm.statMain.Panels[1].Text := Format('共激活 %d 条TTS通道', [TTSChannel]); 
  //Mainfrm.label3.Caption := IntToStr(newreadpass(0));
  Mainfrm.Timer1.Enabled := True;
end;

{-------------------------------------------------------------------------------
  Procedure: ReleSystem
  Author:    Xsp
  DateTime:  2006.05.09
  Arguments: 
  Result:    None
  Popose:    释放系统占用的资源
-------------------------------------------------------------------------------}
procedure ReleSystem();
var
  I: Integer;
begin
  for I := 0 to TTSChannel - 1 do
  begin
    if Channel[I].channeltype = trunk then
    begin
      DJTTS3_StopPlayText(I);
      DJTTS3_DelTTSFromChannel(I);
    end;
  end;

  DJTTS3_Release();
  disablecard;
  freedrv
end;

{-------------------------------------------------------------------------------
  Procedure: AddItemtoTellist
  Author:    Xsp
  DateTime:  2006.05.09
  Arguments: Achnl: Integer
  Result:    None
  Popose:    向催缴列表中加入一项未成功的资料
-------------------------------------------------------------------------------}
procedure AddItemtoTellist(Achnl: Integer);
var
  Aduninfo: TDunInfo;
begin
  with Mainfrm.telebox.Items do
  begin
    Aduninfo := TDunInfo.Create;
    Aduninfo.Sbbh := Channel[Achnl].MeterID;
    Aduninfo.Dialnum := Channel[Achnl].dtmf;
    AddObject(Aduninfo.Dialnum, Aduninfo);
  end;
end;

{-------------------------------------------------------------------------------
  Procedure: DunWaterfee
  Author:    Xsp
  DateTime:  2006.05.09
  Arguments: channelno: Integer
  Result:    None
  Popose:    催缴业务处理过程,实在太简单:),不过作为一般的开发入门应该可以
-------------------------------------------------------------------------------}
procedure DunWaterfee(channelno: Integer);
var
  dialnum: PChar;
  Result, Delay: integer;
  Ainfo, AmeterID, Adialnum: string;
begin
  case channel[channelno].step of
    0: 
      begin
        if (channel[channelno].channeltype = trunk) and
          (channel[channelno].state = Free) then
        begin
          if Mainfrm.telebox.Items.Count >= 1 then
          begin
            channel[channelno].dtmf    := Mainfrm.telebox.Items.Strings[0];
            Channel[channelno].MeterID := TDunInfo(Mainfrm.telebox.Items.Objects[0]).Sbbh;
            //从表中取走号码,防止另外一个通道也拨同一个号码
            Mainfrm.telebox.Items.Delete(0);
            Mainfrm.Progressbar.Position := Round((dmCaller.DuntaskCount - Mainfrm.telebox.Count) / dmCaller.DuntaskCount);

            Mainfrm.stategrid.cells[3, channelno + 1] :=
              '拨打电话:' + channel[channelno].dtmf;
            startsigcheck(channelno);
            dialnum := PChar(channel[channelno].dtmf);
            offhook(channelno);
            channel[channelno].state := occupy;
            starttimer(channelno, 4);
            sig_startdial(channelno, PChar(dialnum), PChar(Mainfrm.PrefixNum), 0);
            channel[channelno].step := 100;
          end
        end
      end;

    100:
      begin
        if ElapseTime(channelno, 4) >= 2000 then //超时处理
        begin
          AddItemtoTellist(channelno);
          //把号码加入到电话表中,留待下次呼出
          ResetChannel(channelno);
        end;
        Result := sig_checkdial(channelno);
        case Result of
          //S_NORESULT:;//还没有检测到结果
          S_BUSY: // 遇忙
            begin
              dmCaller.Dunlog(channelno, '外线', '呼出',
                Format('催缴水表编号 %s 所对应的客户欠费,电话号码为:%s', [Channel[channelno].MeterID, Channel[channelno].dtmf]), '对方忙');
              AddItemtoTellist(channelno);
              ResetChannel(channelno);
            end;

           S_NOBODY: // 没人接听
             begin
              dmCaller.Dunlog(channelno, '外线', '呼出',
                Format('催缴水表编号 %s 所对应的客户欠费,电话号码为:%s', [Channel[channelno].MeterID, Channel[channelno].dtmf]), '无人接听');
              AddItemtoTellist(channelno);
              ResetChannel(channelno);
             end;

           S_NOSIGNAL: // 没有信号
             begin
               dmCaller.Dunlog(channelno, '外线', '呼出',
                Format('催缴水表编号 %s 所对应的客户欠费,电话号码为:%s', [Channel[channelno].MeterID, Channel[channelno].dtmf]), '没有信号');
               AddItemtoTellist(channelno);
               ResetChannel(channelno);
            end;

           S_CONNECT: // 对方摘机
             begin
               Delay := 0;
               while(Delay < 3000) do
               begin
                 Inc(Delay, 50);
               end;
               dmCaller.Dunlog(channelno, '外线', '呼出',
                 Format('催缴水表编号 %s 所对应的客户欠费,电话号码为:%s', [Channel[channelno].MeterID, Channel[channelno].dtmf]), '对方摘机');

               Mainfrm.stategrid.cells[3, channelno + 1] :=
                 Mainfrm.stategrid.cells[3, channelno + 1] + '..对方摘机,开始放音';
               Ainfo := dmCaller.GetDunWaterfee(Channel[channelno].MeterID);
               DJTTS3_StartPlayText(channelno, PChar(Ainfo), INFO_TEXT_BUFFER, 0, 45, 100);
               channel[channelno].Step            := 101;
               Channel[channelno].PlayingWaterfee := True;
             end;
        end// end of case
      end;

    101:
      begin
        if (DJTTS3_CheckPlayTextEnd(channelno) = INFO_PLAY_COMPLATE) or HangupCheck(channelno) then
        begin
          AmeterID := Channel[channelno].MeterID;
          Adialnum := Channel[channelno].dtmf;
          ResetChannel(channelno);
          dmCaller.DunInsert(AmeterID, Adialnum, 1, '催缴成功');
        end;
      end
  end;// end of case
end;//end of dowork

{-------------------------------------------------------------------------------
  Procedure: ResetChannel
  Author:    Xsp
  DateTime:  2006.05.09
  Arguments: channelno: integer
  Result:    None
  Popose:    通道复位以便于下次进行相关的操作
-------------------------------------------------------------------------------}
procedure ResetChannel(channelno: integer);
begin
  channel[channelno].state := Free;
  Mainfrm.stategrid.Cells[3, channelno + 1] := '';
  channel[channelno].dtmf  := '';
  channel[channelno].step  := 0;
  Channel[channelno].PlayingWaterfee := False;
  if channel[channelno].channeltype = trunk then // 如果是外线通道,进行挂机
  begin
    hangup(channelno);
    Sleep(2000);
    startsigcheck(channelno);
    Sig_ResetCheck(channelno);
  end;
end;

{-------------------------------------------------------------------------------
  Procedure: drawgrid
  Author:    Xsp
  DateTime:  2006.05.09
  Arguments: 
  Result:    None
  Popose:    更新每条通道的状态信息
-------------------------------------------------------------------------------}
procedure drawgrid();
var
  channelno: integer;
  temp: string;
begin
  for channelno := 0 to totalchannel do
  begin
    if channel[channelno].connectchannel <>-1 then
      Mainfrm.stategrid.Cells[3, channelno + 1] :=
        '本通道正在和第' + IntToStr(channel[channelno].connectchannel) + '通道通话';
    case channel[channelno].state of
      Free: Mainfrm.stategrid.Cells[2, channelno + 1] := '空闲';
      occupy: Mainfrm.stategrid.Cells[2, channelno + 1] := '占用';
      disabled: Mainfrm.stategrid.Cells[2, channelno + 1] := '无效';
    end;//end of case
  end
end;

end.

⌨️ 快捷键说明

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