- Catalogo: qualità di stampa, margini. ora è 300 DPI.

This commit is contained in:
Surya Paolo
2024-12-05 14:13:19 +01:00
parent 1cb5e6f1ad
commit 5c20e75b6a
20 changed files with 359 additions and 51 deletions

View File

@@ -368,6 +368,10 @@ export const shared_consts = {
Outcoming: 2,
},
CmdConvertPDF: {
RIDUCI_DIMENSIONI: 1,
},
Cmd: {
PROVINCE: 1,
COMUNI: 2,

View File

@@ -360,4 +360,11 @@
.q-img {
position: relative; /* Per la sovrapposizione */
z-index: 2; /* Posiziona l'immagine principale sopra l'ombra */
}
}
.border-box {
border-left: 1px solid lightgray;
border-top: 1px solid lightgray;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
}

View File

@@ -75,7 +75,7 @@
:class="[
'flex', // Classi comuni
'image-container',
{ 'shadow-2': options.in_3d }, // Classe condizionale
{ 'shadow-2': options.in_3d && !optcatalogo.pdf }, // Classe condizionale
scheda.testo_right.font?.posiz_text ===
costanti.POSIZ_TESTO.IN_BASSO
? 'flex-col'
@@ -120,8 +120,8 @@
:class="{
'book-image-fixed': complete,
'cursor-pointer': !complete,
'shadow-4': true,
'image-wrapper': optcatalogo.pdf,
'shadow-4': !optcatalogo.pdf,
'border-box': optcatalogo.pdf,
}"
:style="{
zIndex: 2,
@@ -175,7 +175,6 @@
costanti.POSIZ_TESTO.IN_BASSO
? '100%'
: scheda.testo_right.font?.perc_text ?? '50%',
textAlign: 'center',
marginTop:
scheda.testo_right.font?.posiz_text ===
costanti.POSIZ_TESTO.IN_BASSO
@@ -260,7 +259,6 @@
v-if="scheda.testo_bottom && scheda.testo_bottom.contenuto"
:style="{
width: '100%',
textAlign: 'center',
}"
>
<div

View File

@@ -91,12 +91,32 @@ export default defineComponent({
}
}
function incrementValuePlus1() {
if (!sliderValue.value) {
sliderValue.value = '1'
} else {
sliderValue.value = (parseFloat(sliderValue.value) + 1) + ''; // Aumenta il valore
}
}
function decrementValueMinus1() {
if (sliderValue.value === '0') {
sliderValue.value = ''
} else if (!sliderValue.value) {
// niente
} else {
sliderValue.value = (parseFloat(sliderValue.value) - 1) + ''; // Diminuisci il valore
}
}
return {
t,
shared_consts,
sliderValue,
incrementValue,
decrementValue
decrementValue,
decrementValueMinus1,
incrementValuePlus1,
}
}
})

View File

@@ -6,16 +6,25 @@
@click="decrementValue"
:disable="disable || !sliderValue"
flat
dense
/>
<q-btn
label="-1"
@click="decrementValueMinus1"
:disable="disable || !sliderValue"
flat
dense
/>
<q-input
style="width: 150px"
style="width: 170px"
dense
v-model="sliderValue"
filled
:disable="disable"
>
</q-input>
<q-btn icon="fas fa-plus" @click="incrementValue" :disable="disable" flat />
<q-btn dense label="+1" @click="incrementValuePlus1" :disable="disable" flat />
<q-btn dense icon="fas fa-plus" @click="incrementValue" :disable="disable" flat />
<q-slider
:disable="disable"

View File

@@ -2516,9 +2516,6 @@ body.body--dark {
align-items: center; /* Allineamento verticale al centro */
padding: 0px;
flex-grow: 0; /* Opzionale: permette agli elementi di crescere uniformemente */
break-inside: avoid;
page-break-inside: avoid;
}
.card-page {
@@ -2526,6 +2523,12 @@ body.body--dark {
page-break-after: always;
}
.card-page::after {
content: '';
display: block;
page-break-after: always;
}
.card-row {
display: flex;
justify-content: center;

View File

View File

@@ -0,0 +1,135 @@
import { CMyPage } from '../../../components/CMyPage/index'
import { shared_consts } from '@src/common/shared_vuejs'
import { tools } from '@src/store/Modules/tools'
import axios from 'axios'
import { defineComponent, ref, onMounted } from 'vue'
import { useI18n } from '@src/boot/i18n'
import { useUserStore } from '@store/UserStore'
import { useGlobalStore } from '@store/globalStore'
import { useQuasar } from 'quasar'
import { IParamsQuery } from 'model'
import { toolsext } from '@store/Modules/toolsext'
import { StringDecoder } from 'string_decoder'
import { GlobalConfig } from '@src/common'
export default defineComponent({
name: 'convertPDF',
components: { CMyPage },
setup(props, { emit }) {
const $q = useQuasar()
const { t } = useI18n()
const userStore = useUserStore()
const globalStore = useGlobalStore()
const arrSector = ref(<any[]>[])
const arrSectorGood = ref(<any[]>[])
const arrSkill = ref(<any[]>[])
const arrGood = ref(<any[]>[])
const importasulserver = ref(false)
const skipfirstrow = ref(true)
const incaricamento = ref(false)
const checkAggiornaQta = ref(false)
const inputfile = ref('')
const risultato = ref('')
const risraw = ref('')
const width = ref('8.88')
const height = ref('12.31')
const cosafare = ref(shared_consts.CmdConvertPDF.RIDUCI_DIMENSIONI)
const caricaDatiToggle = ref(false)
const pdfFile = ref(<any>null);
const compressione = ref('prepress')
const ListaCmd = ref(
[
{
label: 'Riduci Dimensioni',
value: shared_consts.CmdConvertPDF.RIDUCI_DIMENSIONI,
},
]
)
const ListaCompressione = ref(
[
{
label: '[Nessuna]',
value: '',
},
{
label: '[screen - Buona per la visualizzazione su schermo; bassa qualità e dimensione del file ridotta]',
value: 'screen',
},
{
label: '[Ebook - Ottimizza il PDF per la lettura su ebook; qualità media e dimensione media]',
value: 'ebook',
},
{
label: '[Printer - Ottimizza il PDF per la stampa di qualità; migliora la risoluzione rispetto a /ebook.]',
value: 'printer',
},
{
label: '[Prepress - Ottimizza per la stampa di alta qualità; ideale per progetti di stampa professionali.]',
value: 'prepress',
},
{
label: '[Default - Usa impostazioni predefinite; generalmente fornisce un buon equilibrio tra qualità e dimensione]',
value: 'default',
},
]
)
function caricadati() {
}
function created() {
inputfile.value = ''
if (caricaDatiToggle.value) {
caricadati()
}
}
const uploadPdf = (event: any) => {
pdfFile.value = event.target.files[0];
};
const convertPdf = async () => {
globalStore.convertPdf(pdfFile.value, width.value, height.value, compressione.value)
}
const execPdf = async () => {
if (cosafare.value === shared_consts.CmdConvertPDF.RIDUCI_DIMENSIONI) {
convertPdf()
}
}
onMounted(created)
return {
shared_consts,
ListaCmd,
cosafare,
convertPdf,
uploadPdf,
width,
height,
execPdf,
ListaCompressione,
compressione,
}
}
})

View File

@@ -0,0 +1,40 @@
<template>
<div class="column">
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
rounded
outlined
v-model="cosafare"
:options="ListaCmd"
label="Operazione"
emit-value
map-options
>
</q-select>
<q-input v-model="width" label="Width:" filled></q-input>
<q-input v-model="height" label="Height:" filled></q-input>
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
rounded
outlined
v-model="compressione"
:options="ListaCompressione"
label="Compressione"
emit-value
map-options
>
</q-select>
<input type="file" @change="uploadPdf" />
<q-btn @click="execPdf" label="Esegui"></q-btn>
<br />
</div>
</template>
<script lang="ts" src="./convertPDF.ts">
</script>
<style lang="scss" scoped>
@import './convertPDF.scss';
</style>

View File

@@ -67,7 +67,20 @@ function getRoutesAd(site: ISites) {
inmenu: true,
submenu: true,
onlyAdmin: true
}
},
{
active: true,
order: 1040,
path: '/admin/convertPDF',
materialIcon: 'event_seat',
name: 'otherpages.manage.convertPDF',
component: () => import('@/rootgen/admin/convertPDF/convertPDF.vue'),
level_parent: 0.0,
level_child: 0.5,
inmenu: true,
submenu: true,
onlyAdmin: true
},
]

View File

@@ -66,6 +66,7 @@ const msg_enUs = {
nessuno: 'None',
sendpushnotif: 'Invia Msg Push',
importfile: 'Importa File',
convertPDF: 'Converti PDF',
},
messages: {
menu: 'Your Messages',

View File

@@ -177,6 +177,7 @@ const msg_it = {
nessuno: 'Nessuno',
sendpushnotif: 'Invia Messaggi',
importfile: 'Importa File',
convertPDF: 'Converti PDF',
},
messages: {
menu: 'I tuoi Messaggi',

View File

@@ -4,15 +4,16 @@ import axios, {
import { Api } from '@api'
import * as Types from '@src/store/Api/ApiTypes'
async function sendRequest(url: string, method: string, mydata: any) {
// if (process.env.DEBUG) console.log('sendRequest', method, url)
async function sendRequest(url: string, method: string, mydata: any, myformdata?: any, responsedata?: any) {
console.log('sendRequest', method, url, mydata)
let request
if (method === 'GET') request = Api.get(url, mydata)
else if (method === 'POST') request = Api.post(url, mydata)
else if (method === 'DELETE') request = Api.Delete(url, mydata)
else if (method === 'PUT') request = Api.put(url, mydata)
else if (method === 'PATCH') request = Api.patch(url, mydata)
if (method === 'GET') request = Api.get(url, mydata, responsedata)
else if (method === 'POST') request = Api.post(url, mydata, responsedata)
else if (method === 'postFormData') request = Api.postFormData(url, myformdata, responsedata)
else if (method === 'DELETE') request = Api.Delete(url, mydata, responsedata)
else if (method === 'PUT') request = Api.put(url, mydata, responsedata)
else if (method === 'PATCH') request = Api.patch(url, mydata, responsedata)
// @ts-ignore
const req: Promise<Types.AxiosSuccess | Types.AxiosError> = request

View File

@@ -47,7 +47,7 @@ export const addAuthHeaders = () => {
// delete axiosInstance.defaults.headers.Authorization
//}
async function Request(type: string, path: string, payload: any): Promise<Types.AxiosSuccess | Types.AxiosError | undefined> {
async function Request(type: string, path: string, payload: any, responsedata?: any): Promise<Types.AxiosSuccess | Types.AxiosError | undefined> {
let ricevuto = false
const userStore = useUserStore()
@@ -65,6 +65,7 @@ async function Request(type: string, path: string, payload: any): Promise<Types.
'x-auth': userStore.x_auth_token,
'x-refrtok': userStore.refreshToken,
},
...responsedata,
})
ricevuto = true
// console.log('Request Response: ', response)
@@ -119,10 +120,12 @@ async function Request(type: string, path: string, payload: any): Promise<Types.
'x-auth': userStore.x_auth_token,
'x-refrtok': userStore.refreshToken,
},
...responsedata,
})
ricevuto = true
return new Types.AxiosSuccess(response.data, response.status)
} else if (type === 'postFormData') {
console.log('postFormData', payload)
response = await axiosInstance.post(path, payload, {
baseURL: globalStore.getServerHost(),
headers: {
@@ -130,6 +133,7 @@ async function Request(type: string, path: string, payload: any): Promise<Types.
'x-auth': userStore.x_auth_token,
'x-refrtok': userStore.refreshToken,
},
...responsedata,
})
ricevuto = true
return new Types.AxiosSuccess(response.data, response.status)

View File

@@ -37,43 +37,43 @@ function ReceiveResponsefromServer(tablesync: string, nametab: string, method: s
// const algoliaApi = new AlgoliaSearch()
export const Api = {
async post(path: string, payload?: any) {
async post(path: string, payload?: any, responsedata?: any) {
const globalStore = useGlobalStore()
globalStore.connData.downloading_server = 1
globalStore.connData.uploading_server = 1
return Request('post', path, payload)
return Request('post', path, payload, responsedata)
},
async postFormData(path: string, payload?: any) {
async postFormData(path: string, payload?: any, responsedata?: any) {
const globalStore = useGlobalStore()
globalStore.connData.uploading_server = 1
globalStore.connData.downloading_server = 1
return Request('postFormData', path, payload)
return Request('postFormData', path, payload, responsedata)
},
async get(path: string, payload?: any) {
async get(path: string, payload?: any, responsedata?: any) {
const globalStore = useGlobalStore()
globalStore.connData.downloading_server = 1
globalStore.connData.uploading_server = 0
return Request('get', path, payload)
return Request('get', path, payload, responsedata)
},
async put(path: string, payload?: any) {
async put(path: string, payload?: any, responsedata?: any) {
const globalStore = useGlobalStore()
globalStore.connData.uploading_server = 1
return Request('put', path, payload)
return Request('put', path, payload, responsedata)
},
async patch(path: string, payload?: any) {
async patch(path: string, payload?: any, responsedata?: any) {
const globalStore = useGlobalStore()
globalStore.connData.uploading_server = 1
return Request('patch', path, payload)
return Request('patch', path, payload, responsedata)
},
async Delete(path: string, payload: any) {
async Delete(path: string, payload: any, responsedata?: any) {
const globalStore = useGlobalStore()
globalStore.connData.uploading_server = 1
return Request('delete', path, payload)
return Request('delete', path, payload, responsedata)
},
async checkSession({ token, refresh_token }: any) {
@@ -131,7 +131,7 @@ export const Api = {
},
async SendReqBase(url: string, method: string, mydata: any, setAuthToken = false, evitaloop = false): Promise<Types.AxiosSuccess | Types.AxiosError> {
async SendReqBase(url: string, method: string, mydata: any, setAuthToken = false, evitaloop = false, myformdata?: any, responsedata?: any): Promise<Types.AxiosSuccess | Types.AxiosError> {
const mydataout = {
...mydata,
keyappid: process.env.PAO_APP_ID,
@@ -145,7 +145,7 @@ export const Api = {
userStore.setServerCode(tools.EMPTY)
userStore.setResStatus(0)
return new Promise((resolve, reject) => sendRequest(url, method, mydataout)
return new Promise((resolve, reject) => sendRequest(url, method, mydataout, myformdata, responsedata)
.then((res) => {
setTimeout(() => {
if (method === 'get') {
@@ -245,10 +245,12 @@ export const Api = {
setAuthToken = false,
evitaloop = false,
retryCount = 3,
retryDelay = 5000
retryDelay = 5000,
myformdata?: any,
responsedata?: any,
): Promise<Types.AxiosSuccess | Types.AxiosError> {
try {
const response = await this.SendReqBase(url, method, mydata, setAuthToken, evitaloop);
const response = await this.SendReqBase(url, method, mydata, setAuthToken, evitaloop, myformdata, responsedata);
return response;
} catch (error: any) {
if (retryCount > 0) {
@@ -262,7 +264,9 @@ export const Api = {
setAuthToken,
evitaloop,
retryCount - 1,
retryDelay
retryDelay,
myformdata,
responsedata,
);
}
throw error;

View File

@@ -380,16 +380,24 @@ export const tools = {
SelectListFormatPDF: [
{ label: 'a4 (mm)', value: [210, 297] },
{ label: '22,60 x 31,26 (in mm)', value: [226.0, 312.6] },
{ label: '22,60 x 31,31 (in mm)', value: [226.0, 313.1] },
{ label: '22,60 x 31,20 (in mm)', value: [226.0, 312.0] },
{ label: '22,60 x 31,10 (in mm)', value: [226.0, 311.0] },
],
SelectListScalePDF: [
{ label: 'Normale (100 DPI)', value: 1 },
{ label: 'Medio (200 PDI)', value: 2 },
{ label: 'Alto (300 PDI)', value: 3 },
{ label: 'Normale (72 DPI)', value: 1 },
{ label: 'Medio (144 PDI)', value: 2 },
{ label: 'Medio-Alta (180 PDI)', value: 2.5 },
{ label: 'Medio-Alta2 (201 PDI)', value: 2.8 },
{ label: 'Alto (216 PDI)', value: 3 },
{ label: 'Alto2 (288 PDI)', value: 4 },
],
SelectListQualityPDF: [
{ label: 'Bassa (1 scale)', value: 1 },
{ label: 'Bassa-Norm (1.5 scale)', value: 1.5 },
{ label: 'Normale (2 scale)', value: 2 },
{ label: 'Normale2.5 (2.5 scale)', value: 2.5 },
{ label: 'Media (3 scale)', value: 3 },
{ label: 'Elevata (4 scale)', value: 4 },
],
@@ -8629,6 +8637,20 @@ export const tools = {
},
removeFileExtension(filename: string) {
// Trova l'ultima occorrenza del punto nel nome del file
const lastDotIndex = filename.lastIndexOf('.');
// Se non c'è un punto o il punto è all'inizio del nome file,
// restituisci il nome file originale
if (lastDotIndex === -1 || lastDotIndex === 0) {
return filename;
}
// Altrimenti, restituisci la parte del nome file prima dell'ultimo punto
return filename.substring(0, lastDotIndex);
},
removeescape(inputString: string): string {
return inputString.replace('\\', '').replace(/"/g, '')
},

View File

@@ -2283,6 +2283,56 @@ export const useGlobalStore = defineStore('GlobalStore', {
})
},
async execConvertPDF(paramquery: any) {
// console.log('paramquery', paramquery)
return Api.SendReq('/admin/convert-pdf', 'postFormData', {}, false, false, 1, 5000, paramquery, { responseType: 'blob' })
.then((res) => {
return res.data
}).catch((error) => {
return false
})
},
async convertPdf(pdfFile: any, width: string, height: string, compressione: string) {
try {
if (!pdfFile) {
console.error('No PDF file selected');
return;
}
const filenameToDownload = tools.removeFileExtension(pdfFile.name) + '-output.pdf'
const formData = new FormData();
if (pdfFile instanceof File) {
formData.append('pdf', pdfFile);
}
formData.append('width', width); // Dimensione del PDF in cm
formData.append('height', height); // Dimensione del PDF in cm
formData.append('compressione', compressione);
const response = await this.execConvertPDF(formData)
if (response) {
const blob = new Blob([response], { type: 'application/pdf' });
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.setAttribute('download', filenameToDownload);
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(downloadUrl);
} else {
console.error('No data returned from the server.');
}
} catch (error) {
console.error('Error converting PDF:', error);
}
},
async saveServerMysql(paramquery: any) {
return Api.SendReq('/admin/mysql', 'POST', paramquery)
.then((res) => {

View File

@@ -100,6 +100,7 @@ body {
.book-descr-estesa {
font-family: 'DINPro', sans-serif;
font-size: calc(14 * var(--scalecatalog) * 1px);
text-align: justify !important;
}
.book-link{

View File

@@ -769,8 +769,8 @@ export default defineComponent({
const element = document.getElementById('pdf-content')
const opt = {
margin: [
props.optcatalogo.printable ? (parseFloat(props.optcatalogo.areadistampa!.margini?.left) || defaultMargin) : defaultMargin,
props.optcatalogo.printable ? (parseFloat(props.optcatalogo.areadistampa!.margini?.top) || defaultMargin) : defaultMargin,
props.optcatalogo.printable ? (parseFloat(props.optcatalogo.areadistampa!.margini?.left) || defaultMargin) : defaultMargin,
props.optcatalogo.printable ? (parseFloat(props.optcatalogo.areadistampa!.margini?.bottom) || defaultMargin) : defaultMargin,
props.optcatalogo.printable ? (parseFloat(props.optcatalogo.areadistampa!.margini?.right) || defaultMargin) : defaultMargin
],
@@ -791,6 +791,7 @@ export default defineComponent({
compress: props.optcatalogo.areadistampa!.compress,
},
enableLinks: true,
pagebreak: { mode: 'avoid-all', before: '.card-page' }
}
console.log('opt di stampa', opt)

View File

@@ -286,15 +286,9 @@
<div
v-if="containsProducts(page)"
:class="{
'fixed-width': getWidthPagina(
optcatalogo,
recscheda.scheda
),
'fixed-height': getHeightPagina(
optcatalogo,
recscheda.scheda
),
'card-page': true,
'fixed-width': true,
'fixed-height': true,
'card-page': false,
}"
:style="
generateStylePageScheda(