Задать вопрос
Ответы пользователя по тегу Laravel
  • Как реализовать функционал подписи документа с помощью CryptoPro на Laravel?

    @vlog
    Недавно реализовывал этот функционал, подписывал файлы, которые уже загружены на сервер. Сама подпись может быть реализована только на фронте и по-сути это вопрос фронта, кроме CryptoPro Browser Plug-in ничего особо не нужно, но я для удобства использовал эту библиотеку.

    С помощью этих функций реализовал создание подписи:

    import {
        createAttachedSignature,
        createDetachedSignature,
        createHash,
        createXMLSignature,
        getSystemInfo,
        getUserCertificates
    } from "crypto-pro";
    
    // В this.cert.thumbprint лежит выбранный пользователем thumbprint
    
    sign(url){
    
                if(!this.cert.thumbprint){
                    alert('Подпись не выбрана. Выберите подпись.');
                    return;
                }
               
                this.signFile = section;
    
                let self = this;
    
                // В моём случае пользователь не загружал файлы для подписания, а подписывал уже имевшиеся на сервере, поэтому в эту функцию передаётся ссылка на файл, функция получает его, обрабатывает и подписывает
                fetch(url)
                    .then(res => res.blob()) // Gets the response and returns it as a blob
                    .then(blob => {
                        // Here's where you get access to the blob
                        // And you can use it for whatever you want
                        // Like calling ref().put(blob)
                  
                        var oFReader = new FileReader();
                        oFReader.readAsArrayBuffer(blob);
    
                        // javascript имеет событийную модель, когда процесс чтения завершиться продолжаем исполнять сценарий
                        oFReader.onload = function(oFREvent) {
                            let sBase64Data = this.result;
                            createHash(sBase64Data).then(self.createSignature.bind(null, sBase64Data), function (hashError) {
                                //
                            });
    
                        };
                    });
    
            },
              createSignature(message, hash){
                let self = this;
    
                var thumbprint = this.cert.thumbprint,
                    signatureType = 'detached',
                    signaturePromise;
    
                switch (signatureType) {
                    case 'attached':
                        signaturePromise = createAttachedSignature(thumbprint, message);
                        break;
                    case 'xml':
                        signaturePromise = createXMLSignature(thumbprint, message);
                        break;
                    case 'detached':
                        signaturePromise = createDetachedSignature(thumbprint, hash);
                        break;
                }
                
                signaturePromise.then(function (signature) {
                    axios.post(route('addSign'), {
                        fileSectionId: self.signFile,
                        signature: signature, // Тут отправлял текст подписи и уже на сервере сохранял её в файл .sign
                        certInfo: self.cert,
                    })
                        .then(function (data){
                            alert('Создание подписи завершилось успехом');
                        });
                }, function (error) {
                    alert('Создание подписи завершилось с ошибкой. Подпись не создана.');
                });
            },


    Когда всё сделаете, обязательно проверьте действительность подписи на госуслугах, чтобы понять, что всё работает корректно.
    Остальное по формированию PDF и сохранению на сервере найдёте сами.

    PS Не бойтесь пользоваться Интернетом :)
    Ответ написан
  • Можно ли как то оптимизировать запросы в контроллере?

    @vlog
    Я, конечно, не суперэксперт, но, мне кажется, у вас не особо громоздкий код в этом месте. Я бы сделал так:

    Цикл с суммой можно заменить этим:
    $sumBalance = $user->sum('balance');
    Подробнее о коллекциях и методах можно почитать тут. Но это если вам будет нужна $user в чистом виде в представлении, если они не будут Вам нужны, то можно вообще не запрашивать всех пользователей из бд, а использовать агрегатную функцию sum()

    $ordersWin и $ordersAllWinидентичны, не понимаю в чем разница. Если хотите оптимизировать запросы, то можно сначала получить записи со статусами 1 и 2 с помощью одного запроса, а затем группировать по статусам используя метод groupBy.

    Кроме того, возможно, Вы специально скрыли это, чтобы вопрос не был большим, но Ваши данные не передаются в приложение сейчас. Для того, чтобы они передавались Вы должны во втором аргументе render передать массив с данными:
    Inertia::render('Admin/Index', [
    'key' => $value,
    ]);


    Рекомендую почитать о коллекциях, там есть полезные вещи. Также, если хотите оптимизировать взаимодействие с бд, рекомендую использовать метод select и запрашивать только те столбцы, которые Вам нужны.
    Ответ написан
    Комментировать