CTO下载-传智播客SQLServer版呼叫中心.ppt_第1页
CTO下载-传智播客SQLServer版呼叫中心.ppt_第2页
CTO下载-传智播客SQLServer版呼叫中心.ppt_第3页
CTO下载-传智播客SQLServer版呼叫中心.ppt_第4页
CTO下载-传智播客SQLServer版呼叫中心.ppt_第5页
已阅读5页,还剩117页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北京传智播客教育 呼叫中心项目开发 讲师:杨中科 项目开发前说明 这个项目尽力避免讲太多WinForm特有的 东西,DataSet、NPOI等要讲的知识都不 是只有Winform中才会用到的。即使是 Winform特有的TreeView也是和ASP.net中 的树状控件、自定义SiteMap等相通的。 呼叫中心概述 什么是呼叫中心。 记录客户活动,先于客户说话就知道客户 的意图。好记性不如计算机。 个性化营销 流程化跟进 提高服务质量 为企业决策提供参考数据 回答策略:站在客户角度,把计算机方式 和人工方式进行对比。 术语 计算机与电信集成技术(CTI) 呼叫中心(Call Center) CRM(客户关系管理)国际著名公司: SalesForge、peoplesoft IVR(Interactive Voice Response)互动式语 音应答。语音菜单。 术语2 座席。 交换机(应用于具有成百上千的座席的大 型的呼叫中心)PK 语音卡(200人以下)。东 进语音卡 智能路由和排队(ACD):根据客户按键 选择,接转到不同的坐席,VIP优先接听, 优先选择上次服务的坐席 系统管理 坐席端(行业无关) 头戴式耳机 一边听,手操作。 客户公司介绍 整车销售,车辆维修,汽车装具,汽车俱乐部服 务,包括咨询、投诉、汽车维(报)修、 保养、救援、售前、售中、保险、售后、 回访等所有与汽车相关的服务,处理汽车 销售订单、预定单,维修、保养等几方面 的问题。 总部在济南,IT机房也在济南。有淄博(2 Seats)、青岛(2 Seats)两个分公司,共10 名坐席人员。 功能简介 角色:系统管理员、班长坐席(管理坐席)、 专家坐席(解答专业性问题)、普通坐席 系统可以根据来电客户的客户编码和密码或主 叫号码等,识别客户身份。 咨询转销售、报修、投诉:如果产生销售机会 ,话务员将按照客户的需求填写订单,转给销 售部门,并进行跟进。 利用系统的标准问题及知识库(FAQ)或汽车 服务信息查询模块,方便及时地答复。 经销商回访、客户回访、投诉回访、维修回访 现有系统分析 一个ERP系统,三地分别运行三个独立的 ERP系统。有部分的客户、销售数据。每 天淄博、青岛分公司将当天的数据以文本 文件形式放到自己的FTP服务器上。要求这 些数据要及时同步到CallCenter中。系统对 接。 有一些遗留的客户数据以Excel形式存在 现有一台闲置服务器, windows2003+MSSQLServer2005。 项目组简介 公司规模:15人,开发人员6人。项目组规 模:一个项目经理,一个语音卡及服务端 开发,一个坐席端开发(Me),一个报表 系统开发。 合同额:35万(包含硬件费用) 项目周期:2个月,最后80天验收。(估算 的项目周期*150%,别盼着按时完成) 技术架构 服务端:Windows2003、东进语音卡(16路)、 .Net3.5、WCF协议(对比Socket、 .NetRemoting、WebService) 数据库服务器:Windows2003、 MSSQLServer2005。没有单独的数据库服务器 ,用的是ERP系统的数据库。 坐席端:Windows XP、.Net3.5、WinForm(为 什么用WinForm)、短信猫 报表系统:ASP.Net(为什么用Asp.Net,领导、 销售人员要看)、MSChart。 提醒我:每半天一个版本(自己保存历史版本)。 开发登陆界面 暂时不用数据库做登录。Application.Run的窗口不能作为登录界 面,因为Application.Run 起来的窗口是主窗口,主窗口适合长 期显示,主窗口一旦关闭程序就终止了。论坛上常问的问题。 专业化的界面 启动时窗口位于屏幕中央StartPosition=CenterScreen 设定AcceptButton,当点击回车键要响应的按钮,这样不用很 土的点击按钮才能触发。 设定CancelButton,当点击ESC键时要响应的按钮。 设定按钮的DialogResult,当点击按钮的时候窗口关闭,并且 执行操作。 设定窗口的DialogResult即可关闭窗口并且让ShowDialog方法 返回设置的值。 选择的图片是以资源的形式嵌套在程序中的resx,删掉源文件 没关系。 MD5算法 MD5算法是一种散列算法(计算摘要,指纹算法),不是一种加密算法(易 错)。任何长度的任意内容都可以用MD5计算出散列值 MD5算法不可逆,也就是只能得到内容对应的MD5值,无法由MD5值反推内 容 Password字段保存用户输入密码的MD5值,这样系统管理员也不知道用户的 密码是什么,也就避免了用户的其他系统密码被利用的问题(很多人不同的 系统密码一样)。这就是为什么很多网站只有密码重置,没有找回原密码功 能了。 判断密码正确性的方法:计算用户输入的密码的MD5值,与数据库存储的 MD5值进行比较,如果相等则认为密码正确。 两个不同的内容生成相同的MD5值,这就叫碰撞。MD5算法的碰撞概率非常 小。 计算文件的MD5值来检验文件没有被篡改过。 /9422e/blog/item/b6a7cb870d91513466096e65.html MD5算法理论上是不可逆的,因此攻击的唯一办法就是碰撞。找到一个内容 虽然不同但是产生同样MD5的内容即可。 MD5算法2 不要露怯,王小云不是破解了MD5算法,只是发现缩短枚举碰撞时间的理论 而已:/content/10/0324/13/16546_20057032.shtml 那些破解MD5网站是怎么回事?它是收集了大量常用的字符串的MD5值,保 存“字符串MD5”的对应关系,本质上仍然是穷举法。只能用于应付一下常 见的问题,对于文件、长字符串是没作用的。记住,密码要用长一点的,带 特殊字符,!?,让黑客哭去吧! 计算字符串的MD5代码:备注中。计算文件的MD代码,自己找。 MD5的其他应用简介:第三方支付用MD5对金额、订单号等进行散列计算, 来保证数据是对方发出的。如鹏网项目会讲。 和MD5类似的还有SHA等算法。 黑客基地讲师来讲网站安全。 说明:类的名字不要和命名空间的名字重复,否则会有很多麻烦。 设计坐席表 坐席表的设计:主键、用户名、姓名、密码 用数据库方式修改登录功能(暂时手动加入数据)。迭 代式开发,不是所有功能都一上来就全部写好,而是添 砖加瓦 修改密码功能。如果得到当前登录用户Id?在Form1中 声明一个Guid类型的全局变量CurrentSeatId(public static Guid CurrentSeatId ;);登陆的时候将rowSeat 中的Id保存在CurrentSeatId中;这样在任何一个类中就 都可以访问Form1.CurrentSeatId来得到当前的坐席主 键了。 坐席管理 图标资源的使用,两种方式的区别。直接导入:本地导 入:每个窗口都有一份;将图标在Resources.resx中导 入,然后按钮选择Image的时候选择下面的“项目资源文 件即可。” 保存:cCSeatBindingSource.EndEdit(); adapter.Update(dataSetUsers); 数据新增初始化 DataRowView row = (DataRowView)tVendorsBindingSource.AddNew(); SeatEndApp.Vendor.DataSetVendors.T_VendorsRow vendorRow = (SeatEndApp.Vendor.DataSetVendors.T_VendorsRow)ro w.Row; vendorRow.BeginEdit(); vendorRow.Id = Guid.NewGuid(); vendorRow.EndEdit(); 怎么知道要转换为什么类型的?用调试功能运行时看属性 的真正类型。用调试器探索是脱离老师、变为牛人的一个 法宝。探索! 坐席管理高级操作 删除 BindingSource.RemoveCurrent(); 密码重置: DataRowView rowView = (DataRowView)bindingSource.Current;var userRow = (SeatEndApp.Seat.DataSetUsers.T_UsersRow)rowView.Row;/怎么知 道要Cast成什么类型。两种方式。 BindingSource作用:维护当前状态。控件绑定到 BindingSource,BindingSource连接到DataSet。两个 控件都绑定到LevelBindingSource看一起动的效果明白 BindingSource的作用,怎么不一起动呢?建两个 BindingSource,连接到同一个DataSet。 坐席管理2 DataGridView的个性化:修改Caption、删除列、调整列顺序 增加一个姓名字段:数据库中增加一列,重新配置DataSet(手工编写 SQL或者用查询生成器),在DGV中增加一列 增加级别列实验步骤: 设计级别表(管理坐席、专家坐席、普通坐席)。Id、Name两个字段。Id是 int类型就可以(对于有限几个值的表,应int做主键就可以,这样也可以在其 他表里引用整个表中的数据也可以轻松的看出数据的值)。 在Seat表中增加LevelId字段(需要把原有数据清除,再增加字段)。重新配置 Seat结果集。 增加SeatLevel对应的结果集。 在DataGridView中增加LevelId对应的列,注意列类型选择 DataGridViewComboBoxColumn。设定列的DataSource为SeatLevel结果集 ,选择DisplayMember为Name,valueMember为Id。 一个界面上两套DS、Adapter。 对照文档讲需求 项目开发流程 公司里开发还是现场开发(坐在客户机房里 开发) 公司里开发是做产品的 现场开发是做项目的 做产品的公司实施阶段也是需要现场二次开发 、实施、配置的。 与客户不断沟通、修改的过程。迭代式开 发。 唯一不会变的就是变化 范式 SeatLevelId Student Id Name Age Major 1 张三 20 计算机 课程表 StudentName 课程名 上课时间 张三 数据库 5月1日 StudentId 课程名 1 数据库 第二范式:任何表都要有主键。 数据库设计第三范式:一张表A中引用另外一张表B的数据的时候,是通过在这个表A 中建立一个指向表B主键的字段。 表设计 北京传智播客教育 l逻辑主键与业务主键的区别。没有特殊理由,都用逻辑主键 这位大哥哥你恐怕认错 认了吧,我不是唐 伯虎,我叫华安 别以为改了名字不通知我, 我就记不得你了,我记 得是你的身份证号9527 表设计2 北京传智播客教育 第三范式通俗版:通过主键引用其他表中的内容,这就遵守了第三范式 。优点:保证数据的更新;缺点:慢。 主 键键 学号名称 001sdu1Tom 007sdu2Lily 日期学生学号 05-30sdu1 11-22sdu2 日期学生主键键 05-30001 11-22007 l上学期间改了学号,那么 就找不到自己的记录了。 l老生离校、新生入学,也 许过两年新同学John分到 了sdu1这个学号,那么他 就会在两年前就有记录了 ! l能够避免上面的问题 l缺点是速度慢,如果要查 05-30的学生的学号,还需 要先查主键,然后再去学 生表中查学号。 第三范式旧数据的问题 北京传智播客教育 主键键身份证证号姓名 0013721王靖雯 0078848谢霆锋 主键键身份证证号姓名 0013721王菲 0078848谢霆锋 歌曲名歌手主键键号 有缘的话001 冠希好兄弟007 改名前出的歌,此时到数 据库中查询出来的结果 :有缘的话:王靖 雯 2008年到数据库中查询出 来的结果:有缘的话 :王菲。那时候就叫 王菲啦? 解决方案:数据版本化、数据作 废功能。 案例分析 北京传智播客教育 l业务上、技术上的原因决定了,必须做违反第三范式的事情!分析 论坛帖子昵称的问题! 用户户名昵称 fj001风间 yyxzz小新 发发帖人用户户名主题题 mxd大家好呀! yyxzz我叫新之助 发发帖人昵称主题题 风间大家好呀! 小新我叫新之助 用户户名昵称 fj001风间 yyxzz小白 改名后 提问,这两种实现方 式有什么优缺点? 改名以后帖子中各 显示什么? 符合第三范式:表中引用其他表的时候都是 通过主键引用就是符合第三范式。 编码规则4 北京传智播客教育 l待解决问题:并发、断号、编码回收 lOracle中的Sequence 美 化 教大家做FormSQL,避免在VS里混乱的问题。 读取连接字符串的方法:添加对System.Configration的引用 (添加引用就是引用别人提供的类所在的dll),然后 ConfigurationManager.ConnectionStrings“constri”.Conne ctionString; 读取 根据输入的是不是以Select开头来判断是ExecuteQuery还是 ExecuteNonQuery。 对于危险性SQL语句(比如不带where语句的Update、 Delete)要提示用户。 MDI: form.MdiParent = this; 把主窗口的IsMDIContainer设为true todo:每个界面只能打开一个,这个放到讲完了泛型、反射 以后再讲。放到Oracle版中讲。 用户控件 函数、类是代码复用的一种方式;用户控件是界面复用的 一种方式,把一些控件组织在一起成为一个整体,这个整 体可以重复使用。 输出属性 案例:带计算器(找现成的源码 /detail/qsrEEiB 项目版本转换) TelTexBox 可绑定,属性标记为Bindable就可以进行数据绑定。 Bindable(true)/放到属性上,属性就可以绑定了 public string TelNum 客户资料管理 姓名(Name)、固定电话(TelPhone)(带播出按钮)、手机(MobilePhone)(带 播出按钮)、邮编(PostCode)、Email、通讯地址(Address)、门店(2位,由总 部顺序分配编号)、购买日期(BuyDate)、车号(CarNum)、车架号( BracketNum)、品牌(Brand)、型号(TypeNum)、意见建议(Suggestion)、备 注(Remarks)。字段哪怕用拼音,也别用拼音缩写(你猜TXDZ是什么字段?),也 不要用中文字段名。表名:T_Customers。易错:电话号码用什么字段类型?这是业务 人员提出来的,人家不会说Id。 编辑界面、列表界面分离。一般情况下列表页面只能看,不能改,否则麻烦会很多。 选择多个控件,用设计器的功能进行批量的对齐,不要像狗啃的。以选中的第一个控件 为排头。 把客户资料管理完善(意见建议、备注用多行TextBox)。双击表格跳转到详细列表 TabPage。 做企业信息系统的一个要求:全键盘操作。也就是不用鼠标就可以进行所有的操作。有 的财务系统完全用小键盘就可以完成。 从左向右,从上向下。设置Tab键顺序,全键盘操作:视图Tab键顺序,鼠标按 要设定的跳转顺序点,设置完毕,再点视图Tab键顺序就可以了。好神奇呀! 不神奇,没有魔法,TabIndex属性,手改也可以。 回车键焦点跳转。锻炼解决问题的能力,教大家上网搜。关键字:“WinForm 回车 Tab” 补充 1、解决mdf文件重新生成就覆盖的问题,让程序去连接项目中的mdf文件,而不是连接bin/Debug下那 个。修改方法,在Program.cs文件Main函数最开始加入,也就是修改DataDirectory 宏的值: string dataDir = AppDomain.CurrentDomain.BaseDirectory; if (dataDir.EndsWith(“binDebug“) | dataDir.EndsWith(“binRelease“) dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName; AppDomain.CurrentDomain.SetData(“DataDirectory“, dataDir); 详细介绍:/forum/thread-11988-1-1.html (暂时不用理解原理) 生产环境如何切换到服务器方式运行?将mdf文件Attach到SQLServer,然后改连接字符串即可。 2、有同学发现编辑数据的时候只有移动焦点到其他行才能保存到数据库中,这是我当时没有讲清,请 在调用Adapter.Update()保存前调用bingdingsource的EndEdit方法来强制把当前页面中的值刷新 到DataSet中,这样就不会有这个问题了。 private void btnSave_Click(object sender, EventArgs e) tUsersBindingSource.EndEdit();/请把界面中的修改立即同步到DataSet中 t_UsersTableAdapter.Update(this.dataSetUsers.T_Users); 在对和界面绑定的DataSet进行修改的时候需要BeginEdit、EndEdit 3、刚才讲课的时候一个失误,忘了讲门店的combobox控件要将SelectValue属性绑定到BranchId字段 了,只有这样绑定才能将门店的数据显示到界面中。 程序处理Excel的技术 OLE Automation:能够使用Excel的所有功能,要求装Excel,微软最推荐这 种用法,因为可以促进Excel的销量。会启动Excel进程,不适合于服务器。 参考资料/denylau/archive/2010/04/30/1725172.html /xuanhun/archive/2010/04/29/1724500.html (*)把Excel当成数据库,使用Microsoft.Jet.OleDb访问访问Excel ,参考资料 /f?kz=331569890 只适合于完全二维结构,功能最弱, 很少用。 (*) OpenXML,微软提供的读写Excel的技术,优点和NPOI差不多,不过只 能处理xlsx格式文件。docx、pptx NPOI、MyXls等,能够进行常用Excel操作,不依赖于Excel,节省资源,没 有安全性、性能的问题,在ASP.net中用最合适。只能处理xls格式文件、不 能处理xlsx这样的新版本Excel文件格式。 Excel基础 整个Excel表格叫工作表:Workbook;工作表 包含的叫页:Sheet;行:Row;单元格:Cell 。 Excel中的电话号码问题,看起来像数字的字符 串以半角单引号开头就没问题了。 使用区域(UsedRange):用Excel表的时候不 一定是从最左上角的单元格开始用,为了减小文 件尺寸,有使用区域的概念,Excel只存储使用区 域。 NPOI组件的引入 我们平时调用的类是已经添加到引用的,如果想调用系 统内置的没有添加引用的其他dll(*严格的说是在GAC 中的Assembly)就要添加引用,在【.Net】选项卡中选 择,对于另外一些第三方dll(*严格说是Assembly)则 需要点击【浏览】选项卡选择对应的dll文件。 将NPOI包解压到硬盘中,然后在项目中添加引用,浏 览,将解压目录下的dll全部添加进来 (*)POI是Apache的一个Java开源项目,NPOI是POI在.net 下的移植版本,很多.Net的移植版本开源项目都是在原来 的Java版本名称前加上N,比如NHibernate、NDoc、 NUnit、NAnt NPOI起步 1、读取,暂时不用管FileStream具体含义,“IO流”会讲 using (FileStream stream = new FileStream(“D:我的文 档livemesh如鹏备课dotnet班级信息2010年4月20日 机工班课件5-5客户资料.xls“, FileMode.Open, FileAccess.Read) HSSFWorkbook workbook = new HSSFWorkbook(stream); MessageBox.Show(workbook.GetSheetName(0) ; 2、遇到错误别慌,仔细看错误信息。可能遇到的问题,文 件被其他进程占用。 读取Excel 读取字符串类型数据 MessageBox.Show(sheet.GetRow(3).Get Cell(4).StringCellValue); 读取数字类型数 据NumericCellValue。 判断单元格数据类型:读取 GetCell(4).CellType,与HSSFCell类中定 义的常量比较即可。 判断使用区域:结束行号:LastRowNum 写入Excel HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.CreateSheet(); HSSFRow row = sheet.CreateRow(0); row.CreateCell(0, HSSFCell.CELL_TYPE_STRING).SetCellValue(“Hello“); row.CreateCell(1, HSSFCell.CELL_TYPE_NUMERIC).SetCellValue(3.14); using (FileStream stream = new FileStream(“c:1.xls“, FileMode.OpenOrCreate, FileAccess.ReadWrite) workbook.Write(stream); 自己研究的东西,格式化单元格文字,插入图片 客户资料导出 将客户资料导出到Excel文件,格式:顾客姓名、 住宅电话、手机、详细通讯地址、邮政编码、车 号、车架号、购买日期、分店编号。 实验步骤 弹出文件保存对话框,用户提供要保存文件的文件名 创建表头 通过tableAdapter.GetData读取所有数据,遍历所有数 据,依次CreateRow添加到WorkSheet中 将文件保存到用户提供的文件名中 提示用户导出完毕。 调用Process.Start(Excel文件全路径)自动打开文件。 客户资料导入 根据车号或车架号匹配客户资料,如果数据已经存在则不作导 入。测试文件。 实验步骤 tableAdapter中增加一个根据车号查询客户资料的方法 GetDataByCarNum, tableAdapter中增加一个根据车架号查询客户资料的方法 GetDataByFrameNum。 弹出对话框,要求用户选择要导入的Excel文件 遍历用户选择的Excel文件,根据行中的车号、车架号匹配 数据库中已有的客户资料,如果车号或者车架号能够匹配上 ,则不导入这条记录。 提示用户导入完毕,并且报告导入多少条,如果存在跳过的 行则还要报告跳过多少条。 优化TableAdapter插入速度 1、测试常规插入模式插入5000条数据的速度,用Stopwatch计时。 2、优化: using (adapter.Connection) adapter.Connection.Open(); for (int i = 0; i 中,然后根据List中元 素数量来判断是不是应该加where,将List中的字符串用or进行分割组合成 SQL语句。 string.Join方法可以将字符串数组用分隔符拼接成一个字符串,例子: string.Join(“,“, new string “1“,“2“,“3“); 将List转换为数组list.ToArray() 注意不要把SQL拼成一个疙瘩呀。 虽然SQL语句也是动态拼接的,但是SQL语句的所有内容都是程序员自己写 的,不存在客户输入介入的时机,所以拼SQL语句的过程没有注入楼哦的那 个攻击!通过参数的方式是不会有注入漏洞攻击的,因为SQLServer不是去 进行字符串的拼接了,SQLServer是直接把值进行比较的。 todo:某个条件不勾选的时候应该禁用控件。 发现程序错误的时候,在可能错误的地方,或者你期望是*的地方设置断点 ,看看可能出错的各个变量、表达式的值。 当你读不懂代码的时候,也可以在关键的地方多设置几个断点,然后一边执 行,一边看变量的变化。 日期范围检索 BuyDate =StartDate and BuyDate中。 练习2:用string.IndexOf方法输出字符串中所有的姓名“同志们好我是杨中科。哈哈,我是 小沈阳。哇塞我是李宇春。” 当递归调用层次过多的时候就会发生“StackOverflowException”异常,所以以后写程序如果 遇到“StackOverflowException”异常,一般就是一个死的递归。递归都有一个递归的终 止条件,就是什么时候不再递归了。 树在数据库中的存储 名称爹 辽宁 沈阳辽宁 皇姑屯沈阳 沈河沈阳 新民沈阳 鞍山辽宁 河北 廊坊河北 固安廊坊 三河廊坊 如何从数据库取得所有省节点? 如何从数据库取得所有市节点? 树是有级次的,数据库表是 二维的,怎么用二维的表储 存级次的树就是一个难题 案例:论坛版块列表 话术脚本概念 话术脚本、知识库、FAQ:坐席对着念 给客户的东西。好记性不如破电脑 要素:标题、正文。 话术管理设计 开发步骤: 设计数据库表; 设计强类型DataSet中取得各级数据的方法; 设计界面,将表中的数据加载到TreeView中,为了能够在点击节点的时 候将节点的正文填充到文本框中,因此将每个节点对应的DataRow放到 节点的Tag中。 设计话术的添加、删除、修改、查找等功能 树状结构表设计,表名T_Scripts,字段: Id(Guid、主 键)、Title(NVarchar(50),标题)、Msg( NVarchar(MAX),正文)、ParentId (Guid、父级主键) ParentId为节点的父节点的主键值,第一级节点的 ParentId为null。录入初始数据。 话术开发1 SQL中判断一个字段是否为空,用is null,而不 是=null。因此取得第一级节点用“where ParentId is null”,而不是“where ParentId=null” 。 adapter中需要增加两个查询方法: GetLevel1Data(select * from T_Scripts where ParentId is null) GetDataByParentId( select * from T_Scripts where ParentId=ParentId ) 测试两个查询方法,查看输出的数据进一步理解 两个方法的设计。 话术开发2 将T_Scripts表中的数据加载到TreeView中的算 法: 调用GetLevel1Data方法将第一级节点的数据加载到 treeview.Nodes。加载节点的时候将节点对应的 T_ScriptsRow对象设置到节点的Tag属性上。 遍历第一级节点,将以第一级节点对应的数据行为 Parent的节点加载到treenode.Nodes子节点上 遍历第二级节点,重复 话术开发2 发现加载的规律,无论是哪级节点都是“将查询 出来的T_ScriptsDataTable填充到 treeview.Nodes或者treenode.Nodes中”, treeview.Nodes、而treenode.Nodes都是 TreeNodeCollection类型,因此设计方法 Fill(TreeNodeCollection nodes,T_ScriptsDataTable scripts) 编写Fill的实现代码:遍历scripts每一行,调用 nodes.Add添加节点,将row的Text设置为节点 的Text 话术开发3 调用Fill方法将GetLevel1Data方法返回的 第一级数据填充到TreeView上。 怎么填充其他级次呢?遍历添加每个节点 的时候都继续“将以我对应的row为Parent 的行添加到我的Nodes中”,因此完善Fill 方法,自己调用自己。 调试的方法查看每步执行结果,理解为什 么这么设计。 话术开发4 将row对象设置到节点的Tag属性上 点击节点在右边显示话术脚本,响应TreeView控件的 AfterSelect事件,从节点的Tag中取出来此节点对应的 T_ScriptsRow,然后显示到TextBox中。 节点的编辑(增加工具栏): 开发节点编辑对话框,由于需要将编辑前节点的Title、 Msg传递给对话框,并且的都爱用户设置的新值,设计 ScriptTitle、ScriptMessage两个属性。 修改节点Tag上的T_ScriptsRow的属性,然后调用 Adapter的Update方法将修改保存到数据库。 需要刷新当前选择节点的界面显示 话术开发5 增加一级节点 弹出节点编辑对话框 将节点设置调用adapter的Insert方法插入数据 库 调用adapter的GetDataById方法将刚插入的数 据检索出来 调用treeview.Nodes.Add增加新节点,并且按 照加载时的逻辑进行节点的Tag、Text设置( 可以把代码抽象到一个函数中) 话术开发6 增加非一级节点(练习) 弹出节点编辑对话框 将节点设置调用adapter的Insert方法插入数据 库 调用adapter的GetDataById方法将刚插入的数 据检索出来 调用treenode.Nodes.Add增加新节点,并且按 照加载时的逻辑进行节点的Tag、Text设置( 可以把代码抽象到一个函数中) 话术脚本7 删除节点算法设计:删除节点包含删除数据库中的对应数据和删除界面上的 节点两部分工作 删除数据库中的节点则要:如果节点有子节点则先删除子节点,再删除自己 ;如果子节点还有子节点,则先删除子节点的子节点,再删除子节点。又是 一个递归。 删除界面上的节点调用TreeNode的Remove方法自杀即可 步骤: 数据库中增加DeleteById方法,根据主键删除数据。 在BLL中增加一个T_scriptsBiz类,增加一个DeleteScriptById方法,用来根据 话术Id删除话术,在其中调用GetDataByParentId方法判断Id对应的节点是否 有子节点,如果有子节点则首先调用DeleteScriptById方法删除子节点,否则 调用DeleteScriptById方法删除当前节点。 调用当前选择节点TreeNode的Remove方法将自己从TreeView中删除 练习作业:通讯录管理,树状结构:名称、Email、电话、手机 外拨流程 WCF服务 器端 WCF客户 端 (*)WCF基础 系统间通讯:一台计算机对另外一台计算机之间进行通信。 系统间通讯技术:Socket、WebService、.Net Remoting、MQ 大一统的通讯技术WCF,底层仍然是上面的技术,但是简化了 很多工作,而且随意切换底层技术。 概念: 服务端、客户端:客户端调用服务端提供的服务(拨号、发传真、得到在线坐席列表、 转接等),这些都是坐席客户端自己无法完成的工作。 回调(CallBack):一般情况下都是客户端调用服务器端的服务,比如外拨、得到在线坐 席列表,然后服务器将调用结果返回给客户端。有的时候主要服务器主动通知客户端, 比如来电了,这种服务器主动调用客户端的行为就叫“回调”。 WCF底层可以用Http、NetTcp等通讯协议。为什么呼叫中心服 务器用NetTcpBinding,而不用HttpBinding?因为Http协议的特 点决定了HttpBinding不能很好的支持回调。 服务器模拟器使用 目标:连接服务器,实现拨号 运行服务器模拟器程序 添加服务引用,使用模拟器界面中的地址。操作步骤见备注 双击引用的服务,查看类定义,这些类是VS自动生成的。 如果服务端定义了回调接口,客户端连接的时候必须传递实 现了回调接口的类的实例,这里让主窗口类实现, InstanceContext context = new InstanceContext(实现类的 对象);new PlatformServiceClient(context); 服务器接口说明见IPlatformService.cs注释 集成服务器模拟器 调用Connect开始登录。不要忘记。 调用DialOut函数拨号,注意不要每次都new PlatformServiceClient,因为每个PlatformServiceClient相当 于一个WCF通道,呼叫中心服务器规定一个坐席客户端只能 有一个WCF通道。因此请将PlatformServiceClient实例保存 到全局变量Globals中。 挂机调用Hang方法,返回值是通话录音文件名。 配置app.config 通讯超时,配置binding段的超时时间,因为咱们的项目是长连接, 所以需要配置为“12:00:00” 修改服务器IP地址,端口,配置endpoint段。尝试连接我的 服务器,看效果。 来电流程 WCF服务 器端 WCF客户 端 回调接口的实现 this.BeginInvoke(new Action(delegate() /回调实现方法的代码放到这里 ); 这涉及到多线程、委托等知识,后面再讲原 理。 来电显示来电信息 目标:来电以后在页面顶部显示来电客户的信息。 关键点: 根据来电查找对应的客户。 将查询出来的客户信息显示的页面顶部。 步骤: 在TableAdapter中增加根据来电模糊匹配(like)客户的查询方法 GetDataByPhone、FillDataByPhone。 在页面顶部中放置Panel控件,并且将Panel控件的Dock属性设置为Top 在上一步的Panel控件中画出界面,拖放一个DataSetCustomers组件到界面,拖 放一个BindingSource组件到界面,绑定BindingSource 组件到DataSetCustomers ,设定Panel上的各个控件的属性到BindingSource(编辑DataBindings节点下的 属性) 。 调用TableAdapter的FillDataByPhone方法将结果填充到DataSet中。 根据车号定位客户。打进来的电话如果没有被正确的识别为正确的客户就需 要根据车号来定位客户了。车号文本框可以编辑,在车号文本框中输入车号 ,点击查询按钮就可以根据车号定位客户。(非常重要!) 通话录音管理 功能点说明: 1、挂机后将录音记录到通话记录表中 2、坐席可以进入通话记录管理界面查看通话录音,普通 坐席只可以查看自己的通话录音,管理坐席以查看所有 坐席的通话录音。可以根据对方号码、通话时间、坐席 等条件进行复合检索。下午有时间做。 tips:1、怎么判断是管理坐席,首先从Globals中取出当 前坐席Id,然后到Adaptor中用GetDataById方法取道坐 席的级别;2、只能查看自己的通话录音,在进行复合 检索的时候加一句and SeatId=SeatId。 3、双击通话录音可以播放通话录音。 现场设计、现场开发。 程序中发邮件技术 北京传智播客教育 lPOP3是接收邮件,SMTP是发送(T:Transfer)(根据他们的英文来 区分) l邮件收发客户端Outlook、FoxMail等,企业中一般都用客户端,因为可 以保证及时收发,离线也能处理邮件。(*) l在程序中通过SMTP协议发送邮件需要邮件提供商开启SMTP服务,企 业邮件一般都支持,免费邮件不一定支持,163免费邮件支持。讲课咱们 用163免费邮箱测试,注册步骤: l进入,注册一个邮箱,例如 、 密码123456 l配置邮箱,右上角 “设置”“客户端设置”“开启POP3/SMTP服务” lSMTP服务器地址: l垃圾邮件问题,服务器一般都限制了一段时间内发送邮件的封数。 (*) 发送邮件代码 MailMessage mailMsg = new MailMessage();/两个类,别混了 引入System.Web这个Assembly mailMsg.From = new MailAddress(““, “新广源集团客服中心“);/源邮件地址 mailMsg.To.Add(new MailAddress(“”,“杨中科”);/目的邮件地址。可以有多个收件人 mailMsg.Subject = “关于.net培训班咨询事宜“;/发送邮件的标题 mailMsg.Body = “附件中是资料,请查收!“;/发送邮件的内容 mailMsg.Attachments.Add(new Attachment(“c:/boot.ini”);/将附件附加到邮件消息对象中 ,可以有多个附件 。 SmtpClient client = new SmtpClient(““); client.Credentials = new NetworkCredential(““, “123456“); client.Send(mailMsg); MessageBox.Show(“发送成功“); 参考资料:/pcmax/archive/2007/08/06/845430.html 扩展阅读:C#发送Email邮件方法总结 /wuhuacong/archive/2009/11/13/1601491.html 发送带嵌入图片邮件之SMTP实现和ESMTP实现 /wuhuacong/archive/2009/11/13/1601491.html 博客园,上上更健康。面试常问问题:你经常去的技术类网站是什么?博客园( ),谁上谁知道。其他常去.net网站:、、codeplex、 。 邮件发送功能 邮件发送配置 用对话框配置邮件服务器配置,使用配置 平台保存配置。配置平台开始发威!系统 越复杂,这种公共平台的威力越大。 问题:用配置平台怎么保证不同坐席有不 同的配置? 内部通讯录管理 过程参考话术管理。字段邮箱、手机、电话。强化复习树 状数据处理模式。将其重要。后面项目不止一次要用到。 步骤: 设计数据库表:T_Contacts:Id、ParentId、Name、Email、TelPhone 、MobilePhone 设计强类型DataSet中增加GetLevel1Data、GetDataByParentId 设计界面,将表中的数据加载到TreeView中,为了能够在点击节点的时 候将节点的正文填充到文本框中,因此将每个节点对应的DataRow放到 节点的Tag中。 设计通讯录的添加、删除、修改等功能 能够从内部通讯录中选择多个内部人员做为收件人。 能够从客户中选择多个客户做为收件人。 咨询窗口 流程:来电时因为不可能立即知道这个客户是咨询、报修 、投诉等,哪怕有IVR导航,用户也可以随便选择,因此 来电首先弹出咨询窗口,然后再根据咨询的情况转报修、 转销售、转投诉等。 咨询、投诉、报修是这个系统中最有价值的功能,但是没 什么技术含量,课上不讲,课下一定要对着截图自己来实 现,否则说起这个项目的时候就会丢下最重要的部分,把 这几个功能自己实现基本就能成为拖控件高手了。注意: 新建咨询、投诉、报修的时候将当前对方号码记录下来 记住:“会了,懂了”离烂熟差很远,企业需要的是熟手! 实际这个项目做下来最烂熟的功能就是这部分。一定要自 己实现! 坐席操作 暂离、重连。为什么需要暂离功能?上洗手间、接水暂离电话就不 会接到这个坐席了。 坐席选择对话框。转接、三方通话 显然只能转接给在线的坐席 调用服务器的GetOnlineSeatIds()方法获得当前在线坐席。注意将自己排 除出去。 自定义对话框,对外提供SelectedSeatid属性。 显示坐席选择对话框,然后得到选中的坐席Id,接着调用转接、三方通话 的方法就可以了。 实现转接;三方通话 通话计时 登录显示坐席信息。 显示通话计时 节省话费,不要闲聊,否则扣钱。 DialOut或者OnDialIn的时候在字段BeginDateTime中记录当前时 间,设置一个Timer,每10秒钟检查一次当前时间和 BeginDateTime的差,TimeSpan类型,如果超过5

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论