Дружба трех друзей 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

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

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

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

Комментарии (7)


  1. scronheim
    29.11.2021 14:43

    <offtop>Вы вроде бы используете стрелочные функции в JS, но при этом не используете шаблонные строки. Выглядит странно и не красиво (имхо)</offtop>


  1. GreekIgor Автор
    29.11.2021 16:40

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


  1. bouncycastle
    29.11.2021 21:02

    Я бы не советовал брать axios. Стандартный fetch не уступает по функционалу и его более чем достаточно для данного проекта.


  1. chuikoffru
    30.11.2021 20:41
    +1

    Если есть сложности с английским, пользуйтесь Google translate. Меня сразу сразило сокращение Aut, как будто out, но с ошибкой, и не понятно почему out, если речь идёт об authenticate, и сократить можно auth


  1. chuikoffru
    30.11.2021 20:42
    +1

    Попробуйте async/await, код будет чище. У axios по умолчанию get используется, поэтому можно писать axios(url)


  1. chuikoffru
    30.11.2021 20:44
    +1

    Но вот идея передавать логин и пароль через get в url, прям таки неудачная.


    1. GreekIgor Автор
      02.12.2021 08:33

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