Чат и оповещение пользователей 1С+Mysql
25.05.17 22:23

Начнем! Для начала на сервере Mysql создадим базу данных mychat  и в ней две таблицы chat - для переписки пользователей  и feed - для их оповещения, все как на скриншотах.

Скачиваем Connector/ODBC  и устанавливаем на сервере 1С.

Идем в конфигурацию 1С и в модуле обычного приложения  в процедуру "ПриНачалеРаботыСистемы" пропишем два обработчика ожидания. 

Для чата интервал 10 секунд, а для служебных сообщений 1 минута!


    ПодключитьОбработчикОжидания("ПроверитьНаличиеСообщенийПользователю",10,);
    ПодключитьОбработчикОжидания("ПроверитьНаличиеСлужебныхСообщений",60,);

И там же добавим к ним две процедуры.


Процедура ПроверитьНаличиеСлужебныхСообщений() Экспорт
РезультатПроверкиСообщений = ОбщийМодульЧат.ПроверитьСлужебныеСообщения();
Если Не РезультатПроверкиСообщений = "" Тогда
ПоказатьОповещениеПользователя("Новое сообщение от Администратора", ,РезультатПроверкиСообщений);   
КонецЕсли;
КонецПроцедуры
 
  Процедура ПроверитьНаличиеСообщенийПользователю() Экспорт
    РезультатПроверкиСообщений = ОбщийМодульЧат.ПроверитьНаличиеСообщенийСервер();
    Если Не РезультатПроверкиСообщений = "" Тогда
        Форма = Обработки.Чат.ПолучитьФорму("Форма");
        Форма.ЭлементыФормы.ЧатПоле.Значение = РезультатПроверкиСообщений;
        Форма.ЭлементыФормы.ЧатПоле.СоздатьКолонки();
    КонецЕсли;
КонецПроцедуры

Эти процедуры будут получать результат с общего модуля.

Создаем общий модуль ("ОбщийМодульЧат"), в его свойствах выставляем калки "Сервер" и "Вызов Сервера", чтобы все функции выполнялись на сервере, где у нас уже установлен Connector/ODBC.

Добавляем  функции!


/////Функция подключения к серверу MySQL/////
//Прописываем данные для подключения к БД
&НаСервере
  Функция ПолучитьConnectStringDBchat()
       
    server    = ""; //"localhost";
    user     = ""; // логин к базе mySql
    password= ""; // пароль к базе mySql
    database= ""; // имя базы
   
    ConnectString="Driver={MySQL ODBC 5.1 Driver};"
        + "Server=" + server
        + ";Database=" + database
        + ";User=" + user
        + ";Password=" + password
        + ";STMT=SET CHARACTER SET cp1251;"
        + ";Option=3;" ;    
    Возврат ConnectString;
   
КонецФункции
//////////////
// Проверяем наличие сообщений на сервере в таблице chat 
/// на начало и конец текущего дня
// записываем все в таблицу значений и возвращаем результат
// в процедуру ПроверитьНаличиеСообщенийПользователю , которая в свою очередь выведет результат в обработку
&НаСервере
Функция ПроверитьНаличиеСообщенийСервер() Экспорт   
    SQLiteObject = Новый COMОбъект("ADODB.Connection");
  SQLiteConnectionString = ПолучитьConnectStringDBchat();
  Попытка
      SQLiteObject.Open(SQLiteConnectionString);
  Исключение
          Сообщить(ОписаниеОшибки());
      Возврат "" ;
  КонецПопытки;
  RS = Новый COMОбъект("ADODB.RecordSet");
  Стр = "chat"; // таблица чат сообщений
    ДатаНачала = НачалоДня(ТекущаяДата());
    ДатаНачалаU = Формат(Число(ДатаНачала - Дата('19700101')),"ЧГ=0");
    ДатаКонца = КонецДня(ТекущаяДата());
    ДатаКонцаU = Формат(Число(ДатаКонца - Дата('19700101')),"ЧГ=0");
    RS.Open("SELECT data, author, text
    |FROM "+стр+" 
    |WHERE data > "+ДатаНачалаU+" 
    |AND data < "+ДатаКонцаU+"" , SQLiteObject);
 
  ТаблицаРезультат = новый ТаблицаЗначений;
  Для НомерСтолбца = 0 По Rs.Fields.Count-1 Цикл
  ИмяНовойКолонки = Rs.Fields(НомерСтолбца).Name;
    ТаблицаРезультат.Колонки.Добавить(ИмяНовойКолонки);
  КонецЦикла;
  Если Не Rs.eof Тогда
  rs.MoveFirst();
  КонецЕсли;
  Пока Не Rs.eof Цикл
  НоваяСтрока = ТаблицаРезультат.Добавить();
  Для каждого Колонка из ТаблицаРезультат.Колонки Цикл
  ИмяКолонки = Колонка.Имя;
                Если ИмяКолонки = "data" тогда
                Значение = Rs.Fields.Item(ИмяКолонки).Value ;
                Значение = дата(1970,1,1,1,0,0) + Значение; //преобразуем unixtime в дату
                Значение = Значение;
            Иначе
                Значение = Rs.Fields.Item(ИмяКолонки).Value ;
          Значение = Значение;
          КонецЕсли;       
  Если значение <> Null Тогда
  НоваяСтрока[ИмяКолонки] = Значение;
  КонецЕсли;
  КонецЦикла;
  rs.MoveNext();
        КонецЦикла;
  SQLiteObject.Close();
        Возврат ТаблицаРезультат;
КонецФункции
/////////////////
////Отправка сообщений на сервер из обработки "Чат" в таблицу chat
&НаСервере
Функция  ВыгрузкаChat(Текст) Экспорт   
    ConnectString=ПолучитьConnectStringDBchat();
    Connection = Новый COMОбъект("ADODB.Connection");
    Connection.open(ConnectString);   
    Дата=ТекущаяДата();
    Пользователь = Пользователи.ТекущийПользователь();
    Текст = Текст;
    Дата = Формат(Дата - Дата(1970,1,1,1,0,0), "ЧГ=0"); //переводим дату в unixtime 
    Попытка
        ТекстSQL = "insert INTO chat
    |(
    | author, 
    | data,
    | text
    |) VALUES (
    | '"+Пользователь+"',
    | '"+Дата+"',
    | '"+Текст+"'
    |);";
    ss=Connection.Execute(текстSQL);
    Connection.Close();
Исключение
        Сообщить(ОписаниеОшибки());
      Возврат "" ;
    КонецПопытки;   
КонецФункции
////////////////////
////Проверяем наличие сообщений для оповещения пользователя из таблицы feed
/// на начало и конец текущего дня
// возвращаем Значение
  &НаСервере
  Функция ПроверитьСлужебныеСообщения() Экспорт
   
    SQLiteObject = Новый COMОбъект("ADODB.Connection");
  SQLiteConnectionString = ПолучитьConnectStringDBchat();
  Попытка
      SQLiteObject.Open(SQLiteConnectionString);
  Исключение
              Сообщить(ОписаниеОшибки());
      Возврат "" ;
  КонецПопытки;
  RS = Новый COMОбъект("ADODB.RecordSet");
  Стр = "feed";
    ДатаНачала = НачалоДня(ТекущаяДата());
    ДатаНачалаU = Формат(Число(ДатаНачала - Дата('19700101')),"ЧГ=0");
    ДатаКонца = КонецДня(ТекущаяДата());
    ДатаКонцаU = Формат(Число(ДатаКонца - Дата('19700101')),"ЧГ=0");
    RS.Open("SELECT text
    |FROM "+стр+" 
    |WHERE data > "+ДатаНачалаU+" 
    |AND data < "+ДатаКонцаU+"" , SQLiteObject);
 
  Если Не Rs.eof Тогда
  rs.MoveFirst();
  КонецЕсли;
  Пока Не Rs.eof Цикл
    Значение = Rs.Fields.Item("text").Value ;
  rs.MoveNext();
    КонецЦикла;
  SQLiteObject.Close();
    Возврат Значение;
КонецФункции
//////////////
///////Отправка сообщений на сервер из внешней обработки "Оповещения" в таблицу feed
&НаСервере
Функция  ВыгрузкаСлужебныхСообщений(Текст) Экспорт
   
    ConnectString=ПолучитьConnectStringDBchat();
    Connection = Новый COMОбъект("ADODB.Connection");
    Connection.open(ConnectString);   
    Дата=ТекущаяДата();
    Пользователь = Пользователи.ТекущийПользователь();
    Текст = Текст;
    Дата = Формат(Дата - Дата(1970,1,1,1,0,0), "ЧГ=0");
    Попытка
       
        ТекстSQL = "insert INTO feed
    |( 
    | data,
    | text
    |) VALUES (
    | '"+Дата+"',
    | '"+Текст+"'
    |);";
    ss=Connection.Execute(текстSQL);
    Connection.Close();
Исключение
        Сообщить(ОписаниеОшибки());
      Возврат "" ;
    КонецПопытки;   
КонецФункции
////////////////////
/////Очищаем таблицу feed из внешней обработки "Оповещения"
//Чтобы у пользователя не выскакивало окно с оповещением 
&НаСервере
Функция УдалитьСообщенияОповещения () Экспорт
    SQLiteObject = Новый COMОбъект("ADODB.Connection");
  SQLiteConnectionString = ПолучитьConnectStringDBchat();
    SQLiteObject.Open(SQLiteConnectionString);
    Попытка
    ТекстSQL = "TRUNCATE TABLE feed ";
    SQLiteObject.Execute(текстSQL);
    Сообщить("Информация успешно удалена с сервера");
      Исключение
    Сообщить(ОписаниеОшибки());
      Возврат "" ;
  КонецПопытки;
  SQLiteObject.Close();
КонецФункции

Осталось теперь создать две обработки. Начнем с Чата!

Создаем обработку, добавляем реквизит "Текст" на форму кидаем ПолеВвода с этим реквизитом и ТабличноеПоле с именем "ЧатПоле".

Для кнопки "Выполнить" пишем следующую процедуру.


Процедура КнопкаВыполнитьНажатие(Кнопка)
    Если Не ЗначениеЗаполнено(Текст) Тогда
        Сообщить("А кто будет заполнять поле?");
        Возврат;
    Иначе
        ОбщийМодульЧат.ВыгрузкаChat(Текст);
    КонецЕсли;
    ЭлементыФормы.ПолеВвода1.Значение = "";
КонецПроцедуры

На этом все, добавляем обработку в конфигурацию!

Обработка оповещения добавляем реквизит "Текст" на форму кидаем ПолеВвода с этим реквизитом и еще одну кнопку "Удалить" для удаления сообщений с сервера.


    Процедура КнопкаВыполнитьНажатие(Кнопка)
    Текст = ЭлементыФормы.ПолеВвода1.Значение;
    Если Не ЗначениеЗаполнено(Текст) Тогда
        Сообщить("А кто будет заполнять поле?");
        Возврат;
    иначе
    ОбщийМодульЧат.ВыгрузкаСлужебныхСообщений(Текст);
    КонецЕсли;
    ЭлементыФормы.ПолеВвода1.Значение = "";
КонецПроцедур


Процедура УдалитьНажатие(Элемент)
    ОбщийМодульЧат.УдалитьСообщенияОповещения();
КонецПроцедуры

Вот результат, и спасибо всем за внимание!

Read Full Article