From c4d8128b67f0261c373bf15180f53f128a8bea4b Mon Sep 17 00:00:00 2001 From: merelendor Date: Fri, 31 Mar 2023 10:47:58 +0300 Subject: [PATCH] pdf generation with digital sign --- actions/questionnaireActions.js | 37 ++- .../forms/DigitalSignaturesList.js | 45 ++- .../forms/Form_2_Contacts/index.js | 8 +- .../forms/Form_3_Signer/index.js | 50 ++- .../forms/Form_4_Shareholders/index.js | 91 +++++- .../questionnaire/forms/Form_7_Check/index.js | 2 - lib/evo_anketa.pdf | Bin 0 -> 130893 bytes lib/evo_anketa_old.pdf | Bin 0 -> 163205 bytes lib/noto.ttf | Bin 0 -> 555264 bytes lib/roboto.ttf | Bin 0 -> 168644 bytes next.config.js | 2 +- package.json | 2 + pages/api/questionnaire/download.js | 293 +++++++++++++++++- reducers/initialState.js | 49 +-- yarn.lock | 35 ++- 15 files changed, 529 insertions(+), 85 deletions(-) create mode 100644 lib/evo_anketa.pdf create mode 100644 lib/evo_anketa_old.pdf create mode 100644 lib/noto.ttf create mode 100644 lib/roboto.ttf diff --git a/actions/questionnaireActions.js b/actions/questionnaireActions.js index 7cfe5e5..e3d98cd 100644 --- a/actions/questionnaireActions.js +++ b/actions/questionnaireActions.js @@ -3,6 +3,7 @@ import { Cookies } from 'react-cookie'; import Router from 'next/router'; import moment from 'moment'; import { nSQL } from "@nano-sql/core"; +import fileDownload from 'js-file-download'; import * as actionTypes from '../constants/actionTypes'; @@ -62,7 +63,7 @@ export const updateQuestionnaire = ({ dispatch, questionnaire }) => }); } -export const downloadQuestionnaire = () => +export const downloadQuestionnaire = (download = true) => { console.log("ACTION", "questionnaireActions", "downloadQuestionnaire()", ); @@ -72,21 +73,41 @@ export const downloadQuestionnaire = () => { let cookies = new Cookies(); let cookies_list = cookies.getAll(); - console.log("cookies_list", cookies_list); + const { questionnaire } = global.store.getState(); - axios.post(`${ process.env.NEXT_PUBLIC_INT_API_HOST }/questionnaire/check`, {}, { + console.log("questionnaire", questionnaire); + const { main, contacts, signatory_person, founded_persons, head_person, non_profit, } = questionnaire; + const playload = { main, contacts, signatory_person, founded_persons, head_person, non_profit, }; + console.log({ playload }); + +/* axios.post(`${ process.env.NEXT_PUBLIC_INT_API_HOST }/questionnaire/download`, { questionnaire: playload }, { headers: { "Authorization": `Bearer ${ cookies_list.jwt }`, }, - //withCredentials: true, + }) +*/ + axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/questionnaire/download`, { questionnaire: playload }, { + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/pdf' + }, + responseType: 'arraybuffer', }) .then((response) => { - console.log("downloadQuestionnaire", "response.data"); - console.log(response.data); - console.log("downloaded?"); + if(download) + { + console.log("downloadQuestionnaire", "response.data"); + fileDownload(response.data, response.headers.filename); + + resolve(); + } + else + { + resolve({ file: response.data, filename: response.headers.filename }); + } + //dispatch({ type: actionTypes.SUPPORT_APPEALS, data: { appeals: { list: response.data.appeals, new: response.data.new, } } }); - resolve(); }) .catch((error) => { diff --git a/components/questionnaire/forms/DigitalSignaturesList.js b/components/questionnaire/forms/DigitalSignaturesList.js index d42e862..2b41d5c 100644 --- a/components/questionnaire/forms/DigitalSignaturesList.js +++ b/components/questionnaire/forms/DigitalSignaturesList.js @@ -1,9 +1,11 @@ import React from "react"; import Link from "next/link"; -import { getCertificates, isPluginCryptoProInstalled } from "../../../utils/digital_signature"; import { SpinnerCircular } from "spinners-react"; import moment from "moment"; +import fileDownload from 'js-file-download'; +import { getCertificates, isPluginCryptoProInstalled, generateSignature } from "../../../utils/digital_signature"; +import { downloadQuestionnaire } from "../../../actions"; export default class DigitalSignaturesList extends React.Component { constructor(props) @@ -73,7 +75,42 @@ export default class DigitalSignaturesList extends React.Component _sign = () => { - alert("Подписание ЭЦП и отправка данных"); + downloadQuestionnaire(false) + .then(({ filedata, filename }) => + { + //let created_at = moment().format('DD-MM-yyyy'); + //let filename = `Коммерческое предложение №${this.props.proposal.proposalId} от ${createAt}.docx` + let file = new File([ filedata ], filename); + + console.log("this.state", this.state); + + generateSignature(file, this.state.certificate_selected.certificate) + .then(signature => { + console.log("signature"); + console.log(signature); + + fileDownload(signature, `${ filename }.sig`); + fileDownload(filedata, filename); + alert("Подписание ЭЦП прошло успешно."); + }); + }) + .catch((e) => + { + console.error("exception on sign"); + console.error(e); + + let errorsText = { + 'The action was cancelled by the user. (0x8010006E)': 'Подписание было отменено', + 'Key does not exist. (0x8009000D)': 'Сертификата не существует', + 'Keyset does not exist (0x80090016)': 'Набор ключей не существует', + 'File upload error': 'Ошибка загрузки файла', + 'Invalid algorithm specified. (0x80090008)': 'На вашем компьютере не установлена программа «КриптоПро CSP»', + 'The card cannot be accessed because the wrong PIN was presented. (0x8010006B)': 'Указанный пароль неверный' + } + + let errorText = errorsText[e.message] || 'Ошибка подписания файла'; + alert(errorText); + }); } render() @@ -105,8 +142,8 @@ export default class DigitalSignaturesList extends React.Component hidden="" id={ `certificate_${ certificate.index }` } name={ `certificate_${ certificate.index }` } - checked={ certificate_selected === certificate.index ? true : false } - onChange={ () => { this.setState({ certificate_selected: certificate.index }) } } + checked={ certificate_selected !== undefined && certificate_selected.index === certificate.index ? true : false } + onChange={ () => { this.setState({ certificate_selected: certificate }) } } />