private static void Update(LineInfo trunk, LineInfo inline) { string sql = "update t_comingrecord set "; //主叫 if (inline != null && inline.CallerPhone != null && !inline.CallerPhone.Equals("")) { Console.Write("号码" + inline.CallerPhone); sql += " callnumber='" + inline.CallerPhone + "',"; } string rectime = trunk.Rectime.ToLocalTime().ToString("yyyyMMdd HH:mm:ss"); sql += "rectime='" + rectime + "',"; string handuptime = trunk.Handuptime.ToLocalTime().ToString("yyyyMMdd HH:mm:ss"); sql += "handuptime='" + handuptime + "',"; string islink = trunk.Islink; sql += "islink='" + islink + "',"; if (inline != null) { string inlinenum = inline.Number.ToString(); sql += " inline = '" + inlinenum + "',"; string gonghao = inline.Gonghao; sql += " gonghao='" + gonghao + "',"; } if (sql.EndsWith(",")) { sql = sql.Substring(0, sql.Length - 1); } sql += " where id='" + trunk.Id + "'"; // log.Debug("更新数据" + sql); SendMessage(sql); }
//插入来电记录 private static void Insert(LineInfo line) { string id = line.Id; string comingtime = line.Comingtime.ToLocalTime().ToString("yyyyMMdd HH:mm:ss"); string trunk = line.Number.ToString(); string sql = "insert into t_comingrecord(id,comingtime,trunk,islink) values('" + id + "','" + comingtime + "','" + trunk + "','no')"; //Console.WriteLine("插入数据:" + sql); DBHelper.executeNonQuery(sql); }
public void Save(LineInfo trunk, LineInfo inline) { //如果id为空,说明是心来电,插入,否则更新 string id = trunk.Id; if (id == null || id.Equals("")) { trunk.Id = Guid.NewGuid().ToString(); Insert(trunk); } else { Update(trunk, inline); } }
//来电记录,参数为外线通道 public static void ComingCall(LineInfo trunk,LineInfo inline) { try { if (saveHelper == null) { loadRecordSave(); } saveHelper.Save(trunk, inline); } catch (Exception e) { log.Debug("保存数据失败!"); } }
/** * 检查是否自动接通 * */ public bool CheckCanAoutLink(LineInfo line) { //通道设置有自动接通时间,当前时间在通道时间范围内,转接到该通道 DateTime now = System.DateTime.Now; string nowHM = now.ToString("HH:mm"); //无开始时间,不自动接通 if (line.StartHour != null || line.StartHour.Equals("")) { return false; } //无结束时间,不自动接通 if (line.EndHour != null || line.EndHour.Equals("")) { return false; } //当前时间在设置的开始结束之间,可接通 if(nowHM.CompareTo(line.StartHour) > 0 && nowHM.CompareTo(line.EndHour) < 0) { return true; } return false; }
//设置监听 private void setListen(LineInfo line) { LineInfo anther = null; try { anther = Lines[line.ListenNum]; } catch (Exception e) { return; } if (anther != null && anther.State == (ushort)state.CH_CONNECTED) { int ren = InvokeVcDll.LinkOneToAnother(line.Number, anther.Number); log.Debug(line.Number + "监听" + anther.Number + ",返回值:" + ren); ren = InvokeVcDll.LinkOneToAnother(line.Number, (ushort)anther.ConnectToLine); log.Debug(line.Number + "监听" + anther.ConnectToLine + ",返回值:" + ren); } }
//查找空闲内线通道,找不到内线通道返回-1 private int GetFreeUser(LineInfo line) { int i =this.ta.Assign(Lines); //如果找不到通道,说明都被使用中,判断号码是否是优先接入号码 if (i == -1) { string sql = "select * from t_teshuhaoma where phone='" + line.CallerPhone + "'"; ArrayList result = DBHelper.executeQuery(sql); if (result.Count > 0) { i = getRandom(); log.Debug("优先接入号码:"+line.CallerPhone +",连接随机通道:"+i); LineInfo inLine = Lines[i]; //强行挂段电话,重置通道 this.ResetLine(i); this.ResetLine(inLine.ConnectToLine); //设置内线状态已连接,内线自动连接外线 inLine.State = (int)state.CH_CHECKSIG; } } return i; }
//得到主叫 private string getCaller(LineInfo trunk) { byte[] number = new byte[128]; InvokeVcDll.GetCallerIDStr(trunk.Number, number); string result = Encoding.UTF8.GetString(number); result = result.TrimEnd('\0'); if (result.Length > 8) { result = result.Substring(8); } char[] c = {'\0'}; string[] phone = result.Split(c); result = phone[0]; trunk.CallerPhone = result; log.Debug("收外线" + trunk.Number + "主叫号码:" + result); return result; }
//主工作方法 public void yzDoWork(LineInfo line) { int tmpCode; //通道对应的连接通道号 int tmpCTL = line.ConnectToLine; //根据类型处理 switch (line.Type) { //内线 case (int)type.CHTYPE_USER: //未摘机 ,不是空闲,不是响铃 if (!line.IsKey && !InvokeVcDll.OffHookDetect(line.Number) && line.State != (int)state.CH_FREE && line.State != (int)state.CH_RINGING) { switch (line.State) { case (int)state.CH_WAITONHOOK: log.Debug("内线" + line.Number + "waitonhook时挂机"); InvokeVcDll.StopRecordFile((ushort)line.Number); ResetLine(line.Number); break; case (int)state.CH_CHECKSIG: log.Debug("内线" + line.Number + "checksig等待连接时挂机"); InvokeVcDll.FeedPower((ushort)tmpCTL); ResetLine(line.ConnectToLine); ResetLine(line.Number); break; case (int)state.CH_CONNECTED: log.Debug("内线" + line.Number + "连接时挂断"); InvokeVcDll.StopRecordFile((ushort)line.Number); int duan = InvokeVcDll.ClearLink(line.Number, (ushort)tmpCTL); log.Debug("断开连接返回值:" + duan); ResetLineInner(line.Number); ResetLine(tmpCTL); break; default: break; } } break; case (int)type.CHTYPE_TRUNK: if (InvokeVcDll.Sig_CheckBusy(line.Number) == 1) { switch (line.State) { case (int)state.CH_DIALING: log.Debug("外线" + line.Number + "dialing响铃时时挂断"); ResetLine(line.Number); break; case (int)state.CH_CHECKSIG: log.Debug("外线" + line.Number + "checksig等待连接时挂断"); this.stopWelcome(line.Number); InvokeVcDll.FeedPower((ushort)line.ConnectToLine); ResetLine(line.ConnectToLine); ResetLine(line.Number); break; case (int)state.CH_CONNECTED: log.Debug("外线" + line.Number + "连接时挂断"); InvokeVcDll.StopRecordFile((ushort)line.ConnectToLine); int duan = InvokeVcDll.ClearLink((ushort)tmpCTL, line.Number); log.Debug("通话时挂断返回值:" + duan); int inerline = line.ConnectToLine; ResetLine(line.Number); this.ResetLineInner(inerline); break; case (int)state.CH_GETCAllNUM: int nx = line.ConnectToLine; ResetLine(line.Number); if (nx != -1) { ResetLine(nx); } break; //播放欢迎语音 case (int) state.CH_PlAYWELCOME: int nx1 = line.ConnectToLine; ResetLine(line.Number); if (nx1 != -1) { ResetLine(nx1); } break; //播放工号 case (int)state.CH_PLAYGONGHAO: int nx2 = line.ConnectToLine; ResetLine(line.Number); if (nx2 != -1) { ResetLine(nx2); } break; //外拨 case (int)state.CH_CALLPHONE: log.Debug("内线" + line.ConnectToLine + "外拨"+line.Number+"时,外线拨号时挂断"); InvokeVcDll.FeedPower((ushort)line.ConnectToLine); ResetLine(line.Number); break; default: break; } } break; default: break; } //根据状态处理(实际电话处理) switch (line.State) { //空闲状态 case (int)state.CH_FREE: //监听响铃 if (InvokeVcDll.RingDetect(line.Number)) { //如果是内线,播放忙音,状态改为摘机 if (line.Type == (int)type.CHTYPE_USER) { if(line.State == (int)state.CH_FREE) { log.Debug("内线" + line.Number + "摘机"); InvokeVcDll.InitDtmfBuf(line.Number); line.State = (int)state.CH_DETECT; } ; } //如果是外线 else if (line.Type == (int)type.CHTYPE_TRUNK) { log.Debug("外线" + line.Number + "电话打入"); InvokeVcDll.StartSigCheck(line.Number); InvokeVcDll.ResetCallerIDBuffer(line.Number); line.State = (int)state.CH_GETCAllNUM; //设置来电时间 line.Comingtime = System.DateTime.Now; //id在comingcall方法内部产生 LineRecordHelper.ComingCall(line, null); } } break; case (int)state.CH_GETCAllNUM: bool bOffHook = false; if (line.Callertime > 1000) { bOffHook = true; } if (bOffHook) { string zhujiao = getCaller(line); line.State = (int)state.CH_PlAYWELCOME; LineRecordHelper.ComingCall(line, null); } else { line.Callertime += 70; } break; //播放欢迎语音 case (int)state.CH_PlAYWELCOME: InvokeVcDll.OffHook(line.Number); this.playWelcome(line.Number); line.State = (int)state.CH_DIALING; break; //查找内线连接 case (int)state.CH_DIALING: tmpCTL = this.GetFreeUser(line); if (tmpCTL == -1) { //欢迎语音结束,播放坐席忙录音 if (InvokeVcDll.CheckPlayEnd(line.Number)) { log.Debug("欢迎语音播放完成,播放忙音"); this.stopWelcome(line.Number); string weladd = Environment.CurrentDirectory + "\\busy1"; InvokeVcDll.StartPlayFile(line.Number, weladd, 0); line.State = (int)state.CH_PLAYBUSY; } break; } Lines[tmpCTL].CallerPhone = line.CallerPhone; InvokeVcDll.FeedRealRing((ushort)tmpCTL); line.ConnectToLine = tmpCTL; Lines[tmpCTL].ConnectToLine = line.Number; line.State = (int)state.CH_CHECKSIG; Lines[tmpCTL].State = (int)state.CH_RINGING; log.Debug("外线" + line.Number + "打入,连接内线" + tmpCTL); LineRecordHelper.ComingCall(line, Lines[tmpCTL]); break; //坐席全忙 case (int)state.CH_PLAYBUSY: if (InvokeVcDll.CheckPlayEnd(line.Number)) { log.Debug(line.Number+"忙音播放完,断开"); InvokeVcDll.StopPlayFile(line.Number); this.ResetLine(line.Number); } break; //等待连接状态 case (int)state.CH_CHECKSIG: tmpCTL = line.ConnectToLine; //检测内线摘机 if (InvokeVcDll.OffHookDetect((ushort)tmpCTL) || Lines[tmpCTL].IsKey) { log.Debug("内线" + tmpCTL + "摘机,与外线" + line.Number + "连通"); this.stopWelcome(line.Number); //播放工号 log.Debug("播放工号"); string weladd = Environment.CurrentDirectory + "\\" + Lines[tmpCTL].Gonghao; InvokeVcDll.StartPlayFile(line.Number, weladd, 0); line.State = (int)state.CH_PLAYGONGHAO; break; } else { LineRecordHelper.ComingCall(line, Lines[tmpCTL]); } break; case (int)state.CH_PLAYGONGHAO: tmpCTL = line.ConnectToLine; //检测内线摘机 if (InvokeVcDll.OffHookDetect((ushort)tmpCTL) || Lines[tmpCTL].IsKey) { log.Debug("内线" + tmpCTL + "摘机,与外线" + line.Number + "连通"); if (InvokeVcDll.CheckPlayEnd(line.Number)) { InvokeVcDll.StopPlayFile(line.Number); } else { break; } InvokeVcDll.FeedPower((ushort)tmpCTL); InvokeVcDll.SetLink(line.Number, (ushort)tmpCTL); line.State = (int)state.CH_CONNECTED; Lines[tmpCTL].State = (int)state.CH_CONNECTED; //录音 string guid = Guid.NewGuid().ToString(); string file = GetSavePath() + guid + ".wav"; InvokeVcDll.StartRecordFile((ushort)tmpCTL, file, 1024 * 8 * 60 * 30); Lines[tmpCTL].RecordFile = guid; //设置接通时间 line.Rectime = System.DateTime.Now; line.Islink = "yes"; LineRecordHelper.ComingCall(line, Lines[tmpCTL]); } else { // LineRecordHelper.ComingCall(line, Lines[tmpCTL]); } break; case (int)state.CH_RINGING: break; case (int)state.CH_CONNECTED: if (InvokeVcDll.CheckSendEnd(line.Number)) { InvokeVcDll.StartSigCheck(line.Number); } break; case (int)state.CH_WAITONHOOK: if (line.Type == (int)type.CHTYPE_TRUNK) { log.Debug("外线" + line.Number + "等待挂机"); ResetLine(line.Number); } break; //摘机状态 case (int)state.CH_DETECT: //如果是内线,检测是否挂机 if (line.Type == (int)type.CHTYPE_USER) { short code = InvokeVcDll.GetDtmfCode(line.Number); if (code != -1) { log.Debug("内线" + line.Number + "按键" + code); if (line.ListenNum != -1) { InvokeVcDll.ClearOneFromAnother((ushort)line.Number, (ushort)line.ListenNum); } line.ListenNum = ConvertDtmf(code); } InvokeVcDll.StartHangUpDetect(line.Number); if (InvokeVcDll.HangUpDetect(line.Number) == 2) { InvokeVcDll.ClearOneFromAnother((ushort)line.Number, (ushort)line.ListenNum); log.Debug("内线" + line.Number + "挂机111"); int num = line.ConnectToLine; ResetLine(line.Number); if (num != -1) { ResetLine(num); } } } break; //外拨 case (int)state.CH_CALLPHONE: //拨号完成后,建立通道 if (InvokeVcDll.CheckSendEnd((ushort)line.Number)) { InvokeVcDll.StartSigCheck((ushort)line.Number); InvokeVcDll.StartSigCheck((ushort)line.ConnectToLine); InvokeVcDll.SetLink((ushort)line.Number, (ushort)line.ConnectToLine); //设置为接通 line.State = (int)state.CH_CONNECTED; Lines[line.ConnectToLine].State = (int)state.CH_CONNECTED; } break; default: break; } }
/** * 初始化语音通道 **/ public void InitLines(ObservableCollection<LineInfo> objs) { //加载语音通道配置文件 String currentDir = Environment.CurrentDirectory; String path = System.IO.Path.Combine(currentDir, "lines.xml"); XElement lineConfig = XElement.Load(System.Xml.XmlReader.Create(path)); ushort TotalLine = InvokeVcDll.CheckValidCh(); for (int ch = 0; ch < TotalLine; ch++) { ushort type = InvokeVcDll.CheckChTypeNew(ch); LineInfo line = new LineInfo(); line.Number = (ushort)ch; line.Type = type; line.ConnectToLine = -1; line.State = (int)state.CH_FREE; line.CallerPhone = ""; line.RecordFile = ""; line.LastTime = System.DateTime.Now; line.Comingtime = System.DateTime.Now; line.Rectime = System.DateTime.Now; ; line.Handuptime = System.DateTime.Now; line.Id = ""; line.Gonghao = ""; line.IsKey = false; line.Islink = "no"; line.ListenNum = -1; //查找配置文件中内容,设置通道属性 if(lineConfig !=null) { XElement element = lineConfig.Elements().Where(e => e.Attribute("num").Value == ch+"").FirstOrDefault(); if(element !=null) { //设定通道自动接通的开始和结束小时 string shour = (string)element.Attribute("starthour").Value; string ehour = (string)element.Attribute("endhour").Value; line.StartHour =shour; line.EndHour = ehour; } } objs.Add(line); } //给每条通道分配初始语音缓冲区 if (InvokeVcDll.EnableCard(TotalLine, 1024 * 128) != (long)0) { InvokeVcDll.FreeDRV(); } }