Webview 2 + Html + ChatGPT !
- TOTOVIOTTI
- Posts: 422
- Joined: Fri Feb 05, 2010 11:30 am
- Location: San Francisco - Córdoba - Argentina
Webview 2 + Html + ChatGPT !
Hola amigos..
estoy intentando probar webview2 con un código html que simula un dashboard.
Si lo ejecuto por afuera, el html me muestra la pantalla que está en el código, pero,
cuando lo mando desde el prg, la pantalla sale en blanco, que puede ser??
Adjunto el código como para probar:
#include "fivewin.ch"
//----------------------------------------------------------------------------//
function Main()
local oWebView := TWebView():New()
oWebView:bOnBind = { | cJson, nCalls | MsgInfo( cJson, nCalls ) }
oWebView:Bind( "SendToFWH" )
oWebView:Navigate( Html() )
Sleep( 200 )
oWebView:Run()
oWebView:Destroy()
return nil
//----------------------------------------------------------------------------//
function Html()
local cHtml
TEXT INTO cHtml
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tablero de Control Empresarial</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #8b93bb; /* Beige claro */
}
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.ventana {
background-color: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transition: all 0.3s ease;
}
.ventana:hover {
transform: translateY(-5px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
h1 {
text-align: center;
color: #333;
}
h3 {
margin-top: 0;
color: #fff;
display: flex;
align-items: center;
padding: 10px;
border-radius: 5px 5px 0 0;
}
h3 i {
margin-right: 10px;
}
.valor {
font-size: 20px;
font-weight: bold;
color: #333;
margin: 10px 0;
}
.finanzas { background-color: #4CAF50; }
.ventas { background-color: #2196F3; }
.operaciones { background-color: #FFC107; }
.marketing { background-color: #E91E63; }
</style>
</head>
<body>
<h1>Tablero de Control Empresarial</h1>
<div id="dashboard" class="dashboard">
<!-- Las ventanas del dashboard se insertarán aquí dinámicamente -->
</div>
<script>
// Datos de ejemplo (en una aplicación real, estos datos podrían venir de FiveWin)
const datos = {
'ventas_mensuales': 150000,
'compras_mensuales': 100000,
'clientes_activos': 500,
'productos_en_stock': 1000,
'pedidos_pendientes': 50,
'ingresos_anuales': 2000000,
'gastos_anuales': 1500000,
'empleados': 100,
'proyectos_activos': 10,
'tasa_conversion': 3.5,
'satisfaccion_cliente': 4.2,
'crecimiento_ventas': 7.5,
'retorno_inversion': 15.2,
'rotacion_inventario': 12,
'cuentas_por_cobrar': 200000,
'cuentas_por_pagar': 150000,
'flujo_caja': 300000,
'margen_beneficio': 25,
'cuota_mercado': 8.5,
'valor_marca': 5000000
};
function crearVentana(titulo, valor, unidad = '', icono = 'fa-chart-line', categoria = 'finanzas') {
const ventana = document.createElement('div');
ventana.className = 'ventana';
ventana.innerHTML = `
<h3 class="${categoria}"><i class="fas ${icono}"></i>${titulo}</h3>
<p class="valor">${formatearNumero(valor)} ${unidad}</p>
`;
return ventana;
}
function formatearNumero(numero) {
return numero.toLocaleString('es-ES');
}
function inicializarDashboard() {
const dashboard = document.getElementById('dashboard');
const ventanas = [
{ titulo: 'Ventas de Contado', valor: datos.ventas_mensuales, unidad: '$', icono: 'fa-shopping-cart', categoria: 'finanzas' },
{ titulo: 'Ventas en Cuenta Corriente', valor: datos.compras_mensuales, unidad: '$', icono: 'fa-shopping-cart', categoria: 'finanzas' },
{ titulo: 'Compras de Contado', valor: datos.clientes_activos, unidad: '$', icono: 'fa-solid fa-basket-shopping', categoria: 'marketing' },
{ titulo: 'Compras en Cuenta Corriente', valor: datos.productos_en_stock, unidad: '$', icono: 'fa-solid fa-basket-shopping', categoria: 'marketing' },
{ titulo: 'Cobranzas por Recibos', valor: datos.pedidos_pendientes, unidad: '$', icono: 'fa-hand-holding-usd', categoria: 'finanzas' },
{ titulo: 'Otros Ingresos', valor: datos.ingresos_anuales, unidad: '$', icono: 'fa-money-bill-wave', categoria: 'finanzas' },
{ titulo: 'Pagos por Órdenes de Pago', valor: datos.gastos_anuales, unidad: '$', icono: 'fa-file-invoice-dollar', categoria: 'marketing' },
{ titulo: 'Otros Egresos', valor: datos.empleados, unidad: '$', icono: 'fa-solid fa-comment-dollar', categoria: 'marketing' },
{ titulo: 'Saldo CC Clientes a fecha', valor: datos.proyectos_activos, unidad: '$', icono: 'fa-users', categoria: 'finanzas' },
{ titulo: 'Saldo Total CC Clientes', valor: datos.tasa_conversion, unidad: '$', icono: 'fa-users', categoria: 'finanzas' },
{ titulo: 'Saldo CC Proveedores a fecha', valor: datos.satisfaccion_cliente, unidad: '$', icono: 'fa-regular fa-user', categoria: 'marketing' },
{ titulo: 'Saldo Total CC Proveedores', valor: datos.crecimiento_ventas, unidad: '$', icono: 'fa-regular fa-user', categoria: 'marketing' },
{ titulo: 'Cheques a Vencer al', valor: datos.retorno_inversion, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques en Cartera', valor: datos.rotacion_inventario, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Recibidos entre', valor: datos.cuentas_por_cobrar, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Transferidos entre', valor: datos.cuentas_por_pagar, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Emitidos', valor: datos.flujo_caja, unidad: '$', icono: 'fa-solid fa-building-columns', categoria: 'ventas' },
{ titulo: 'Transferencias Realizadas', valor: datos.margen_beneficio, unidad: '$', icono: 'fa-exchange-alt', categoria: 'ventas' },
{ titulo: 'Transferencias Recibidas', valor: datos.cuota_mercado, unidad: '$', icono: 'fa-exchange-alt', categoria: 'ventas' }
];
ventanas.forEach(v => {
dashboard.appendChild(crearVentana(v.titulo, v.valor, v.unidad, v.icono, v.categoria));
});
}
// Inicializar el dashboard cuando la página se cargue
window.onload = inicializarDashboard;
</script>
</body>
</html>
ENDTEXT
return cHtml
estoy intentando probar webview2 con un código html que simula un dashboard.
Si lo ejecuto por afuera, el html me muestra la pantalla que está en el código, pero,
cuando lo mando desde el prg, la pantalla sale en blanco, que puede ser??
Adjunto el código como para probar:
#include "fivewin.ch"
//----------------------------------------------------------------------------//
function Main()
local oWebView := TWebView():New()
oWebView:bOnBind = { | cJson, nCalls | MsgInfo( cJson, nCalls ) }
oWebView:Bind( "SendToFWH" )
oWebView:Navigate( Html() )
Sleep( 200 )
oWebView:Run()
oWebView:Destroy()
return nil
//----------------------------------------------------------------------------//
function Html()
local cHtml
TEXT INTO cHtml
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tablero de Control Empresarial</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #8b93bb; /* Beige claro */
}
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.ventana {
background-color: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transition: all 0.3s ease;
}
.ventana:hover {
transform: translateY(-5px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
h1 {
text-align: center;
color: #333;
}
h3 {
margin-top: 0;
color: #fff;
display: flex;
align-items: center;
padding: 10px;
border-radius: 5px 5px 0 0;
}
h3 i {
margin-right: 10px;
}
.valor {
font-size: 20px;
font-weight: bold;
color: #333;
margin: 10px 0;
}
.finanzas { background-color: #4CAF50; }
.ventas { background-color: #2196F3; }
.operaciones { background-color: #FFC107; }
.marketing { background-color: #E91E63; }
</style>
</head>
<body>
<h1>Tablero de Control Empresarial</h1>
<div id="dashboard" class="dashboard">
<!-- Las ventanas del dashboard se insertarán aquí dinámicamente -->
</div>
<script>
// Datos de ejemplo (en una aplicación real, estos datos podrían venir de FiveWin)
const datos = {
'ventas_mensuales': 150000,
'compras_mensuales': 100000,
'clientes_activos': 500,
'productos_en_stock': 1000,
'pedidos_pendientes': 50,
'ingresos_anuales': 2000000,
'gastos_anuales': 1500000,
'empleados': 100,
'proyectos_activos': 10,
'tasa_conversion': 3.5,
'satisfaccion_cliente': 4.2,
'crecimiento_ventas': 7.5,
'retorno_inversion': 15.2,
'rotacion_inventario': 12,
'cuentas_por_cobrar': 200000,
'cuentas_por_pagar': 150000,
'flujo_caja': 300000,
'margen_beneficio': 25,
'cuota_mercado': 8.5,
'valor_marca': 5000000
};
function crearVentana(titulo, valor, unidad = '', icono = 'fa-chart-line', categoria = 'finanzas') {
const ventana = document.createElement('div');
ventana.className = 'ventana';
ventana.innerHTML = `
<h3 class="${categoria}"><i class="fas ${icono}"></i>${titulo}</h3>
<p class="valor">${formatearNumero(valor)} ${unidad}</p>
`;
return ventana;
}
function formatearNumero(numero) {
return numero.toLocaleString('es-ES');
}
function inicializarDashboard() {
const dashboard = document.getElementById('dashboard');
const ventanas = [
{ titulo: 'Ventas de Contado', valor: datos.ventas_mensuales, unidad: '$', icono: 'fa-shopping-cart', categoria: 'finanzas' },
{ titulo: 'Ventas en Cuenta Corriente', valor: datos.compras_mensuales, unidad: '$', icono: 'fa-shopping-cart', categoria: 'finanzas' },
{ titulo: 'Compras de Contado', valor: datos.clientes_activos, unidad: '$', icono: 'fa-solid fa-basket-shopping', categoria: 'marketing' },
{ titulo: 'Compras en Cuenta Corriente', valor: datos.productos_en_stock, unidad: '$', icono: 'fa-solid fa-basket-shopping', categoria: 'marketing' },
{ titulo: 'Cobranzas por Recibos', valor: datos.pedidos_pendientes, unidad: '$', icono: 'fa-hand-holding-usd', categoria: 'finanzas' },
{ titulo: 'Otros Ingresos', valor: datos.ingresos_anuales, unidad: '$', icono: 'fa-money-bill-wave', categoria: 'finanzas' },
{ titulo: 'Pagos por Órdenes de Pago', valor: datos.gastos_anuales, unidad: '$', icono: 'fa-file-invoice-dollar', categoria: 'marketing' },
{ titulo: 'Otros Egresos', valor: datos.empleados, unidad: '$', icono: 'fa-solid fa-comment-dollar', categoria: 'marketing' },
{ titulo: 'Saldo CC Clientes a fecha', valor: datos.proyectos_activos, unidad: '$', icono: 'fa-users', categoria: 'finanzas' },
{ titulo: 'Saldo Total CC Clientes', valor: datos.tasa_conversion, unidad: '$', icono: 'fa-users', categoria: 'finanzas' },
{ titulo: 'Saldo CC Proveedores a fecha', valor: datos.satisfaccion_cliente, unidad: '$', icono: 'fa-regular fa-user', categoria: 'marketing' },
{ titulo: 'Saldo Total CC Proveedores', valor: datos.crecimiento_ventas, unidad: '$', icono: 'fa-regular fa-user', categoria: 'marketing' },
{ titulo: 'Cheques a Vencer al', valor: datos.retorno_inversion, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques en Cartera', valor: datos.rotacion_inventario, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Recibidos entre', valor: datos.cuentas_por_cobrar, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Transferidos entre', valor: datos.cuentas_por_pagar, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Emitidos', valor: datos.flujo_caja, unidad: '$', icono: 'fa-solid fa-building-columns', categoria: 'ventas' },
{ titulo: 'Transferencias Realizadas', valor: datos.margen_beneficio, unidad: '$', icono: 'fa-exchange-alt', categoria: 'ventas' },
{ titulo: 'Transferencias Recibidas', valor: datos.cuota_mercado, unidad: '$', icono: 'fa-exchange-alt', categoria: 'ventas' }
];
ventanas.forEach(v => {
dashboard.appendChild(crearVentana(v.titulo, v.valor, v.unidad, v.icono, v.categoria));
});
}
// Inicializar el dashboard cuando la página se cargue
window.onload = inicializarDashboard;
</script>
</body>
</html>
ENDTEXT
return cHtml
- Antonio Linares
- Site Admin
- Posts: 42253
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: Webview 2 + Html
Hazlo asi:
test.prg
test.prg
Code: Select all | Expand
#include "FiveWin.ch"
//----------------------------------------------------------------------------//
function Main()
local oWnd, oWebView
DEFINE WINDOW oWnd
oWebView = TWebView2():New( oWnd )
oWebView:SetHtml( Html() )
ACTIVATE WINDOW oWnd MAXIMIZED ;
ON RESIZE oWebView:SetSize( nWidth, nHeight )
return nil
//----------------------------------------------------------------------------//
function Html()
local cHtml
TEXT INTO cHtml
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tablero de Control Empresarial</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #8b93bb; /* Beige claro */
}
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.ventana {
background-color: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transition: all 0.3s ease;
}
.ventana:hover {
transform: translateY(-5px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
h1 {
text-align: center;
color: #333;
}
h3 {
margin-top: 0;
color: #fff;
display: flex;
align-items: center;
padding: 10px;
border-radius: 5px 5px 0 0;
}
h3 i {
margin-right: 10px;
}
.valor {
font-size: 20px;
font-weight: bold;
color: #333;
margin: 10px 0;
}
.finanzas { background-color: #4CAF50; }
.ventas { background-color: #2196F3; }
.operaciones { background-color: #FFC107; }
.marketing { background-color: #E91E63; }
</style>
</head>
<body>
<h1>Tablero de Control Empresarial</h1>
<div id="dashboard" class="dashboard">
<!-- Las ventanas del dashboard se insertarán aquí dinámicamente -->
</div>
<script>
// Datos de ejemplo (en una aplicación real, estos datos podrían venir de FiveWin)
const datos = {
'ventas_mensuales': 150000,
'compras_mensuales': 100000,
'clientes_activos': 500,
'productos_en_stock': 1000,
'pedidos_pendientes': 50,
'ingresos_anuales': 2000000,
'gastos_anuales': 1500000,
'empleados': 100,
'proyectos_activos': 10,
'tasa_conversion': 3.5,
'satisfaccion_cliente': 4.2,
'crecimiento_ventas': 7.5,
'retorno_inversion': 15.2,
'rotacion_inventario': 12,
'cuentas_por_cobrar': 200000,
'cuentas_por_pagar': 150000,
'flujo_caja': 300000,
'margen_beneficio': 25,
'cuota_mercado': 8.5,
'valor_marca': 5000000
};
function crearVentana(titulo, valor, unidad = '', icono = 'fa-chart-line', categoria = 'finanzas') {
const ventana = document.createElement('div');
ventana.className = 'ventana';
ventana.innerHTML = `
<h3 class="${categoria}"><i class="fas ${icono}"></i>${titulo}</h3>
<p class="valor">${formatearNumero(valor)} ${unidad}</p>
`;
return ventana;
}
function formatearNumero(numero) {
return numero.toLocaleString('es-ES');
}
function inicializarDashboard() {
const dashboard = document.getElementById('dashboard');
const ventanas = [
{ titulo: 'Ventas de Contado', valor: datos.ventas_mensuales, unidad: '$', icono: 'fa-shopping-cart', categoria: 'finanzas' },
{ titulo: 'Ventas en Cuenta Corriente', valor: datos.compras_mensuales, unidad: '$', icono: 'fa-shopping-cart', categoria: 'finanzas' },
{ titulo: 'Compras de Contado', valor: datos.clientes_activos, unidad: '$', icono: 'fa-solid fa-basket-shopping', categoria: 'marketing' },
{ titulo: 'Compras en Cuenta Corriente', valor: datos.productos_en_stock, unidad: '$', icono: 'fa-solid fa-basket-shopping', categoria: 'marketing' },
{ titulo: 'Cobranzas por Recibos', valor: datos.pedidos_pendientes, unidad: '$', icono: 'fa-hand-holding-usd', categoria: 'finanzas' },
{ titulo: 'Otros Ingresos', valor: datos.ingresos_anuales, unidad: '$', icono: 'fa-money-bill-wave', categoria: 'finanzas' },
{ titulo: 'Pagos por Órdenes de Pago', valor: datos.gastos_anuales, unidad: '$', icono: 'fa-file-invoice-dollar', categoria: 'marketing' },
{ titulo: 'Otros Egresos', valor: datos.empleados, unidad: '$', icono: 'fa-solid fa-comment-dollar', categoria: 'marketing' },
{ titulo: 'Saldo CC Clientes a fecha', valor: datos.proyectos_activos, unidad: '$', icono: 'fa-users', categoria: 'finanzas' },
{ titulo: 'Saldo Total CC Clientes', valor: datos.tasa_conversion, unidad: '$', icono: 'fa-users', categoria: 'finanzas' },
{ titulo: 'Saldo CC Proveedores a fecha', valor: datos.satisfaccion_cliente, unidad: '$', icono: 'fa-regular fa-user', categoria: 'marketing' },
{ titulo: 'Saldo Total CC Proveedores', valor: datos.crecimiento_ventas, unidad: '$', icono: 'fa-regular fa-user', categoria: 'marketing' },
{ titulo: 'Cheques a Vencer al', valor: datos.retorno_inversion, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques en Cartera', valor: datos.rotacion_inventario, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Recibidos entre', valor: datos.cuentas_por_cobrar, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Transferidos entre', valor: datos.cuentas_por_pagar, unidad: '$', icono: 'fa-solid fa-money-check', categoria: 'operaciones' },
{ titulo: 'Cheques Emitidos', valor: datos.flujo_caja, unidad: '$', icono: 'fa-solid fa-building-columns', categoria: 'ventas' },
{ titulo: 'Transferencias Realizadas', valor: datos.margen_beneficio, unidad: '$', icono: 'fa-exchange-alt', categoria: 'ventas' },
{ titulo: 'Transferencias Recibidas', valor: datos.cuota_mercado, unidad: '$', icono: 'fa-exchange-alt', categoria: 'ventas' }
];
ventanas.forEach(v => {
dashboard.appendChild(crearVentana(v.titulo, v.valor, v.unidad, v.icono, v.categoria));
});
}
// Inicializar el dashboard cuando la página se cargue
window.onload = inicializarDashboard;
</script>
</body>
</html>
ENDTEXT
return cHtml
- TOTOVIOTTI
- Posts: 422
- Joined: Fri Feb 05, 2010 11:30 am
- Location: San Francisco - Córdoba - Argentina
Re: Webview 2 + Html
EXCELENTE!!!!!!!!!!!!!
GRACIAS ANTONIOOOOOOOOOO!!!!
GRACIAS ANTONIOOOOOOOOOO!!!!
Re: Webview 2 + Html
Tiro otra idea, usando como contenedor nuestra aplicacion y para que tenga interactividad con nuestro programa
Quedaría algo asi:
Este sería el html (Paso 1, los otros serían a la imaginacion de cada uno)
Code: Select all | Expand
#include "FiveWin.ch"
FUNCTION Main()
local oWebView, oBtn
Local oWnd, oExBar, oPanelExplorer, oPanelWeb, oPanel, oGet := ARRAY(2), dDesde := DATE(), dHasta := DATE()
REQUEST HB_LANG_ESWIN
REQUEST HB_CODEPAGE_ESMWIN
SET DATE FORMAT "DD/MM/YYYY"
SET 3DLOOK ON
HB_LANGSELECT( 'ESWIN' )
//Si mi aplicacion es MDI asi debería definir la ventana
//DEFINE WINDOW oWnd MDICHILD OF oApp:oWnd TITLE "Dashboard " ICON oApp:oIco
DEFINE WINDOW oWnd TITLE "Dashboard "
*** Paneles
oPanelExplorer := TPanel():New( 0, 0, oWnd:nHeight, 280, oWnd )
oPanelWeb := TPanel():New( 0, 281, oWnd:nHeight, oWnd:nWidth, oWnd )
oExBar := TExplorerBar():New( 0, 0, 250, 300, oPanelExplorer )
oPanelExplorer:oClient = oExBar
oPanel := oExBar:AddPanel( "Seleccionar Fecha", "..\bitmaps\calendar.bmp", 255 )
oPanel:AddLink( "Ventas del Periodo" , { || oWebView:SetHtml(memoread('ventas.html')) }, "..\bitmaps\go.bmp" )
oPanel:AddLink( "Compras del Periodo " , { || oWebView:SetHtml(memoread('compras.html')) }, "..\bitmaps\go.bmp" )
oPanel:AddLink( "Cobros del Periodo" , { || oWebView:SetHtml(memoread('cobros.html')) }, "..\bitmaps\go.bmp" )
oPanel:AddLink( "Pagos del Periodo" , { || oWebView:SetHtml(memoread('pagos.html')) }, "..\bitmaps\go.bmp" )
*/
@170, 15 SAY "Desde Fecha:" OF oPanel TRANSPARENT PIXEL SIZE 40,12
@200, 15 SAY "Hasta Fecha:" OF oPanel TRANSPARENT PIXEL SIZE 40,12
@170,90 GET oGet[1] VAR dDesde OF oPanel PIXEL
@200,90 GET oGet[2] VAR dHasta OF oPanel PIXEL
@230,50 BUTTON oBtn PROMPT "Cambiar Fechas" OF oPanel PIXEL SIZE 110,25
oWebView := TWebView2():New(oPanelWeb)
oWebView:SetUserAgent( "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Mobile Safari/537.36" )
oWebView:SetHtml( memoread( 'ventas.html' ) )
oWebView:Run()
ACTIVATE WINDOW oWnd MAXIMIZED ON RESIZE (oPanelExplorer:Move( , , , oWnd:nHeight ),;
oPanelWeb:Move ( , , oWnd:nWidth - oPanelExplorer:nRight, oWnd:nHeight - 60 ),;
oWebView:SetSize(oPanelWeb:nWidth,oPanelWeb:nHeight));
ON INIT (oWebView:SetSize(oPanelWeb:nWidth,oPanelWeb:nHeight),oWnd:Move(0,0))
//Si mi app es MDI deberia agregar aqui
//ON INIT (oWnd:SetSize(oApp:oWnd:oWndclient:nWidth, oApp:oWnd:oWndclient:nHeight)
RETURN nil
Este sería el html (Paso 1, los otros serían a la imaginacion de cada uno)
Code: Select all | Expand
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.1/css/all.css" crossorigin="anonymous">
<script type="text/javascript">
// Cargar Google Charts
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawCharts);
// Función para dibujar los gráficos
function drawCharts() {
drawPieChart();
drawLineChart();
}
// Gráfico de torta
function drawPieChart() {
var data = google.visualization.arrayToDataTable([
['Concepto', 'Importe'],
['Efectivo', 800000],
['Mercadopago', 200000],
['Tarjetas', 300000],
['Transferencias', 500000],
['Otros', 150000]
]);
var options = {
title: 'Ingresos por ventas',
widht: '100%',
height: 300,
is3D: true
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
// Gráfico de líneas
function drawLineChart() {
var data = google.visualization.arrayToDataTable([
['Rubro', 'Totales'],
['Carniceria', 1000000],
['Fiambreria', 1170000],
['Comestibles', 660000],
['Bazar', 1030000]
]);
var options = {
title: 'Ventas Por Rubro',
curveType: 'function',
legend: { position: 'bottom' },
widht: '100%',
height: 300,
is3D: true
};
var chart = new google.visualization.ColumnChart(document.getElementById('linechart'));
chart.draw(data, options);
}
window.onresize = function () {
drawCharts(); // Redibujar gráficos cuando la ventana cambia de tamaño
};
</script>
</head>
<body class="bg-gray-100">
<div class="flex flex-col lg:flex-row min-h-screen">
<!-- Sidebar -->
<!-- Main Content -->
<div class="flex-1 p-8 overflow-y-auto">
<!-- Valores Section -->
<div id="values" class="section">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Ingresos -->
<div class="bg-white shadow-md p-6 h-50 rounded-lg text-center border-t-4 border-green-500">
<h3 class="text-lg font-bold text-green-500"><i class="fas fa-dollar-sign fa-3x"></i></h3>
<p class="text-xl mt-4 text-gray-700">Ventas</p>
<p class="text-3xl mt-2 text-green-500 font-bold">$1,000,000</p>
</div>
<!-- Productos -->
<div class="bg-white shadow-md p-6 h-50 rounded-lg text-center border-t-4 border-blue-500">
<h3 class="text-lg font-bold text-blue-500"><i class="fas fa-boxes fa-3x"></i></h3>
<p class="text-xl mt-4 text-gray-700">Costo</p>
<p class="text-3xl mt-2 text-blue-500 font-bold">$900,000</p>
</div>
<!-- Usuarios -->
<div class="bg-white shadow-md p-6 h-50 rounded-lg text-center border-t-4 border-yellow-500">
<h3 class="text-lg font-bold text-yellow-500"><i class="fas fa-users fa-3x"></i></h3>
<p class="text-xl mt-4 text-gray-700">Unidades</p>
<p class="text-3xl mt-2 text-yellow-500 font-bold">12,000</p>
</div>
</div>
</div>
<div class="section p-2">
<hr>
</div>
<!-- Gráficos Section -->
<div id="charts" class="section">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-6">
<div class="bg-white shadow-md p-6 rounded-lg">
<h2 class="text-xl font-bold mb-4 text-green-500">Ventas</h2>
<div id="piechart"></div>
</div>
<div class="bg-white shadow-md p-6 rounded-lg">
<h2 class="text-xl font-bold mb-4 text-blue-500">Por Rubro</h2>
<div id="linechart"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Re: Webview 2 + Html
Lo mismo pero con una clase que nos permita generar dinamicamente el html que vamos a mostrar
La clase TDashboard tiene 2 metodos, uno para agregar un panel y otro para agregar un grafico
El método AddPanel tiene los siguientes parametros:
METHOD AddPanel(cTexto, cValor, cFaFaIcon, cColor )
cTexto -> El nombre del panel a mostrar
cValor -> El número que queremos mostrar en formato texto
cFaFaIcon -> El icono que queremos mostrar (Cualquiera de fa fa icons https://fontawesome.com/)
cColor -> Un color de la Tailwind https://tailwindcss.com/docs/customizing-colors que es el css que usa
El método AddGraph tiene los siguientes parametros:
METHOD AddGraph (cNombre, cTitulo, cTipo, aColumnsData, aData, cColor )
cNombre -> Nombre del grafico (que sea una sola palabra, porque lo convierte en la funcion a llamar por Javascrip)
cTitulo -> Titulo del grafico
cTipo -> Un tipo de grafico simple de google graph (PieChart, BarChart, ColumnChart, etc)
aColumnsData -> Array con los titulos de las columnas de los datos a mostrar en el grafico (2 columnas, 1 fila)
aData -> Array con los los datos a mostrar en el grafico (2 columnas, n filas)
cColor -> Un color de Tailwind para el color del titulo
Esto es muy mejorable, pero es un inicio, espero que los expertos sumen funcionalidades
Code: Select all | Expand
#include "FiveWin.ch"
FUNCTION Main()
local oWebView, oBtn
Local oWnd, oExBar, oPanelExplorer, oPanelWeb, oPanel, oGet := ARRAY(2), dDesde := DATE(), dHasta := DATE()
REQUEST HB_LANG_ESWIN
REQUEST HB_CODEPAGE_ESMWIN
SET DATE FORMAT "DD/MM/YYYY"
SET 3DLOOK ON
HB_LANGSELECT( 'ESWIN' )
//Si mi aplicacion es MDI asi debería definir la ventana
//DEFINE WINDOW oWnd MDICHILD OF oApp:oWnd TITLE "Dashboard " ICON oApp:oIco
DEFINE WINDOW oWnd TITLE "Dashboard "
*** Paneles
oPanelExplorer := TPanel():New( 0, 0, oWnd:nHeight, 280, oWnd )
oPanelWeb := TPanel():New( 0, 281, oWnd:nHeight, oWnd:nWidth, oWnd )
oExBar := TExplorerBar():New( 0, 0, 250, 300, oPanelExplorer )
oPanelExplorer:oClient = oExBar
oPanel := oExBar:AddPanel( "Seleccionar Fecha", "..\bitmaps\calendar.bmp", 255 )
oPanel:AddLink( "Ventas del Periodo" , { || oWebView:SetHtml(MiHtml(1)) }, "..\bitmaps\go.bmp" )
oPanel:AddLink( "Compras del Periodo " , { || oWebView:SetHtml(MiHtml(2)) }, "..\bitmaps\go.bmp" )
oPanel:AddLink( "Cobros del Periodo" , { || oWebView:SetHtml(MiHtml(3)) }, "..\bitmaps\go.bmp" )
oPanel:AddLink( "Pagos del Periodo" , { || oWebView:SetHtml(MiHtml(4)) }, "..\bitmaps\go.bmp" )
oWebView := TWebView2():New(oPanelWeb)
oWebView:SetUserAgent( "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Mobile Safari/537.36" )
oWebView:SetHtml( MiHtml(1) )
oWebView:Run()
ACTIVATE WINDOW oWnd MAXIMIZED ON RESIZE (oPanelExplorer:Move( , , , oWnd:nHeight ),;
oPanelWeb:Move ( , , oWnd:nWidth - oPanelExplorer:nRight, oWnd:nHeight - 60 ),;
oWebView:SetSize(oPanelWeb:nWidth,oPanelWeb:nHeight));
ON INIT (oWebView:SetSize(oPanelWeb:nWidth,oPanelWeb:nHeight),oWnd:Move(0,0))
//Si mi app es MDI deberia agregar aqui
//ON INIT (oWnd:SetSize(oApp:oWnd:oWndclient:nWidth, oApp:oWnd:oWndclient:nHeight)
RETURN nil
STATIC FUNCTION MiHtml(n)
LOCAL oDashBoard, aData
oDashBoard = TDashboard():New()
DO CASE
CASE n = 1
oDashBoard:AddPanel('Ventas','$1,000,000','dollar-sign','green')
oDashBoard:AddPanel('Costo' ,'$900,000','boxes','blue')
oDashBoard:AddPanel('Productos' ,'12,000','cubes','lime')
aData := {{'Carniceria', 1000000},;
{'Fiambreria', 1170000},;
{'Comestibles', 660000},;
{'Bazar', 1030000}}
oDashBoard:AddGraph('Ventas', 'Ventas del periodo', 'PieChart', {'Rubro', 'Totales'}, aData, 'emerald' )
aData := {{'Mercado Pago', 1000000},;
{'Efectivo', 1170000},;
{'Tarjeta', 660000},;
{'Transferencia', 1030000},;
{'Cuenta Corriente', 1030000}}
oDashBoard:AddGraph('Cobros', 'Por Forma de pago', 'ColumnChart', {'Concepto', 'Importe'}, aData, 'purple' )
CASE n = 2
oDashBoard:AddPanel('Compras','$750,000','dollar-sign','emerald')
oDashBoard:AddPanel('Gastos' ,'$350,000','desktop','indigo')
oDashBoard:AddPanel('Stock' ,'7,000','cubes','indigo')
oDashBoard:AddPanel('Reciclado' ,'$90,000','recycle','purple')
aData := {{'Materia Prima', 300000},;
{'Productos Compraventa', 850000},;
{'Gastos', 690000}}
oDashBoard:AddGraph('Compras', 'Por Tipo de compra', 'BarChart', {'Concepto', 'Importe'}, aData, 'purple' )
CASE n = 3
oDashBoard:AddPanel('Tarjetas','$960,000','credit-card','pink')
oDashBoard:AddPanel('Efectivo','$1,050,000','dollar-sign','blue')
CASE n = 4
oDashBoard:AddPanel('Transferencias','$660,000','university','cyan')
oDashBoard:AddPanel('Efectivo','$550,000','dollar-sign','orange')
ENDCASE
RETURN oDashBoard:cHtml
********************************************
** Generar Html
CLASS TDashboard
DATA cHtml
DATA aGraph INIT {}
METHOD New() CONSTRUCTOR
METHOD AddPanel(cTexto, cValor, cFaFaIcon, cColor )
METHOD AddGraph (cNombre, cTitulo, cTipo, aColumnsData, aData, cColor )
ENDCLASS
//----------------------------------------------------------------//
METHOD New() CLASS TDashboard
TEXT INTO ::cHtml
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.1/css/all.css" crossorigin="anonymous">
<script type="text/javascript">
// Cargar Google Charts
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawCharts);
// Función para dibujar los gráficos
function drawCharts() {
//AgregarChar
}
//FuncionGrafico
window.onresize = function () {
drawCharts(); // Redibujar gráficos cuando la ventana cambia de tamaño
};
</script>
</head>
<body class="bg-gray-100">
<div class="flex flex-col lg:flex-row min-h-screen">
<!-- Main Content -->
<div class="flex-1 p-8 overflow-y-auto">
<div id="values" class="section">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- AddPanel -->
</div>
</div>
<div class="section p-2">
<hr>
</div>
<!-- Gráficos Section -->
<div id="charts" class="section">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-6">
<!-- idgrafico -->
</div>
</div>
</div>
</div>
</body>
</html>
ENDTEXT
return Self
METHOD AddPanel(cTexto, cValor, cFaFaIcon, cColor ) CLASS TDashboard
Local cPanel := '<div class="bg-white shadow-md p-6 h-50 rounded-lg text-center border-t-4 border-'+cColor+'-500">'+;
' <h3 class="text-lg font-bold text-'+cColor+'-500"><i class="fas fa-'+cFaFaIcon+' fa-3x"></i></h3>'+;
' <p class="text-xl mt-4 text-'+cColor+'-700">'+cTexto+'</p>'+;
' <p class="text-3xl mt-2 text-'+cColor+'-500 font-bold">'+cValor+'</p>'+;
'</div>'+;
'<!-- AddPanel -->'
::cHtml := strtran(::cHtml,"<!-- AddPanel -->",cPanel)
return Self
METHOD AddGraph (cNombre, cTitulo, cTipo, aColumnsData, aData, cColor )
Local cGraph, cFuncion, cId, i
cGraph := cNombre+'();//AgregarChar'
::cHtml := strtran(::cHtml,"//AgregarChar",cGraph)
cFuncion := "function "+cNombre+"() { "+;
"var data = google.visualization.arrayToDataTable(["+;
" ['"+aColumnsData[1]+"', '"+aColumnsData[2]+"'], "
for i := 1 to len(aData)
cFuncion := cFuncion + "['"+aData[i,1]+"', "+STR(aData[i,2])+"],"
next i
cFuncion := cFuncion + " ]);"+;
"var options = { "+;
" title: '"+cTitulo+"',"+;
" widht: '100%',"+;
" height: 300, "+;
" is3D: true "+;
"};"+;
"var chart = new google.visualization."+cTipo+"(document.getElementById('"+cNombre+"'));"+;
"chart.draw(data, options);"+;
"}"+;
"//FuncionGrafico"
::cHtml := strtran(::cHtml,"//FuncionGrafico",cFuncion)
cId := '<div class="bg-white shadow-md p-6 rounded-lg">'+;
'<h2 class="text-xl font-bold mb-4 text-'+cColor+'-500">'+cTitulo+'</h2>'+;
'<div id="'+cNombre+'"></div>'+;
'</div>'+;
'<!-- idgrafico -->'
::cHtml := strtran(::cHtml,"<!-- idgrafico -->",cId)
return Self
El método AddPanel tiene los siguientes parametros:
METHOD AddPanel(cTexto, cValor, cFaFaIcon, cColor )
cTexto -> El nombre del panel a mostrar
cValor -> El número que queremos mostrar en formato texto
cFaFaIcon -> El icono que queremos mostrar (Cualquiera de fa fa icons https://fontawesome.com/)
cColor -> Un color de la Tailwind https://tailwindcss.com/docs/customizing-colors que es el css que usa
El método AddGraph tiene los siguientes parametros:
METHOD AddGraph (cNombre, cTitulo, cTipo, aColumnsData, aData, cColor )
cNombre -> Nombre del grafico (que sea una sola palabra, porque lo convierte en la funcion a llamar por Javascrip)
cTitulo -> Titulo del grafico
cTipo -> Un tipo de grafico simple de google graph (PieChart, BarChart, ColumnChart, etc)
aColumnsData -> Array con los titulos de las columnas de los datos a mostrar en el grafico (2 columnas, 1 fila)
aData -> Array con los los datos a mostrar en el grafico (2 columnas, n filas)
cColor -> Un color de Tailwind para el color del titulo
Esto es muy mejorable, pero es un inicio, espero que los expertos sumen funcionalidades
- Antonio Linares
- Site Admin
- Posts: 42253
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: Webview 2 + Html
Querido César,
Muy bueno y muy inspirador!
muchas gracias
Muy bueno y muy inspirador!
muchas gracias
- Antonio Linares
- Site Admin
- Posts: 42253
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: Webview 2 + Html
César,
He simplificado mucho el modelo con la idea de usar la inteligencia artificial para hacer el trabajo
buildit.prg
He simplificado mucho el modelo con la idea de usar la inteligencia artificial para hacer el trabajo
buildit.prg
Code: Select all | Expand
#include "FiveWin.ch"
function Main()
local oWnd, oExplBar, oExplPanel, oWebView
local cCategory := Space( 30 )
DEFINE WINDOW oWnd TITLE "Build it"
oExplBar = TExplorerBar():New( 0, 82, 480, 100, oWnd:oLeft )
oWnd:oLeft = oExplBar
oExplBar:AddPanel( "My App" )
oExplPanel = oExplBar:AddPanel( "AI assistant" )
oExplPanel:AddLink( "what is this app about ?",;
{ || MsgGet( "App category", "Please specify it", @cCategory ) } )
oWnd:oClient = TPanel():New( 0, 0, 100, 100, oWnd )
oWebView = TWebView2():New( oWnd:oClient )
oWebView:Navigate( "https://www.google.com" )
ACTIVATE WINDOW oWnd MAXIMIZED ;
ON RESIZE ( oWebView:SetSize( nWidth - oExplBar:nWidth, nHeight ), oExplBar:SetSize( 480, nHeight ) )
return nil
Re: Webview 2 + Html
Si, esta mucho mas limpio.Antonio Linares wrote: He simplificado mucho el modelo con la idea de usar la inteligencia artificial para hacer el trabajo
Cual sería la idea de usar IA ? Para hacer los dashboard?
- Antonio Linares
- Site Admin
- Posts: 42253
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: Webview 2 + Html
Un ejemplo:
1. Preguntamos de que es la aplicación
El usuario responde, por ejemplo, contabilidad
2. la IA lista en un json las categorias que tiene que tener la aplicación y rellena el explorer bar
3. Al seleccionar una de esas opciones, se le pregunta a la IA que categorias debe tener esa opción
4. Finalmente al seleccionar la opción, se genera el HTML para dicha opción
Es algo muy simple pero tengo curiosidad de ver hasta donde se puede llegar. El código HTML se guarda en un campo memo
de forma que podamos mantener un histórico de las distintas versiones probadas.
1. Preguntamos de que es la aplicación
El usuario responde, por ejemplo, contabilidad
2. la IA lista en un json las categorias que tiene que tener la aplicación y rellena el explorer bar
3. Al seleccionar una de esas opciones, se le pregunta a la IA que categorias debe tener esa opción
4. Finalmente al seleccionar la opción, se genera el HTML para dicha opción
Es algo muy simple pero tengo curiosidad de ver hasta donde se puede llegar. El código HTML se guarda en un campo memo
de forma que podamos mantener un histórico de las distintas versiones probadas.
Re: Webview 2 + Html
Genial!
Me gustaría ver el avance.
Me gustaría ver el avance.
- TOTOVIOTTI
- Posts: 422
- Joined: Fri Feb 05, 2010 11:30 am
- Location: San Francisco - Córdoba - Argentina
Re: Webview 2 + Html
Siiiiiiiiiiiiiiiiiii.. se viene algo muy interesante acá!!!
Re: Webview 2 + Html
Muy interesante Antonio!
Esperamos el avance con entusiasmo
Esperamos el avance con entusiasmo
- ruben Dario
- Posts: 1070
- Joined: Thu Sep 27, 2007 3:47 pm
- Location: Colombia
Re: Webview 2 + Html
Excelente el curso, Y muy interesante lo de inteligencia Artificial, Gracias-
- Antonio Linares
- Site Admin
- Posts: 42253
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: Webview 2 + Html
Para probarlo necesitais registraros en OpenAI y obtener vuestra clave. Estamos usando el modelo "gpt-4o-mini" que es muy económico.
Ya hemos incluido la Clase TChatgpt para el próximo build de FWH.
buildit.prg
chatgpt.prg
Ya hemos incluido la Clase TChatgpt para el próximo build de FWH.
buildit.prg
Code: Select all | Expand
#include "FiveWin.ch"
// get your OpenAI key from https://platform.openai.com/api-keys
static cKey := "sk-proj-..."
static oChatgpt
static oTree
static cCategory := " "
function Main()
local oWnd, oExplBar, oAppPanel, oExplPanel, oWebView
oChatgpt = TChatgpt():New( cKey )
DEFINE WINDOW oWnd TITLE "Build it"
oExplBar = TExplorerBar():New( 0, 82, 480, 100, oWnd:oLeft, CLR_WHITE, RGB( 31, 31, 31 ) )
oWnd:oLeft = oExplBar
oExplPanel = oExplBar:AddPanel( "AI assistant" )
oExplPanel:AddLink( "what is this app about ?",;
{ || If( MsgGet( "App category", "Please specify it", @cCategory ), AddOptions( cCategory, oExplBar ),) } )
oExplPanel:AddLink( "Add options to selected item", { || AddSubOptions() } )
oWnd:oClient = TPanel():New( 0, 0, 100, 100, oWnd )
oWebView = TWebView2():New( oWnd:oClient )
oWebView:Navigate( "https://www.google.com" )
ACTIVATE WINDOW oWnd MAXIMIZED ;
ON RESIZE ( oWebView:SetSize( nWidth - oExplBar:nWidth, nHeight ), oExplBar:SetSize( 480, nHeight ) )
return nil
function AddOptions( cCategory, oExplBar )
local cOptions, aOptions, cOption, oAppPanel
oChatgpt:cPrompt := "genera una lista separada por comas con las opciones de una aplicación de " + AllTrim( cCategory ) + ;
". No des ninguna explicación"
oChatgpt:Send()
cOptions = oChatgpt:GetValue( "choices", "message", "content" )
aOptions = hb_ATokens( cOptions, "," )
oAppPanel = oExplBar:AddPanel( cCategory,, 700 )
oTree = TTreeView():New( 2.5, 2, oAppPanel,,,,, 423, 675 )
for each cOption in aOptions
oTree:Add( cOption )
next
return nil
function AddSubOptions()
local oItem
local cOption := If( ( oItem := oTree:GetSelected() ) != nil, oItem:cPrompt, "" )
local cOptions, cSubOption, aOptions
if ! Empty( cOption )
oChatgpt:cPrompt := "genera una lista separada por comas con las opciones de " + cOption + ;
" para una aplicación de " + cCategory + ". No des ninguna explicación"
oChatgpt:Send()
cOptions = oChatgpt:GetValue( "choices", "message", "content" )
aOptions = hb_ATokens( cOptions, "," )
for each cSubOption in aOptions
oItem:Add( cSubOption )
next
oItem:Expand()
endif
return nil
Code: Select all | Expand
#include "FiveWin.ch"
#include "hbcurl.ch"
//----------------------------------------------------------------------------//
CLASS TChatgpt
DATA cKey AS CHARACTER INIT ""
DATA hCurl
DATA nHttpCode
DATA nError INIT 0
DATA cResponse
DATA cPrompt
DATA cModel INIT "gpt-4o-mini"
DATA cUrl INIT "https://api.openai.com/v1/chat/completions"
METHOD New( cKey )
METHOD End()
METHOD Send()
METHOD Reset()
METHOD GetValue( ... )
ENDCLASS
//----------------------------------------------------------------------------//
METHOD New( cKey ) CLASS TChatgpt
::cKey := cKey
::hCurl := curl_easy_init()
return Self
//----------------------------------------------------------------------------//
METHOD Send() CLASS TChatgpt
local aheaders, nHttpCode, cJson, h := { => }, hMessage := { => }
curl_easy_setopt( ::hCurl, HB_CURLOPT_POST, .T. )
curl_easy_setopt( ::hCurl, HB_CURLOPT_URL, ::cUrl )
aheaders := { "Content-Type: application/json", ;
"Authorization: Bearer " + ::cKey }
curl_easy_setopt( ::hCurl, HB_CURLOPT_HTTPHEADER, aheaders )
curl_easy_setopt( ::hCurl, HB_CURLOPT_USERNAME, '' )
curl_easy_setopt( ::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt( ::hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
hb_HSet( h, "model", ::cModel )
hb_HSet( hMessage, "role", "user" )
hb_HSet( hMessage, "content", ::cPrompt )
h["messages"] = { hMessage }
cJson = hb_jsonEncode( h )
curl_easy_setopt( ::hcurl, HB_CURLOPT_POSTFIELDS, cJson )
::nError = curl_easy_perform( ::hCurl )
curl_easy_getinfo( ::hCurl, HB_CURLINFO_RESPONSE_CODE, @nHttpCode )
::nHttpCode = nHttpCode
if ::nError == HB_CURLE_OK
::cResponse = curl_easy_dl_buff_get( ::hCurl )
else
endif
return ::cResponse
//----------------------------------------------------------------------------//
METHOD Reset() CLASS TChatgpt
curl_easy_reset( ::hCurl )
::nError := HB_CURLE_OK
::cResponse := nil
return nil
//----------------------------------------------------------------------------//
METHOD End() CLASS TChatgpt
curl_easy_cleanup( ::hCurl )
::hCurl := nil
return nil
//----------------------------------------------------------------------------//
METHOD GetValue( ... ) CLASS TChatgpt
local aKeys := hb_AParams(), cKey
local uValue := hb_jsonDecode( ::cResponse )
for each cKey in aKeys
if ValType( uValue[ cKey ] ) == "A"
uValue = uValue[ cKey ][ 1 ]
else
uValue = uValue[ cKey ]
endif
next
return uValue
//----------------------------------------------------------------------------//
- Antonio Linares
- Site Admin
- Posts: 42253
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact: