Как я Подружил React и сканер HP LJ M127

от автора

Дружба трех друзей React, Delphi, HP LJ M127

Сегодня я расскажу вам историю дружбы трех друзей или если по простому то как я , мне пришла идея подружить веб с железом.

Начну наверное с того что все началось с написания софтверного приложения на delphi для сканирования документов и сохранения их blob данных в БД MSSQL SERVER 20212, ниже я приведу скриншот этого приложения, но как говорится в заголовке моей статьи сегодня речь пойдет, о другом приложении

Вообще идея пришла с того что хотелось сделать приложение, которое можно было запускать на любом компьютере, но тут как раз и появилась первая проблема, reactjs как и все веб фреймворки не работает с железом с драйверами, и тут на помощь пришел мои опыт работы с высокоуровневым языком программирования Delphi

Приложение на React

Представляю вашему вниманию страницу входа авторизации

Авторизация у меня по сути построена на двух функциях, одна функция это проверка авторизовался ли ранее этот пользователь, а вторая функцию уже авторизует пользователя

    ReallyAut=()=>     {         axios.get(Conf.API_URL+'user/really_aut/'+localStorage.getItem('hash'))             .then(res => {                 const data= res.data;                 let autentificate = data.autentificate;                 this.setState({autentificate : autentificate.success});                  this.props.aut(data.data.hash,data.success,data.data.username);                 this.props.autentificate(autentificate);              })      }

Данная функция как раз и занимается проверкой авторизован ли пользователь, эту функцию я вызываю в жизненном цикле react в ComponentDidMount ( эта функция выполняется после добавления объекта в дерево DOM) и конечно же я использую hash значения для работы с авторизациями

    Autorize = (event) => {         event.preventDefault();          let passwd = this.passwdRef.current.value;         let login = this.loginRef.current.value;         Toast.loading('Ожидание ответа....');         axios.get(Conf.API_URL+'user/autorize/'+login+'/'+passwd)             .then(res => {                  const data = res.data;                 Toast.hide();                 if(data.success){                     this.props.aut(data.token,data.success,data.name);                     localStorage.setItem('hash',data.token);                     localStorage.setItem('userName',data.token);                 } else                 {                     NotificationManager.error('Неверный логин или пароль, повторите ввод','Ошибка авторизации',3000);                 }              }).catch(err => {             if (err.response) {                 // client received an error response (5xx, 4xx)             } else if (err.request) {                 // client never received a response, or request never left             } else {                 // anything else             }            NotificationManager.error('Нет доступа....','Ошибка',3000);             console.log(err);             Toast.hide();         });       }

Ну вот мы и добрались до второй функции которая авторизует нас на сервере и выдает нам token

Главная форма имеет следующий вид, и как видно из скриншота позволяет нам в быстром наборе, выбирать заказчика и исполнителя, но основной функционал заключается в другом, а именно в сканировании и сохранении документа, побочные функции это удаление, перемещение , добавление сканированных документов

В общем уже заполненная форма сканированными документами, как видно на скриншоте их можно перемещать удалять

Как в общем производится сканирование, тут в принципе все просто, в программе на DELPHI которая сидит в трее заключена вся сила, а именно это связь со сканером HP LJ M127 , приложение закрепляет на порту слушатель , теперь перейдем к приложению на Delphi

Приложение Delphi

Опишем основные объекты, один из которых это объект который хранит в себе информацию об отсканированных изображения, тут основная хитрость в том чтобы хранить изображение в зашифрованном виде в виде строки чтобы удобно ее передавать и хранить

type   TScanImage = class(Tobject)   public     Image: TBitmap;     thumbnail: TJPEGImage;     StreamBitmap: TMemoryStream;     base64_image: String;     sended: Byte;     heigh: Integer;     width: Integer;     date_scan: TDateTime;     constructor Create(zimg: TBitmap; zh, zw: Integer; zds: TDateTime);   end;

Второй объект нужен для информирования нашего веб приложения о текущих задачах которые выполняет наше приложение, событии всего несколько

  • Событии нету

  • Сканирование Документа

  • Поворот картинки

  • Конвертация в PDF

  • Сохранение на сервер

type   TEvents = class(Tobject)   public     procedure SetEvent(EventCode: Byte; EventStatus: Byte;       EventData: TJSONArray);     procedure SetEventName(EventName: String; EventCode: Byte);     procedure SetStatusEvent(EventStatus: Byte);     procedure SetEventData(EventData: TJSONArray);      function GetEvent: TJSONObject;    private     constructor Create();    protected     event_name: String;     event_code: Byte;     event_status: Byte;     event_date: Int64;     event_data: TJSONArray;     event_message: String;    end;

То есть сам принцип дружбы заключается в звене которое выполняет наше приложение на Delphi , это происходит так

1. Веб приложение на React посредством http запросов (через axios) дает команду на сканирование документа, приложение на Delphi слушает порт и получает команду начинает выполнять и записывает в события что происходит в данный момент в приложении на delphi

2. Веб приложение через определенный промежуток запрашивает статус задачи которая выполняется или уже выполнилась

3. Приложение на Delphi когда завершила сканирование документа (Это может быть и автоподачик и ручное сканирование) записывает в статус события объекты которые отсканировала и при запросе от веб приложения их отдает

Вернемся к веб приложению на ReactJS

На данном скриншоте представлены документы которые уже отсканированы и их можно просмотреть, удалить

Просмотр документа с возможностью его загрузки

Удаление документа


ссылка на оригинал статьи https://habr.com/ru/articles/592191/