Служба поддержки на ExtJS
Выпала мне задача написать службу поддержки на ExtJS, с очередью свободных суппортов, с обязательным условием «Без обновления страницы, ТОЛЬКО догрузка». Скажу сразу что не осилил допилить поделие.. Но наработки получились интересные. Выкладываю себе на будущее, да и кому мож тоже пригодится.
Что нужно для работы: последний дистрибутив ExtJS (в моем случае по ТЗ ExtJS нужен был 3.4), браузер и редактор. Мне наиболее удобно показалось использовать браузер Chome (включить нужно инструменты разработчика), хотя везде в учебниках смотрю советуют FireFox. Чисто теоретически ExtJS скрипты будет работать и без установленного апача/хостинга, но так как у меня был поднят свой хостинг, поэтому проект создавал прямо там. Логику работы можно разбить на 3 этапа: регистрация, ожидание свободного суппорта, вход в диалоговое окно. Реализация интерфейса суппорта да вообще обмен сообщениями так и не было завершено.
При разработке были использованы следующие ресурсы для помощи:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="ru-RU"> <head profile="http://gmpg.org/xfn/11"> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Техподдержка</title> <link href="js/resources/css/ext-all.css" type="text/css" rel="stylesheet"> <script type="text/javascript" src="js/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="js/ext-all.js"> </script> <? include("myjs/login.php"); // логинимся include("myjs/waitme.php"); // ожидание подключения include("myjs/dialog.php"); // окно диалога ?> </head> <body> <div id="work_area"> </div> </body> </html> |
Ну тут все просто. Подгружаем скрипты, создаем div куда будут подгружаться результаты работы скриптов
Этап 1. Регистрация пользователя.
По ТЗ регистрация — просто вход, без процедуры регистрации и пр. За вход у меня отвечает файл со скриптами include(«myjs/login.php»);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
<script> function getCookie(name) { var cookie = " " + document.cookie; var search = " " + name + "="; var setStr = null; var offset = 0; var end = 0; if (cookie.length > 0) { offset = cookie.indexOf(search); if (offset != -1) { offset += search.length; end = cookie.indexOf(";", offset) if (end == -1) { end = cookie.length; } setStr = unescape(cookie.substring(offset, end)); } } return(setStr); }; function LoginMe(){ Ext.onReady(function(){ // если точно все загрузилось, то начинаем работу Ext.QuickTips.init(); // будут высвечиваться подсказки var user_login = new Ext.form.TextField({ fieldLabel: 'Логин', minLength:3, minLengthText:'Минимальная длина логина 3 символа', allowBlank:false, id:'user_login' }); var user_pass = new Ext.form.TextField({ fieldLabel: 'Пароль', inputType: 'password', minLength:3, minLengthText:'Минимальная длина пароля 3 символа', allowBlank:false, id:'user_pass' }); var buttonOk = new Ext.Button({ text: 'Войти', // обработка нажатия handler:function(){ Ext.getCmp('login_form').getForm().submit({ success: function(form,action) { win.close(); // ждем пока не освободится суппорт и далее переходим к общению GetFreeSupportAndGoNext(action.result.user_id,action.result.user_name); }, failure: function(form,action) {Ext.Msg.alert("Ошибка получения данных/логин или пароль не верен!");} }); } }); // создаем форму и добавляем в неё поля и кнопку var form = new Ext.form.FormPanel({ id: 'login_form', url:'login.php', // обработчик ввода items:[user_login,user_pass,buttonOk] // Перечисляем в массиве элементы формы }); //создаем окно var win = new Ext.Window({ applyTo:'work_area', width:280, AutoHeight:true, title: 'Вход', closeAction:'show' }); win.add(form); // добавляем в него форму win.show(); // показываем окно }); }; user_id=getCookie('user_id'); user_name=getCookie('user_name'); if (user_id=="") {LoginMe();} else {GetFreeSupportAndGoNext(user_id,user_name);}; |
Что тут есть?
Проверяются кукисы. Если есть — переходим к ожиданию свободного суппорта. Если нет — вызываем функцию LoginMe(), показывающую форму для входа:
Этот кусок кода отвечает за создание формы, при submit вызывается обработчик login.php — серверная сторона, которая выдает результат в формате JSON есть такой пользователь или нет.
1 2 3 4 5 |
var form = new Ext.form.FormPanel({ id: 'login_form', url:'login.php', // обработчик ввода items:[user_login,user_pass,buttonOk] // Перечисляем в массиве элементы формы }); |
Из интересного, стоит рассмотреть этот кусок кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var buttonOk = new Ext.Button({ text: 'Войти', // обработка нажатия handler:function(){ Ext.getCmp('login_form').getForm().submit({ success: function(form,action) { win.close(); // ждем пока не освободится суппорт и далее переходим к общению GetFreeSupportAndGoNext(action.result.user_id,action.result.user_name); }, failure: function(form,action) {Ext.Msg.alert("Ошибка получения данных/логин или пароль не верен!");} }); } }); |
Если результат sucess:true тогда переходим к ожиданию свободного оператора. Так-же в login.php на серверной стороне ставятся кукисы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<? include("config.php"); include("connect.php"); $user_login=$_POST["user_login"]; $user_pass=$_POST["user_pass"]; $result = mysql_query("SELECT * FROM users where (login='$user_login' and pass='$user_pass');",$base_id); if (!$result) {die('Ошибка запроса 1: ' . mysql_error());} $myrow = mysql_fetch_array($result); if ($myrow!='') { SetCookie("user_id","$myrow[id]",time()+360000); SetCookie("user_name","$myrow[name]",time()+360000); echo '{"success":true,"user_id":"'.$myrow[id].'","user_name":"'.$myrow[name].'"}'; } else {echo '{"success":false}';}; ?> |
Этап 2 — ожидание свободного оператора
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
function GetFreeSupport(userid,username,win){Ext.onReady(function(){ useradminid=""; var ex1 = Ext.get('work_area'); ex1.html='work..'; Ext.Ajax.request({ url: 'getfreeadmin.php', method: 'GET', params: {user_id: userid}, success: function (result, request) { var json = Ext.util.JSON.decode(result.responseText); if (json.success==false) {setTimeout(GetFreeSupport(userid,username,win),1000);} else { win.hide(); ShowDialog(userid,username,json.useradminid,json.useradminname); }; }, failure: function (result, request) { setTimeout(GetFreeSupport(userid,username),1000); } }); }) }; function GetFreeSupportAndGoNext(userid,username){ var winwait = new Ext.Window({ width:280, AutoHeight:true, title: 'Ждите', html:'Подождите первого освободившегося сотрудника..', closeAction:'show' }); winwait.show(); // показываем окно GetFreeSupport(userid,username,winwait); }; |
Логика: с интервалом в 1 секунду делаем AJAX запрос, с вопросом «а кто свободен?. Если ктото свободен, то переходим к форме службы сообщений. У меня серверая часть поиска свободного оператора — просто «заглушка»
1 2 3 4 5 6 |
<? // по идее здесь запрос который выбирает свободного оператора. Пока заглушка $rnd=rand(1,144); if ($rnd==2) {echo '{"success":true,"useradminid":"2","useradminname":"Support"}';} else {echo '{"success":false,"useradminid":"2","useradminname":"Support"}';} ?> |
Этап 3 — общаемся
Вот тут как раз у меня и вышел затык. Если отрисовать все кнопочки нужные и надписи у меня вышло без проблем, то реализовать в форме где отображаются сами сообщения скроллбары,чтоб окно не растягивалось, у меня не вышло. На том энтузиазм и угас..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
function refreshdlgwin() { Ext.get("dsc").createChild('<div>222</div>'); ; }; function ShowDialog(userid,username,useradminid,useradminname) { // добавляем участников ych = new Ext.Panel({ title: "Участники", renderTo: Ext.getBody(), html: "<li>"+username+"</li><li>"+useradminname+"</li>" }) // тело сообщений txtbody = new Ext.Panel({ id:'msgs', autoScroll:true, AutoHeight:true, title: "Сообщения", html: "<div id='dsc'></div>" }) // тело отсылки сообщений edtr=new Ext.form.HtmlEditor({ width: 700, height: 100, }); var formDlg = new Ext.form.FormPanel({ layout:'fit', id: 'send_form', url:'send.php', // обработчик ввода items:[edtr], buttons: [{text: 'Отослать'}] }); // рисуем окошко var windlg = new Ext.Window({ applyTo:'work_area', width:640, Height:480, title: 'Окно диалога с техподдержкой', // closeAction:'show', items : [ych,txtbody,formDlg] }); windlg.show(); // показываем окно setInterval(refreshdlgwin,1000); // запускаем процесс постоянного обновления окна сообщений }; </script> |