ver: 1.1.21:
- Lista dei Cataloghi - Gestione Cataloghi in base alla configurazione
This commit is contained in:
@@ -20,7 +20,7 @@ PUBLIC_VAPI_KEY="BGXRf1TgcqocqD6J7qnRgCG7AvM2lxAoW7peb7UEzB4SxBb6DxGRdJ0UvD9ewnr
|
||||
PRIVATE_VAPI_KEY="St9UMzcS76Q9yKG6RInAuYydYjFRliqwHTJY3A5wjO0"
|
||||
GCM_API_KEY="AIzaSyD7w1jztfVV05mX1iyxoI-r1pZWxuxdUK8"
|
||||
PATH_CERT_KEY=key.pem
|
||||
PATH_SERVER_CRT=cert.pem
|
||||
PATH_SERVER_CRT=fullchain.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
PROD=1
|
||||
|
||||
@@ -22,10 +22,8 @@ VAPI_KEY_SUBJECT="mailto:surya@riso.app"
|
||||
PUBLIC_VAPI_KEY="BJgo8XR_upbnbMLWgCAUELo6DK7dRXffYAnFOxbaMMz5favBgcQBKT-eISqouO-jRad4Sw8l5nd2wCF6KorGiTc"
|
||||
PRIVATE_VAPI_KEY="LVpFDJuKscdHuQr5pe20dFuYuWX1-ZRb6x72PP-Pp4I"
|
||||
GCM_API_KEY="AIzaSyD7w1jztfVV05mX1iyxoI-r1pZWxuxdUK8"
|
||||
PATH_CERT_KEY=key.pem
|
||||
PATH_SERVER_CRT=cert.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
PATH_CERT_KEY=privkey.pem
|
||||
PATH_SERVER_CRT=fullchain.pem
|
||||
PROD=1
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=iUUb38v23jjDFaosWj92axkBOXCQ
|
||||
|
||||
@@ -19,10 +19,8 @@ VAPI_KEY_SUBJECT="mailto:surya@riso.app"
|
||||
PUBLIC_VAPI_KEY="BGXRf1TgcqocqD6J7qnRgCG7AvM2lxAoW7peb7UEzB4SxBb6DxGRdJ0UvD9ewnrB9KrSrh0-aDCODXBm7sZ1DDs"
|
||||
PRIVATE_VAPI_KEY="St9UMzcS76Q9yKG6RInAuYydYjFRliqwHTJY3A5wjO0"
|
||||
GCM_API_KEY="AIzaSyD7w1jztfVV05mX1iyxoI-r1pZWxuxdUK8"
|
||||
PATH_CERT_KEY=key.pem
|
||||
PATH_SERVER_CRT=cert.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
PATH_CERT_KEY=privkey.pem
|
||||
PATH_SERVER_CRT=fullchain.pem
|
||||
PROD=1
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=iUUb38v23jjDFaosWj92axkBOXCQ
|
||||
|
||||
@@ -23,7 +23,7 @@ PUBLIC_VAPI_KEY="BJgo8XR_upbnbMLWgCAUELo6DK7dRXffYAnFOxbaMMz5favBgcQBKT-eISqouO-
|
||||
PRIVATE_VAPI_KEY="LVpFDJuKscdHuQr5pe20dFuYuWX1-ZRb6x72PP-Pp4I"
|
||||
GCM_API_KEY="AIzaSyD7w1jztfVV05mX1iyxoI-r1pZWxuxdUK8"
|
||||
PATH_CERT_KEY=key.pem
|
||||
PATH_SERVER_CRT=cert.pem
|
||||
PATH_SERVER_CRT=fullchain.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
PROD=0
|
||||
|
||||
@@ -20,7 +20,7 @@ PUBLIC_VAPI_KEY="BGXRf1TgcqocqD6J7qnRgCG7AvM2lxAoW7peb7UEzB4SxBb6DxGRdJ0UvD9ewnr
|
||||
PRIVATE_VAPI_KEY="St9UMzcS76Q9yKG6RInAuYydYjFRliqwHTJY3A5wjO0"
|
||||
GCM_API_KEY="AIzaSyD7w1jztfVV05mX1iyxoI-r1pZWxuxdUK8"
|
||||
PATH_CERT_KEY=key.pem
|
||||
PATH_SERVER_CRT=cert.pem
|
||||
PATH_SERVER_CRT=fullchain.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
PROD=0
|
||||
|
||||
@@ -21,7 +21,7 @@ PUBLIC_VAPI_KEY="BGXRf1TgcqocqD6J7qnRgCG7AvM2lxAoW7peb7UEzB4SxBb6DxGRdJ0UvD9ewnr
|
||||
PRIVATE_VAPI_KEY="St9UMzcS76Q9yKG6RInAuYydYjFRliqwHTJY3A5wjO0"
|
||||
GCM_API_KEY="AIzaSyD7w1jztfVV05mX1iyxoI-r1pZWxuxdUK8"
|
||||
PATH_CERT_KEY=key.pem
|
||||
PATH_SERVER_CRT=cert.pem
|
||||
PATH_SERVER_CRT=fullchain.pem
|
||||
PATH_SSL_ROOT_PEM=root.pem
|
||||
PATH_SSL_CHAIN_PEM=chain.pem
|
||||
PROD=0
|
||||
|
||||
@@ -4,6 +4,8 @@ const Schema = mongoose.Schema;
|
||||
const tools = require('../tools/general');
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
const { IImg } = require('../models/myscheda');
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
|
||||
@@ -13,22 +15,6 @@ mongoose.plugin(schema => {
|
||||
schema.options.usePushEach = true
|
||||
});
|
||||
|
||||
const Foto = {
|
||||
imagefile: {
|
||||
type: String,
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
},
|
||||
};
|
||||
|
||||
const FilesCataloghi = {
|
||||
per_web: { type: String, },
|
||||
per_stampa: { type: String, },
|
||||
};
|
||||
|
||||
const CatalogSchema = new Schema({
|
||||
idapp: {
|
||||
@@ -38,13 +24,18 @@ const CatalogSchema = new Schema({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
versione_perstampa: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
foto_collana: Foto,
|
||||
foto_collana: IImg,
|
||||
idCollane: [{
|
||||
type: Number,
|
||||
}],
|
||||
editore: [{ type: String }],
|
||||
descr_introduttiva: {
|
||||
type: String,
|
||||
},
|
||||
@@ -55,13 +46,20 @@ const CatalogSchema = new Schema({
|
||||
type: String,
|
||||
}],
|
||||
|
||||
img_bordata_web: Foto,
|
||||
img_bordata_stampa: Foto,
|
||||
img_intro_web: Foto,
|
||||
img_intro_stampa: Foto,
|
||||
img_bordata: IImg,
|
||||
img_intro: IImg,
|
||||
pagina_introduttiva_sfondo_nero: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
generati: FilesCataloghi,
|
||||
online: FilesCataloghi,
|
||||
pdf_generato: String,
|
||||
data_generato: {
|
||||
type: Date,
|
||||
},
|
||||
pdf_online: String,
|
||||
data_online: {
|
||||
type: Date,
|
||||
},
|
||||
|
||||
date_created: {
|
||||
type: Date,
|
||||
|
||||
@@ -6,6 +6,7 @@ const { ObjectId } = require('mongodb');
|
||||
|
||||
const { MySchedaSchema, IDimensioni, IImg, IText, IAreaDiStampa } = require('../models/myscheda');
|
||||
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
|
||||
|
||||
@@ -113,6 +113,7 @@ const IElementiScheda = new Schema({
|
||||
const scheletroScheda = {
|
||||
idapp: { type: String },
|
||||
isTemplate: { type: Boolean },
|
||||
isPagIntro: { type: Boolean },
|
||||
linkIdTemplate: { type: String },
|
||||
name: { type: String },
|
||||
numschede_perRiga: { type: Number },
|
||||
@@ -161,4 +162,4 @@ MyScheda.createIndexes((err) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
module.exports = { MyScheda, MySchedaSchema, IDimensioni, IImg, IText, IAreaDiStampa };
|
||||
module.exports = { MyScheda, MySchedaSchema, IDimensioni, IImg, IText, IAreaDiStampa, IImg };
|
||||
|
||||
26
src/server/populate/catalogs.js
Normal file
26
src/server/populate/catalogs.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
module.exports = {
|
||||
list: [
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a1'), idapp: '18', title: 'Alimentazione Sana' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a2'), idapp: '18', title: 'Attualità e Informazione Libera' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a3'), idapp: '18', title: 'Psicologia e Crescita Personale' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a4'), idapp: '18', title: 'Educazione e Formazione' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a5'), idapp: '18', title: 'Bambini e Ragazzi Felici' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a6'), idapp: '18', title: 'Salute e Benessere Naturali' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a7'), idapp: '18', title: 'Nuove Scienze' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a8'), idapp: '18', title: 'Spiritualità e Sciamanesimo' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4a9'), idapp: '18', title: 'Storia e Archeologia Segreta' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4aa'), idapp: '18', title: 'Autosufficienza, Autoproduzione e Vita Naturale' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4ab'), idapp: '18', title: 'Yoga' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4ac'), idapp: '18', title: 'Amici Animali' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4ad'), idapp: '18', title: 'Corpi Energetici' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4ae'), idapp: '18', title: 'Erbe, Alberi e Natura' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4af'), idapp: '18', title: 'Astrologia, Esoterismi e Numerologia' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4b0'), idapp: '18', title: 'Universo Femminile' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4b1'), idapp: '18', title: 'Sessualità e Relazione di coppia' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4b2'), idapp: '18', title: 'Tarocchi, Oracoli e Carte' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4b3'), idapp: '18', title: 'Techiche per il corpo' },
|
||||
{ _id: ObjectId('605c72e2f9b1a019c1e4f4b4'), idapp: '18', title: 'Antroposofia' },
|
||||
],
|
||||
};
|
||||
@@ -81,7 +81,7 @@ module.exports = {
|
||||
numupdated++;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('Error processing record:', e);
|
||||
console.log('Error processing record: ', tablename, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,12 @@ module.exports = {
|
||||
if (rec.table === 'contribtypes') {
|
||||
attiva = scrivi_contribtype;
|
||||
}
|
||||
|
||||
if (mytable) {
|
||||
await this.insertIntoDb_NoDuplicate(attiva, rec.table, mytable, rec.key, rec.key2);
|
||||
} else {
|
||||
console.error('Tabella ', mytable, ' non esistente!')
|
||||
}
|
||||
}
|
||||
|
||||
console.log('FINE - popolaTabelleNuove');
|
||||
|
||||
@@ -23,6 +23,9 @@ const { ObjectId } = require('mongodb');
|
||||
|
||||
const OpenAI = require("openai");
|
||||
|
||||
const { PassThrough } = require('stream');
|
||||
|
||||
|
||||
router.post('/getlist', authenticate_noerror, async function (req, res, next) {
|
||||
|
||||
|
||||
@@ -45,65 +48,127 @@ router.post('/getlist', authenticate_noerror, async function (req, res, next) {
|
||||
});
|
||||
|
||||
|
||||
|
||||
async function getDeepSeekResponse(prompt, options) {
|
||||
try {
|
||||
|
||||
const deepseek = new OpenAI({
|
||||
baseURL: 'https://api.deepseek.com/v1', // Verifica il percorso esatto dalle API
|
||||
apiKey: process.env.DS_API_KEY, // Mai hardcodare la chiave!
|
||||
baseURL: 'https://api.deepseek.com/v1',
|
||||
apiKey: process.env.DS_API_KEY,
|
||||
defaultHeaders: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!options.withexplain) {
|
||||
prompt = prompt + '\n' + 'Ritornami solo il risultato, senza spiegazione.'
|
||||
prompt = prompt + '\n' + 'Ritornami solo il risultato, senza spiegazione.';
|
||||
}
|
||||
if (options.outputType) {
|
||||
prompt = prompt + '\n' + options.outputType;
|
||||
}
|
||||
|
||||
const completion = await deepseek.chat.completions.create({
|
||||
const completionStream = await deepseek.chat.completions.create({
|
||||
model: options.model || "deepseek-chat",
|
||||
messages: [
|
||||
{ role: "system", content: options.contestsystem || "" },
|
||||
{ role: "system", content: options?.contestsystem || "" },
|
||||
{ role: "user", content: prompt }
|
||||
],
|
||||
temperature: options.temp || 0.3,
|
||||
max_tokens: options.max_tokens || 1000,
|
||||
stream: options.stream || false,
|
||||
temperature: options?.temp || 0.3,
|
||||
max_tokens: options?.max_tokens || 1000,
|
||||
stream: options?.stream || false,
|
||||
});
|
||||
|
||||
if (!completion || !completion.choices || completion.choices.length === 0) {
|
||||
if (options?.stream) {
|
||||
// Creiamo un PassThrough stream per inviare i chunk al frontend
|
||||
/*const stream = new PassThrough();
|
||||
completionStream.on('data', (chunk) => {
|
||||
stream.write(`data: ${JSON.stringify(chunk)}\n\n`);
|
||||
});
|
||||
completionStream.on('end', () => {
|
||||
stream.end();
|
||||
});
|
||||
return stream;*/
|
||||
|
||||
return completionStream;
|
||||
} else {
|
||||
if (!completionStream || !completionStream.choices || completionStream.choices.length === 0) {
|
||||
throw new Error('Invalid response from DeepSeek API');
|
||||
}
|
||||
|
||||
return completion.choices[0];
|
||||
return completionStream.choices[0];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('DeepSeek Error:', error.response?.data || error.message);
|
||||
throw new Error('Failed to get AI response');
|
||||
}
|
||||
}
|
||||
|
||||
// Endpoint per DeepSeek
|
||||
router.post('/ds', authenticate, async (req, res) => {
|
||||
try {
|
||||
let prompt = req.body.prompt;
|
||||
let options = req.body.options;
|
||||
|
||||
const { prompt, options } = req.body;
|
||||
|
||||
const isstream = (options && options?.stream)
|
||||
|
||||
if (isstream) {
|
||||
// Se lo streaming è abilitato, restituiamo un flusso di dati
|
||||
res.setHeader('Content-Type', 'text/event-stream');
|
||||
res.setHeader('Cache-Control', 'no-cache');
|
||||
res.setHeader('Connection', 'keep-alive');
|
||||
|
||||
try {
|
||||
// Ottieni il flusso di dati da DeepSeek
|
||||
const completionStream = await getDeepSeekResponse(prompt, options);
|
||||
|
||||
for await (const chunk of completionStream) {
|
||||
if (chunk.choices && chunk.choices[0]) {
|
||||
const data = JSON.stringify({ choice: chunk.choices[0] });
|
||||
res.write(`data: ${data}\n\n`);
|
||||
try {
|
||||
const msg = chunk.choices[0].delta.content;
|
||||
if (msg) {
|
||||
console.log(msg);
|
||||
// await tools.sleep(10000)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error: ' + e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.write('data: [DONE]\n\n');
|
||||
res.end();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
const errorstr = 'DeepSeek API Error:' + (error.response?.data || error.message)
|
||||
console.error(errorstr);
|
||||
|
||||
// In caso di errore durante lo streaming, invia un messaggio di errore
|
||||
const errorData = JSON.stringify({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: errorstr,
|
||||
});
|
||||
res.write(`data: ${errorData}\n\n`);
|
||||
res.end();
|
||||
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
// Se lo streaming non è abilitato, restituisci la risposta completa
|
||||
const choice = await getDeepSeekResponse(prompt, options);
|
||||
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
choice,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('DeepSeek API Error:', error.response?.data || error.message);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, error: 'Errore nella chiamata a DeepSeek: ' + error.response?.data || error.message });
|
||||
const errorstr = 'DeepSeek API Error:' + (error.response?.data || error.message)
|
||||
console.error(errorstr);
|
||||
|
||||
// In caso di errore senza streaming, restituisci un errore standard
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: errorstr,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -668,6 +668,32 @@ router.post('/setsubrec', authenticate, (req, res) => {
|
||||
|
||||
});
|
||||
|
||||
router.post('/getobj', authenticate_noerror, async (req, res) => {
|
||||
|
||||
try {
|
||||
let cmd = req.body.cmd;
|
||||
let idapp = req.user ? req.user.idapp : sanitizeHtml(req.body.idapp); // Cambiato from params.idapp a req.body.idapp
|
||||
let ris = null;
|
||||
|
||||
if (cmd === 'lista_editori') {
|
||||
ris = await User.find(
|
||||
{
|
||||
idapp,
|
||||
perm: { $bitsAnySet: 0b10000 },
|
||||
},
|
||||
{ username: 1, name: 1, surname: 1 }
|
||||
).lean();
|
||||
}
|
||||
|
||||
// Invia la risposta
|
||||
res.status(200).send({ code: server_constants.RIS_CODE_OK, data: ris });
|
||||
|
||||
} catch (e) {
|
||||
console.error(`ERROR getobj ${cmd}: `, e.message);
|
||||
res.status(200).send({ code: server_constants.RIS_CODE_OK, data: [] });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/gettable', authenticate_noerror, (req, res) => {
|
||||
let params = req.body;
|
||||
|
||||
@@ -868,6 +894,8 @@ async function duplicatePage(pageId, newpath) {
|
||||
|
||||
const catalogo = elem.catalogo;
|
||||
|
||||
if (catalogo) {
|
||||
|
||||
for (const recscheda of catalogo.arrSchede) {
|
||||
if (recscheda.scheda?.isTemplate) {
|
||||
// Se è un template allora devo mettergli un altro ID !
|
||||
@@ -875,9 +903,11 @@ async function duplicatePage(pageId, newpath) {
|
||||
// recscheda.scheda.name = getNewFreeNameTemplate(recscheda.scheda?.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let newelem = { ...elem };
|
||||
|
||||
if (catalogo)
|
||||
elem.catalogo = { ...catalogo };
|
||||
|
||||
const newElem = new MyElem({
|
||||
|
||||
@@ -720,8 +720,8 @@ function getCredentials(hostname) {
|
||||
|
||||
if (NUOVO_METODO_TEST) {
|
||||
if (METODO_MULTI_CORS) {
|
||||
const fileprivkey = `/etc/letsencrypt/live/${hostname}/privkey.pem`;
|
||||
const filecert = `/etc/letsencrypt/live/${hostname}/cert.pem`;
|
||||
const fileprivkey = `/etc/letsencrypt/live/${hostname}/` + process.env.PATH_CERT_KEY;
|
||||
const filecert = `/etc/letsencrypt/live/${hostname}/` + process.env.PATH_SERVER_CRT;
|
||||
|
||||
console.log('fileprivkey: ', fileprivkey, ' filecert: ', filecert);
|
||||
|
||||
|
||||
@@ -525,10 +525,6 @@ class ImageDownloader {
|
||||
}
|
||||
}
|
||||
|
||||
// Funzione per implementare il ritardo tra i tentativi
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
MYAPPS: [],
|
||||
@@ -5956,6 +5952,11 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
// Funzione per implementare il ritardo tra i tentativi
|
||||
sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -267,11 +267,16 @@ module.exports = {
|
||||
{
|
||||
table: 'adtypegoods',
|
||||
keyOFF: 'descr',
|
||||
}, {
|
||||
},
|
||||
{
|
||||
table: 'catalogs',
|
||||
key: 'title',
|
||||
},
|
||||
{
|
||||
table: 'adtypes',
|
||||
keyOFF: 'descr',
|
||||
},
|
||||
{ table: 'catgrps', key: 'descr' },
|
||||
{ table: 'catgrps' },
|
||||
{
|
||||
table: 'contribtypes',
|
||||
keyOLD: 'descr',
|
||||
@@ -282,7 +287,8 @@ module.exports = {
|
||||
{ table: 'provinces', key: 'descr' },
|
||||
{ table: 'sectorgoods', keyOLD: 'descr' },
|
||||
{ table: 'sectors', keyOLD: 'descr' },
|
||||
{ table: 'skills', key: 'descr', key2: 'idSector' },
|
||||
// { table: 'skills', key: 'descr', key2: 'idSector' },
|
||||
{ table: 'skills' },
|
||||
{ table: 'statusSkills', keyOLD: 'descr' },
|
||||
// { table: 'catais', key: 'descr' },
|
||||
// { table: 'queryais', key: 'descr' },
|
||||
|
||||
Reference in New Issue
Block a user