Quickstarters
Come costruire un backend e-commerce?
90 min
in questo tutorial pratico, creerai un'applicazione e commerce full stack solida come una roccia da zero utilizzando un backend come servizio lungo il percorso, padroneggerai autenticazione sicura degli utenti, garantendo che solo gli acquirenti e gli amministratori autorizzati possano accedere modelli di dati intuitivi, progettati per alimentare cataloghi di prodotti, profili clienti e storici degli ordini api restful e in tempo reale, in modo che il tuo frontend rimanga sempre sincronizzato con l'inventario, i carrelli e lo stato del checkout pipeline di distribuzione automatizzate, che ti consentono di inviare aggiornamenti con fiducia e di tornare indietro se qualcosa va storto alla fine, avrai non solo un negozio online pronto per la produzione, ma anche le conoscenze architettoniche per estendere, scalare e proteggere qualsiasi applicazione web esplora l'applicazione e commerce finita in azione su web e commerce app iniziamo! punti chiave impostazione rapida del backend avvia e configura un modello di dati e‑commerce completo in pochi minuti con la piattaforma low‑code di back4app flussi utente sicuri implementa registrazioni, accessi e disconnessioni robusti utilizzando cloud code e token di sessione sviluppo api first accedi ai tuoi dati tramite endpoint rest/graphql generati automaticamente e il parse sdk per qualsiasi client logica aziendale in cloud code centralizza le operazioni principali—crud dei prodotti, gestione del carrello e checkout—mentre imponi permessi distribuzione frontend contenitorizzata imballa e distribuisci il tuo negozio next js in back4app web deployment per un hosting coerente e scalabile requisiti e configurazione dell'ambiente per seguire questo tutorial, assicurati di avere quanto segue un account back4app puoi registrarti gratuitamente sul sito web di back4app https //www back4app com/signup node js installato, che ti consente di gestire le dipendenze con npm o yarn familiarità con javascript per scrivere codice cloud personalizzato e sfruttare l'sdk di back4app comprensione di base dei concetti di e commerce come autenticazione degli utenti, gestione del catalogo prodotti e elaborazione degli ordini git per il controllo delle versioni, in modo da poter tenere traccia delle modifiche, tornare indietro se necessario e collaborare senza problemi assicurarti di avere gli elementi sopra ti aiuterà a massimizzare le capacità di back4app e implementare funzionalità chiave di e commerce senza rimanere bloccato creare e configurare il tuo account back4app per iniziare a configurare il tuo backend e commerce su back4app, visita back4app https //www back4app com e clicca su registrati inserisci il tuo indirizzo email, scegli una password forte e fornisci i dettagli richiesti una volta verificato il tuo email, avrai accesso alla dashboard di back4app pagina di registrazione di back4app all'interno della dashboard, seleziona crea nuova app o crea nuova app e dai un nome al tuo progetto—qualcosa di descrittivo in modo da poterlo trovare facilmente in seguito conferma le tue scelte, poi attendi che il processo di creazione dell'app sia completato il cruscotto del progetto mostrerà classi, analisi e configurazioni creazione di un app back4app con questi passaggi, hai creato una piattaforma di e commerce nella sezione successiva, progetterai il tuo schema dati e ti preparerai per la gestione dei prodotti, la gestione degli ordini e l'autenticazione degli utenti progettazione del tuo schema dati per l'e commerce per implementare un backend scalabile e manutenibile per la tua piattaforma di e commerce, organizzerai i tuoi dati attorno a sette tabelle fondamentali utente , acquirente , venditore , prodotto , carrello , ordine , e dettagliordine ogni tabella svolge un ruolo specifico nel supportare la funzionalità complessiva del sistema e insieme formano uno schema normalizzato ed efficiente inizia con la user tabella, che funge da base per tutte le identità degli utenti ogni persona sulla tua piattaforma—indipendentemente dal loro ruolo—si autenticherà utilizzando questa tabella includi campi come username , password , e email per gestire il login di base aggiungi emailverified per tracciare lo stato di verifica, e authdata se prevedi di supportare login di terze parti o flussi oauth per distinguere tra acquirenti e venditori, definisci un campo usertype questo campo ti consente di controllare l'accesso, gestire le visualizzazioni e separare le funzionalità in base ai ruoli degli utenti, mantenendo comunque un sistema di login unico e coerente invece di mescolare tutti i tipi di utenti in un'unica tabella, crea separate tabelle buyer e seller che fanno riferimento a user tramite il campo userid questo ti consente di memorizzare dati specifici per ruolo senza appesantire la tabella principale degli utenti la tabella buyer può contenere campi relativi agli acquisti come paymentinfo e shippingaddress , che sono essenziali per i processi di checkout e consegna al contrario, la tabella seller tiene traccia delle caratteristiche rilevanti per i commercianti, come storename , bio , e phonenumber con questa separazione, puoi gestire e interrogare facilmente acquirenti e venditori in modo indipendente, mantenendoli comunque collegati alla loro identità condivisa in user il tuo prodotto tavolo è dove sono memorizzati gli articoli in vendita ogni prodotto dovrebbe includere informazioni descrittive di base come un nome, una descrizione dettagliata e una o più immagini per la gestione dei prezzi e dell'inventario, vorrai anche includere campi per il prezzo, lo stato di disponibilità tramite un booleano isactive , e la quantità di stock sotto quantityavailable fondamentale, ogni prodotto deve essere collegato al venditore che lo ha elencato per stabilire quella relazione, aggiungi una sellerid chiave esterna che fa riferimento alla seller tabella questa struttura garantisce che ogni articolo nel tuo catalogo sia legato a un commerciante verificato e rende il filtraggio specifico per venditore semplice per gestire il comportamento pre acquisto, introduci una cart tabella ogni carrello appartiene a un utente, quindi includi un userid campo che si collega di nuovo a user memorizza un array di items , ciascuno rappresentante un prodotto che l'utente intende acquistare, insieme a qualsiasi metadato di cui hai bisogno come quantità o opzioni selezionate tracciare il totalprice del carrello ti consente di visualizzare rapidamente i riepiloghi di checkout senza ricalcolare i valori ad ogni richiesta questa configurazione supporta la funzionalità di base del carrello e semplifica la persistenza della sessione se trovi la struttura dell'array limitante—particolarmente se hai bisogno di registrare dati più complessi a livello di articolo—puoi sempre rifattorizzare gli articoli in una tabella separata in seguito quando un acquirente effettua un ordine, registrerai la transazione nella order tabella ogni ordine è legato a un buyerid , facendo riferimento alla buyer tabella per garantire che l'acquirente sia valido e autorizzato in aggiunta a questo collegamento, memorizza la orderdate , lo stato attuale orderstatus , e il valore monetario totale sotto il campo total questo ti fornisce un chiaro riepilogo dell'acquisto e supporta flussi di lavoro come il tracciamento e l'evasione degli ordini poiché ogni ordine può contenere più prodotti, avrai bisogno di una orderdetails tabella per gestire i singoli articoli questa tabella collega ogni articolo al suo ordine principale tramite orderid , e al prodotto acquistato utilizzando productid per registrare accuratamente lo stato dell'acquisto, includi la quantità acquistata e il prezzounitario al momento della vendita separare i dettagli dell'ordine in questo modo ti consente di costruire report, generare fatture e gestire resi o aggiustamenti con precisione questo schema, con la sua chiara separazione delle preoccupazioni e integrità relazionale, forma una solida base per il tuo sistema di e commerce con il modello di dati ora allineato ai flussi di lavoro reali della tua piattaforma, sei pronto per iniziare a implementarlo nel tuo backend inizia impostando le utente , acquirente , e venditore tabelle, e costruisci da lì impostazione delle classi nel dashboard segui i passaggi qui sotto per creare e collegare le tue entità in back4app definirai classi per utente , acquirente , venditore , carrello , prodotto , ordine , e dettagliordine , quindi stabilirai puntatori per rappresentare relazioni come ereditarietà, uno a molti e molti a molti accedi al database browser apri il dashboard della tua applicazione e crea una nuova classe chiamata utente clicca su database dal menu a sinistra back4app dashboard creazione della classe “utente” back4app crea automaticamente una classe utente la utente classe viene fornita con le seguenti colonne nomeutente password email ecc per aggiungere la tipoutente colonna, seleziona aggiungi una nuova colonna add new column fornisci il nome della colonna, il tipo di dati, il valore predefinito, ecc add usertype column nota in parse, ogni classe include un objectid predefinito, che funge da chiave primaria questo significa che objectid servirà effettivamente come userid nel tuo modello relazionale creazione della classe “buyer” per creare la classe buyer, torna al database browser e seleziona add class create new class scegli custom e chiamala buyer add buyer class aggiungi una pointer colonna chiamata user , che punta alla classe user create userid class questo simula l'“ereditarietà” facendo riferimento all' objectid , dell'utente base 3\ aggiungi le seguenti colonne indirizzospedizione (stringa) informazionipagamento (stringa) quando crei un nuovo oggetto acquirente, lo collegherai a un record utente esistente impostando buyer user all'objectid di quell'utente creazione della classe “venditore” ripeti lo stesso processo per creare una venditore classe aggiungi una puntatore colonna chiamata user che fa riferimento alla classe user aggiungi queste colonne aggiuntive nomenegozio (stringa) bio (stringa) numeroditelefono (numero) creazione della classe “prodotto” seleziona crea una classe di nuovo, chiamandola prodotto aggiungi una colonna puntatore chiamata venditore che punta alla classe venditore (questo impone una relazione uno a molti in cui un venditore può avere molti prodotti) aggiungi le seguenti colonne nome (stringa) descrizione (stringa) prezzo (numero) quantitàdisponibile (numero) èattivo (booleano) immagini (array) memorizza oggetti che rappresentano le immagini del prodotto creazione della classe “carrello” clicca crea una classe , chiama la classe carrello aggiungi una colonna puntatore chiamata utente che punta alla classe utente (questo collega ogni carrello a un utente specifico) poi aggiungi le seguenti colonne per rappresentare gli articoli nel carrello articoli (array) memorizza oggetti che rappresentano ciascun articolo del carrello ogni articolo può essere un oggetto come { prodotto puntatore a prodotto, quantità numero } prezzototale (numero) creazione della classe “ordine” crea una nuova classe chiamata order aggiungi una colonna pointer chiamata buyer che punta alla classe buyer (indicando che un acquirente può avere molti ordini) includi queste colonne orderdate (data o stringa, a seconda della tua preferenza) orderstatus (stringa) creazione della classe “orderdetails” infine, crea una classe chiamata orderdetails aggiungi due colonne pointer order → riferimenti a order product → riferimenti a product poi, aggiungi le colonne rimanenti quantity (numero) unitprice (numero) questa configurazione consente una relazione molti a molti tra order e product attraverso orderdetails , poiché ogni ordine può includere più prodotti e ogni prodotto può apparire in più ordini visualizzazione delle relazioni ecco un diagramma semplificato delle entità e delle relazioni (erd) che riflette le classi e i loro riferimenti dbschema2 una volta che queste classi sono in atto, puoi gestire le registrazioni e i login attraverso la classe user , creare record specializzati per acquirente o venditore per diversi tipi di utenti e memorizzare informazioni sui prodotti o sugli ordini con chiari riferimenti a chiavi esterne strutturando il tuo database in questo modo, ottieni un design pulito e manutenibile per qualsiasi applicazione di e commerce con il tuo schema in atto, sei pronto per impostare l'autenticazione e l'autorizzazione per limitare chi può elencare prodotti, effettuare ordini o svolgere compiti amministrativi il passo successivo ti mostrerà come configurare flussi di registrazione e accesso sicuri che si basano sui ruoli e sulle classi che hai appena definito implementazione dell'autenticazione con back4app l'autenticazione sicura è centrale per qualsiasi piattaforma di e commerce, aiutandoti a proteggere gli account degli utenti, i dettagli di pagamento e i dati personali back4app semplifica questo con più metodi—dalle classiche combinazioni di nome utente/password ai login social o flussi basati su token—garantendo che tu possa offrire ai tuoi acquirenti un'esperienza semplice e sicura per impostare l'autenticazione nella tua applicazione di e commerce, utilizzerai il cloud code il cloud code estende le capacità del tuo backend permettendoti di scrivere logica aziendale personalizzata senza dover ospitare i tuoi server questo significa che puoi convalidare ordini, calcolare commissioni o attivare notifiche su eventi specifici—interamente all'interno dell'infrastruttura di back4app è un modo ideale per gestire transazioni sensibili o processi di dati che necessitano di un controllo rigoroso e di un'esecuzione rapida per abilitare il cloud code su back4app, apri il dashboard della tua app e individua la cloud code sezione find cloud code quando clicchi su cloud code , vedrai un main js dove puoi iniziare a implementare funzioni personalizzate cloud code per implementare il flusso di autenticazione in back4app, sarà necessario distribuire alcune funzioni sul tuo codice cloud per registrare utenti, effettuare il login e disconnettere gli utenti registrare un nuovo utente (acquirente per default) per registrare un nuovo utente, utilizza il metodo di registrazione di parse imposta campi standard come username , password , e email , e includi un campo personalizzato per indicare il ruolo o buyer o seller per impostazione predefinita, ai nuovi utenti viene assegnato il ruolo di buyer fino a quando non decidono di cambiarlo per iniziare, crea un auth js file nella directory cloud del tuo codice cloud e aggiungi il blocco di codice qui sotto parse cloud define('signupuser', async (request) => { const { name, password, confirmpassword, email, shippingaddress, paymentinfo } = request params; // validate password match if (password !== confirmpassword) { throw new error('passwords do not match'); } const user = new parse user(); user set('username', name); user set('password', password); user set('email', email); user set('usertype', "buyer"); try { // sign up the user const signedupuser = await user signup(); console log('user registered ', signedupuser id); // create a buyer record linked to the new user const buyer = parse object extend('buyer'); const buyer = new buyer(); buyer set('user', signedupuser); buyer set('shippingaddress', shippingaddress); buyer set('paymentinfo', paymentinfo); const savedbuyer = await buyer save(); console log('buyer created ', savedbuyer id); return { success true, message 'user registered and buyer created', userid signedupuser id, buyerid savedbuyer id }; } catch (error) { console error('sign up failed ', error); throw new error('sign up failed ' + error message); } }); questa cloud function gestisce la registrazione degli utenti per gli acquirenti valida l'input, crea un nuovo utente parse, assegna un ruolo ( buyer ), e memorizza i dati specifici per gli acquirenti in una classe buyer separata accedi agli utenti per autenticare gli utenti, chiama il metodo integrato di parse parse user login e restituisci il token di sessione al client aggiungi il seguente codice al tuo auth js file per implementare questa logica nel tuo backend di cloud code parse cloud define("loginuser", async (request) => { const { email, password } = request params; try { const user = await parse user login(email, password); // example block users with disabled flag if (user get("isdisabled")) { throw new parse error(403, "account is disabled"); } return { sessiontoken user getsessiontoken(), userid user id, }; } catch (error) { throw new parse error(101, "invalid credentials"); } }); questa funzione prende un'email e una password dal client, tenta di autenticare l'utente e restituisce il token di sessione se ha successo se l'account è contrassegnato come disabilitato, blocca l'accesso e genera un errore chiaro disconnettersi per implementare la funzione di disconnessione per il tuo backend, aggiungi il blocco di codice qui sotto al tuo auth js file parse cloud define('logoutuser', async (request) => { const sessiontoken = request headers\['x parse session token']; if (!sessiontoken) { throw new error('session token required'); } const sessionquery = new parse query(' session'); sessionquery equalto('sessiontoken', sessiontoken); const session = await sessionquery first({ usemasterkey true }); if (session) { await session destroy({ usemasterkey true }); } return { success true, message 'session invalidated' }; }); questo termina in modo sicuro la sessione sul backend, impedendo ulteriori utilizzi del token con queste funzioni di cloud code in atto, ora hai un sistema di autenticazione sicuro che registra gli utenti con logica basata sui ruoli autentica e autorizza l'accesso utilizzando token di sessione collega gli account utente a registri specifici per acquirenti supporta flussi di login e disconnessione puliti sfrutta gli strumenti di verifica della sessione e dell'email integrati di back4app costruire la logica aziendale per la tua app ecommerce per gestire utenti, prodotti, carrelli e transazioni nella tua piattaforma di e commerce, definirai una serie di funzioni di cloud code in back4app queste funzioni ti consentono di creare, leggere, aggiornare e eliminare (crud) risorse come venditori, prodotti e ordini mantenendo il controllo degli accessi sicuro legato ai ruoli degli utenti di seguito è riportato un insieme di funzioni cloud che dimostrano come lavorare con entità chiave venditore , prodotto , carrello , ordine , e dettagliordine ogni funzione gestisce un'operazione specifica del backend e garantisce che i permessi siano applicati attraverso la validazione degli utenti e i controlli dei ruoli venditore crea un profilo venditore per un utente che desidera offrire prodotti sulla piattaforma creazione di un venditore questa funzione aggiorna il ruolo dell'utente attuale a venditore e crea un venditore record con le informazioni del negozio per implementare questo nel tuo codice cloud, prima crea un seller js file e aggiungi il blocco di codice qui sotto parse cloud define('createseller', async (request) => { const currentuser = request user; // get the current logged in user if (!currentuser) { throw new error('user is not logged in'); } try { // check and update the user type const usertype = currentuser get('usertype'); if (usertype === 'buyer') { currentuser set('usertype', 'seller'); await currentuser save(); } // create the seller object const { businessname, bio, phone } = request params; const seller = parse object extend('seller'); const seller = new seller(); seller set('user', currentuser); seller set('storename', businessname); seller set('bio', bio); seller set('phonenumber', number(phone)); const newseller = await seller save(); console log('seller created ', newseller id); return { success true, message 'seller account created', sellerid newseller id }; } catch (error) { console error('error creating seller ', error); throw new error('error creating seller ' + error message); } }); questo garantisce che solo gli utenti autenticati possano diventare venditori e collega il venditore record all'utente corrispondente tramite un puntatore prodotto i prodotti sono elencati dai venditori e possono essere sfogliati, interrogati e acquistati dagli acquirenti queste funzioni consentono ai venditori di creare, recuperare, aggiornare ed eliminare i propri prodotti e forniscono anche accesso ai prodotti per gli acquirenti creare un prodotto questa funzione aggiunge un nuovo prodotto per un venditore connesso e allega fino a tre immagini del prodotto per implementarlo nel tuo codice cloud, crea un product js file e aggiungi il blocco di codice qui sotto parse cloud define("addproduct", async (request) => { // destructure parameters sent from the client const { name, description, price, quantityavailable, isactive, imagefiles } = request params; // optional check if user is logged in (request user is available when an active session exists) const currentuser = request user; if (!currentuser) { throw new error("unauthorized you must be logged in to add a product "); } // ensure the user is indeed a seller by checking their usertype const usertype = currentuser get("usertype"); if (usertype != "seller") { throw new error("this user is not a seller "); } const seller = parse object extend("seller"); const query = new parse query(seller); query equalto("userid", currentuser); // match the pointer field in seller const sellerobj = await query first({ usemasterkey true }); if (!sellerobj) { throw new error("no matching 'seller' object found for this user "); } if(!array isarray(imagefiles) || imagefiles length > 3) { throw new error("a maximum of 3 images are provided"); } // create the new product object const product = parse object extend("product"); const product = new product(); product set("seller", sellerobj); // pointer to the seller product set("name", name); product set("description", description); product set("price", number(price)); product set("quantityavailable", number(quantityavailable)); product set("isactive", isactive); product set("images", imagefiles); // save the product to the database try { const savedproduct = await product save(null, { usemasterkey true }); return savedproduct; } catch (error) { throw new error(`could not create product ${error message}`); } }); questa funzione verifica che l'utente sia connesso e abbia un ruolo di venditore, che esista un corrispondente seller oggetto, e che non vengano inviate più di tre immagini una volta convalidato, memorizza il prodotto e lo collega al venditore interrogare tutti i prodotti questa funzione recupera tutti i prodotti nel sistema, che possono essere utilizzati per costruire un negozio pubblico per implementare questo nel tuo codice cloud, aggiungi il blocco di codice qui sotto al tuo products js file parse cloud define("fetchallproducts", async (request) => { try { const product = parse object extend("product"); const query = new parse query(product); const products = await query find({ usemasterkey true }); // return products in a json friendly format return products map((product) => ({ id product id, sellerid product get("seller")? id, name product get("name"), description product get("description"), price product get("price"), quantityavailable product get("quantityavailable"), isactive product get("isactive"), createdat product createdat, updatedat product updatedat, })); } catch (error) { throw new error(`error fetching products ${error message}`); } }); questa funzione recupera i prodotti con il usemasterkey flag, e li formatta per il consumo frontend interrogare un singolo prodotto usa questa funzione quando visualizzi informazioni dettagliate sul prodotto per gli acquirenti per implementarlo nel tuo codice cloud, aggiungi il blocco di codice qui sotto al tuo products js file parse cloud define("getsingleproduct", async (request) => { const { productid } = request params; const currentuser = request user; // ensure user is logged in if (!currentuser) { throw new error("you must be logged in to retrieve product information "); } if (!productid) { throw new error("missing required parameter productid "); } // query the product class const product = parse object extend("product"); const query = new parse query(product); query equalto("objectid", productid); try { const product = await query first({ usemasterkey true }); if (!product) { throw new error("product not found "); } // return a json friendly object return { objectid product id, name product get("name"), description product get("description"), price product get("price"), quantityavailable product get("quantityavailable"), isactive product get("isactive"), // optionally return more fields like images, category, etc }; } catch (error) { throw new error(`error fetching product ${error message}`); } }); questa funzione restituisce i dettagli completi del prodotto per un articolo verifica che un valido productid venga passato e assicura che il richiedente sia connesso interrogare i prodotti del venditore questa funzione consente a un venditore di recuperare tutti i propri prodotti per implementarlo nel tuo codice cloud, aggiungi il blocco di codice qui sotto al tuo products js file parse cloud define("getsellerproducts", async (request) => { const currentuser = request user; // ensure the user is logged in if (!currentuser) { throw new error("you must be logged in to fetch seller products "); } // if your schema depends on verifying the user is truly a seller, you can check usertype const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can view their own products "); } // if you want to retrieve products for the currently logged in seller // fetch the seller record that points to currentuser const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // finally, fetch all products pointing to this seller const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("seller", sellerrecord); productquery limit(1000); // adjust or paginate as needed try { const products = await productquery find({ usemasterkey true }); // return a more friendly json structure return products map((prod) => ({ objectid prod id, name prod get("name"), description prod get("description"), price prod get("price"), quantityavailable prod get("quantityavailable"), isactive prod get("isactive"), createdat prod createdat, updatedat prod updatedat, })); } catch (error) { throw new error(`error fetching seller products ${error message}`); } }); questa funzione conferma che l'utente è un venditore, localizza il seller associato e interroga la classe product utilizzando un puntatore al venditore i venditori usano questo per recuperare tutti i propri prodotti eliminare un prodotto questa funzione garantisce che solo il venditore che ha creato un prodotto possa eliminarlo per implementare questo nel tuo codice cloud, aggiungi il blocco di codice qui sotto al tuo products js file parse cloud define("deleteproduct", async (request) => { const { productid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to delete a product "); } const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can delete products "); } if (!productid) { throw new error("missing required parameter productid "); } // 1 find the seller record for the current user const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // 2 fetch the product with a query that ensures the user owns it const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); productquery equalto("seller", sellerrecord); // must match the correct seller const product = await productquery first({ usemasterkey true }); if (!product) { throw new error("product not found or you do not have permission to delete it "); } // 3 destroy the product try { await product destroy({ usemasterkey true }); return { message "product deleted successfully ", productid }; } catch (error) { throw new error(`error deleting product ${error message}`); } }); questa funzione conferma la proprietà dell'utente e poi rimuove il prodotto dal database aggiornare un prodotto consenti ai venditori di modificare i dettagli di un prodotto utilizzando questa funzione per implementarlo nel tuo codice cloud, aggiungi il blocco di codice qui sotto al tuo products js file parse cloud define("updateproduct", async (request) => { const { productid, name, description, price, quantityavailable, isactive } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to update a product "); } const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can update products "); } if (!productid) { throw new error("missing required parameter productid "); } // 1 find the seller record for the current user const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // 2 fetch the product const product = parse object extend("product"); const query = new parse query(product); query equalto("objectid", productid); query equalto("seller", sellerrecord); // must match the seller to ensure ownership const product = await query first({ usemasterkey true }); if (!product) { throw new error("product not found or you do not have permission to modify it "); } // 3 update product fields if (name !== undefined) product set("name", name); if (description !== undefined) product set("description", description); if (price !== undefined) product set("price", price); if (quantityavailable !== undefined) product set("quantityavailable", quantityavailable); if (isactive !== undefined) product set("isactive", isactive); // 4 save changes try { const updatedproduct = await product save(null, { usemasterkey true }); return { objectid updatedproduct id, name updatedproduct get("name"), description updatedproduct get("description"), price updatedproduct get("price"), quantityavailable updatedproduct get("quantityavailable"), isactive updatedproduct get("isactive"), }; } catch (error) { throw new error(`error updating product ${error message}`); } }); garantisce che l'utente sia un venditore, conferma la proprietà del prodotto e aggiorna solo i campi forniti nella richiesta carrello le carrello funzioni consentono agli acquirenti di gestire gli articoli che intendono acquistare queste funzioni includono l'aggiunta al carrello, l'aggiornamento delle quantità, la visualizzazione dei contenuti e la rimozione degli articoli aggiunta al carrello questa funzione aggiunge un prodotto al carrello dell'acquirente o aggiorna la quantità se esiste già per implementare questo, crea un cart js file e aggiungi il blocco di codice qui sotto parse cloud define("addtocart", async (request) => { const { productid, quantity } = request params; // ensure there is a currently logged in user const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to modify the cart "); } if (!productid || !quantity) { throw new error("missing required parameters productid and quantity "); } // 1 fetch or create the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); let cart = await cartquery first({ usemasterkey true }); if (!cart) { cart = new cart(); cart set("user", currentuser); cart set("items", \[]); // initialize empty array cart set("totalprice", 0); // initialize price } // 2 fetch the product for price details (or any other attributes you need) const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); const product = await productquery first({ usemasterkey true }); if (!product) { throw new error("product not found "); } const productprice = product get("price") || 0; // 3 insert or update the item in the cart const cartitems = cart get("items") || \[]; // check if this product is already in the cart const existingitemindex = cartitems findindex( (item) => item product objectid === productid ); if (existingitemindex >= 0) { // if product is already in cart, update the quantity cartitems\[existingitemindex] quantity += quantity; } else { // otherwise, add a new entry cartitems push({ product { type "pointer", classname "product", objectid productid, }, quantity quantity }); } // 4 recalculate total price // e g , summation of productprice quantity for each cart item let total = 0; for (const item of cartitems) { if (item product objectid === productid) { // use productprice from the newly fetched product total += productprice item quantity; } else { // this is a simplified approach ideally, you'd also store a price attribute on each item // or re fetch each product's price // for demonstration, we'll just skip them } } cart set("items", cartitems); cart set("totalprice", total); // 5 save the cart object try { const savedcart = await cart save(null, { usemasterkey true }); return { message "cart updated successfully", cartid savedcart id, items savedcart get("items"), totalprice savedcart get("totalprice"), }; } catch (error) { throw new error(`error saving cart ${error message}`); } }); assicura che l'utente sia autenticato, valida il prodotto, aggiorna l'elenco degli articoli e ricalcola il prezzo totale del carrello interrogare il carrello recupera i contenuti del carrello dell'utente attuale, inclusi i dettagli del prodotto e i subtotali per implementare questo, aggiungi il blocco di codice qui sotto al tuo cart js file parse cloud define("getcart", async (request) => { if (!request user) throw "user must be logged in "; const user = request user; const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", user); cartquery include("items product"); // deep include const cart = await cartquery first(); if (!cart) return { items \[], totalprice 0 }; const items = cart get("items") || \[]; const parseditems = \[]; for (const item of items) { const product = item product; parseditems push({ productid product id, name product get("name"), price product get("price"), image product get("image")? url() || null, quantity item quantity, subtotal product get("price") item quantity, }); } return { cartid cart id, items parseditems, totalprice cart get("totalprice") || 0, }; }); questa funzione utilizza include("items product") per recuperare i dati del prodotto annidati in un'unica query modifica del carrello aggiorna la quantità di un articolo nel carrello o rimuovilo completamente se la nuova quantità è zero per implementare questo, aggiungi il blocco di codice qui sotto al tuo cart js file parse cloud define("updatecart", async (request) => { const { productid, newquantity } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to update the cart "); } if (!productid || newquantity === undefined) { throw new error("missing required parameters productid and newquantity "); } // fetch or create the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); let cart = await cartquery first({ usemasterkey true }); if (!cart) { // if there's no existing cart, create one cart = new cart(); cart set("user", currentuser); cart set("items", \[]); cart set("totalprice", 0); } let cartitems = cart get("items") || \[]; // find the item matching the productid const itemindex = cartitems findindex( (item) => item product id === productid ); if (itemindex === 1) { throw new error("product not found in cart please add it first "); } // if newquantity <= 0, remove the item from the cart if (newquantity <= 0) { cartitems splice(itemindex, 1); } else { // otherwise, update the quantity cartitems\[itemindex] quantity = newquantity; } // recalculate total by fetching current prices from each product let total = 0; if (cartitems length > 0) { const product = parse object extend("product"); // for each item in the cart, fetch the product to get its price for (const item of cartitems) { const productquery = new parse query(product); productquery equalto("objectid", item product objectid); const product = await productquery first({ usemasterkey true }); if (product) { const productprice = product get("price") || 0; total += productprice item quantity; } } } // update and save the cart cart set("items", cartitems); cart set("totalprice", total); try { const updatedcart = await cart save(null, { usemasterkey true }); return { message "cart updated successfully", cartid updatedcart id, items updatedcart get("items"), totalprice updatedcart get("totalprice"), }; } catch (error) { throw new error(`error updating cart ${error message}`); } }); rivalida tutti i prezzi dei prodotti durante l'aggiornamento per garantire la massima accuratezza eliminazione dal carrello questa funzione rimuove un prodotto dal carrello dell'utente per implementare questo, aggiungi il blocco di codice qui sotto al tuo cart js file parse cloud define("removefromcart", async (request) => { const { productid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to remove items from the cart "); } if (!productid) { throw new error("missing required parameter productid "); } // fetch the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); const cart = await cartquery first({ usemasterkey true }); if (!cart) { throw new error("no existing cart found for this user "); } let cartitems = cart get("items") || \[]; // filter out the item with the specified productid const filtereditems = cartitems filter( (item) => item product id !== productid ); // if nothing changed, the product wasn't in the cart if (filtereditems length === cartitems length) { throw new error("product not found in cart "); } // recalculate the cart total let total = 0; if (filtereditems length > 0) { const product = parse object extend("product"); for (const item of filtereditems) { const productquery = new parse query(product); productquery equalto("objectid", item product objectid); const product = await productquery first({ usemasterkey true }); if (product) { const productprice = product get("price") || 0; total += productprice item quantity; } } } // update and save the cart cart set("items", filtereditems); cart set("totalprice", total); try { const updatedcart = await cart save(null, { usemasterkey true }); return { message "item removed from cart", cartid updatedcart id, items updatedcart get("items"), totalprice updatedcart get("totalprice"), }; } catch (error) { throw new error(`error removing item from cart ${error message}`); } }); filtra l'elemento dall'array del carrello e ricalcola il totale prima di salvare ordine queste funzioni gestiscono il processo di ordinazione—dalla creazione degli ordini al recupero della cronologia degli ordini di un venditore creare un ordine questa funzione converte il carrello dell'acquirente in un ordine ufficiale per implementare questo, crea un order js file e aggiungi il blocco di codice qui sotto parse cloud define("createorder", async (request) => { const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to place an order "); } // ensure the user is a buyer (assumes buyer class with user pointer) const buyer = parse object extend("buyer"); const buyerquery = new parse query(buyer); buyerquery equalto("user", currentuser); const buyer = await buyerquery first({ usemasterkey true }); if (!buyer) { throw new error("only buyers can place orders "); } // retrieve the cart for the user const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", buyer get("user")); // assuming the user pointer is stored in buyer const cart = await cartquery first({ usemasterkey true }); if (!cart || !cart get("items") || cart get("items") length === 0) { throw new error("cart is empty"); } const items = cart get("items"); let totalamount = 0; // adjust stock and calculate total order price const orderdetails = \[]; for (const item of items) { const productid = item product id; const quantity = item quantity; const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); const product = await productquery first({ usemasterkey true }); if (!product) { throw new error(`product with id ${productid} not found`); } const availablequantity = product get("quantityavailable"); if (availablequantity < quantity) { throw new error(`not enough stock for product ${product get("name")}`); } // reduce the product quantity product set("quantityavailable", availablequantity quantity); await product save(null, { usemasterkey true }); const unitprice = product get("price"); totalamount += unitprice quantity; // prepare order detail entry orderdetails push({ product, quantity, unitprice }); } // create the new order object const order = parse object extend("order"); const order = new order(); order set("buyer", buyer); // set the buyer pointer order set("total", totalamount); // set the total amount order set("orderstatus", "pending"); // set the order status order set("orderdate", new date()); // set the order date // save the order to the database try { const savedorder = await order save(null, { usemasterkey true }); // create orderdetails for each item const orderdetails = parse object extend("orderdetails"); for (const detail of orderdetails) { const orderdetail = new orderdetails(); orderdetail set("order", savedorder); orderdetail set("product", detail product); orderdetail set("quantity", detail quantity); orderdetail set("unitprice", detail unitprice); await orderdetail save(null, { usemasterkey true }); } // optionally, clear the cart after saving the order cart set("items", \[]); await cart save(null, { usemasterkey true }); return savedorder; } catch (error) { throw new error(`could not create order ${error message}`); } }); convalida l'acquirente, controlla la disponibilità del magazzino, riduce l'inventario dei prodotti, salva sia ordine che dettagliordine , e svuota il carrello dopo un ordine riuscito ottenere ordini del venditore questa funzione recupera tutti gli ordini che includono prodotti venduti dal venditore attuale per implementare questo, aggiungi il blocco di codice qui sotto al tuo order js file parse cloud define("getsellerorders", async (request) => { const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to view your orders "); } if (currentuser get("usertype") !== "seller") { throw new error("only sellers can access this endpoint "); } try { const seller = parse object extend("seller"); const seller = await new parse query(seller) equalto("userid", currentuser) first({ usemasterkey true }); if (!seller) { throw new error("seller profile not found "); } // find products by this seller const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("seller", seller); const products = await productquery find({ usemasterkey true }); if (!products || products length === 0) { return \[]; } // get product ids const productids = products map(product => product id); // find order details containing these products const orderdetails = parse object extend("orderdetails"); const orderdetailsquery = new parse query(orderdetails); orderdetailsquery containedin("product", products); const orderdetails = await orderdetailsquery find({ usemasterkey true }); if (!orderdetails || orderdetails length === 0) { return \[]; } const orderids = \[ new set(orderdetails map(detail => detail get("order") id))]; // query orders for these ids const order = parse object extend("order"); const orderquery = new parse query(order); orderquery containedin("objectid", orderids); orderquery include("buyer"); const orders = await orderquery find({ usemasterkey true }); // return the orders return orders map(order => ({ id order id, total order get("total"), status order get("orderstatus"), date order get("orderdate"), buyer order get("buyer") })); } catch (error) { throw new error(`could not fetch orders ${error message}`); } }); localizza i prodotti di proprietà del venditore, interroga orderdetails per quei prodotti, recupera gli ordini corrispondenti e restituisce una struttura semplificata che include le informazioni dell'acquirente aggiornamento dello stato dell'ordine questa funzione alterna lo stato di un ordine tra “in attesa” e “completato ” per implementare questo, aggiungi il blocco di codice qui sotto al tuo order js file parse cloud define("updateorder", async (request) => { const { orderid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to view your orders "); } if (currentuser get("usertype") !== "seller") { throw new error("only sellers can access this endpoint "); } // validate the input parameter if (!orderid) { throw new error("missing required field orderid"); } try { // find the order with the specified orderid const order = parse object extend("order"); const query = new parse query(order); query equalto("objectid", orderid); const order = await query first({ usemasterkey true }); if (!order) { throw new error("order not found"); } // check current status // update the order status if (order get("orderstatus") === "completed") { order set("orderstatus", "pending"); } else { order set("orderstatus", "completed"); } // save the updated order await order save(null, { usemasterkey true }); return { success true, message "order status updated to completed" }; } catch (error) { throw new error(`could not update order status ${error message}`); } }); garantisce che solo i venditori possano eseguire questa azione e che l'ordine esista prima di aggiornare lo stato queste funzioni backend danno alla tua app di e commerce la possibilità di gestire in modo sicuro tutte le operazioni fondamentali—elenco dei prodotti, carrelli degli acquirenti, ordini e inventario dei venditori—direttamente all'interno di back4app utilizzando il cloud code per garantire che tu possa accedere a queste funzioni cloud esternamente, devi registrare tutti i tuoi file di codice cloud nel tuo main js file, puoi farlo aggiungendo il blocco di codice qui sotto al tuo main js file //main js require(" /auth js") require(" /cart js") require(" /order js") require(" /product js") require(" /seller js") creazione del frontend per costruire visivamente il tuo negozio e commerce, utilizzerai v0 dev per fare ciò, inizia visitando v0 dev http //v0 dev crea un account se non ne hai già uno una volta impostato il tuo account, puoi iniziare a creare il tuo frontend per creare il tuo frontend, inserisci il prompt qui sotto create an e commerce web application with authentication features and a buyer and seller feature il prompt costruirà un'app ecommerce next js con le funzionalità richieste create ecommerce app utilizzando la funzione di anteprima, puoi navigare attraverso l'applicazione per confermare che tutto funzioni come previsto se ci sono complicazioni o vuoi aggiungere ulteriori funzionalità, puoi passare un altro prompt e v0 modificherà l'applicazione ad esempio, passa il prompt the seller can create, add, delete and update products questo prompt modificherà l'app, creando pagine in cui il venditore può eseguire operazioni crud modify ecommerce app infine, passa il prompt do not sort products by categories and remove the categories page and input fields, remove the second and third step from the process of becoming a seller and add a bio input field to the first step, users should only sign in with email, and enhance the seller functionality to fully support product management (crud operations) questo prompt apporterà le modifiche finali all'applicazione per ottenere un'anteprima dell'applicazione modificata, fai clic sul visualizza pulsante nella sezione evidenziata nell'immagine sopra una volta che sei sicuro che l'applicazione è ciò che desideri, il passo successivo è portare il progetto sul tuo dispositivo locale per fare questo, clicca sul pulsante di download che v0 genera con la risposta del prompt pulsante di download cliccando sul pulsante verrà visualizzato un menu a discesa con un link e un pulsante di download zip menu a discesa successivamente, clicca sul pulsante di download zip una volta completato il download dello zip, apri il tuo terminale e crea una nuova cartella chiamata ecommerce app nella tua directory preferita mkdir ecommerce app ora estrai il contenuto della cartella zip nella cartella ecommerce app naviga nella directory ecommerce app sul tuo terminale e installa le dipendenze necessarie per fare questo, esegui il seguente comando cd ecommerce app npm install dopo aver installato le dipendenze, esegui il comando npm run dev sul tuo terminale per visualizzare il progetto sul tuo server localhost integrare il tuo frontend con il tuo backend per connettere il tuo frontend con le funzioni cloud code nel tuo backend di back4app, utilizzerai il parse javascript sdk l'sdk ti consente di autenticare gli utenti, chiamare funzioni di backend e interagire con i modelli di dati della tua app in modo sicuro ed efficiente per configurare l'sdk, esegui il seguente comando nella directory del tuo progetto nel terminale npm install parse poi crea un lib/parse js file per configurare la connessione in questo file, inserisci il blocco di codice qui sotto import parse from "parse/dist/parse min js"; parse initialize("your app id", "your javascript key"); parse serverurl = "https //parseapi back4app com"; export default parse; sostituisci your app id e your javascript key con le credenziali trovate nel tuo dashboard di back4app sotto app settings questa configurazione di base assicura che l'sdk sappia come connettersi al tuo progetto specifico ora che hai collegato il tuo frontend al tuo backend, puoi iniziare a scrivere funzioni per chiamare le funzioni di codice cloud che hai definito nella tua applicazione back4app autenticazione sul client questa sezione mostra come gestire la registrazione, il login e il logout degli utenti nel tuo frontend utilizzando l'sdk di parse ogni funzione corrisponde a una funzione di cloud code o a un metodo sdk che hai implementato nel tuo backend di back4app nella tua applicazione, la app/auth/register directory contiene la logica per registrare gli utenti nel page tsx definisci lo stato formdata questo stato conterrà le credenziali necessarie per registrare un utente lo stato formdata dovrebbe apparire così const \[formdata, setformdata] = usestate({ name "", email "", password "", confirmpassword "", shippingaddress "", paymentinfo "", }); con le credenziali passate nel formdata , puoi chiamare la signupuser funzione cloud che hai definito nella tua applicazione back4app assicurati di importare parse da lib/parse js import parse from "@/lib/parse"; const handlesubmit = async(e react formevent) => { e preventdefault(); try { const response = await parse cloud run("signupuser", { name formdata name, email formdata email, password formdata password, confirmpassword formdata confirmpassword, shippingaddress formdata shippingaddress, paymentinfo formdata paymentinfo, }); console log("signup successful ", response); } catch (error any) { console error("signup failed ", error); } } questa funzione verrà eseguita quando invii il modulo di registrazione chiama la signupuser funzione cloud definita nel cloud code la funzione passa le credenziali dell'utente e i dati specifici dell'acquirente (come le informazioni di spedizione e pagamento) infine, registra la risposta se l'operazione ha successo o stampa un errore se fallisce accesso degli utenti per accedere a un utente, utilizza la loginuser funzione di codice cloud nel tuo backend naviga nella app/auth/login directory della tua applicazione all'interno del page tsx file, v0 avrà creato lo stato contenente le credenziali dell'utente di cui hai bisogno per accedere, tutto ciò che devi fare è passare quelle credenziali alla loginuser funzione ad esempio import parse from "@/lib/parse"; const handlesubmit = async (e react formevent) => { e preventdefault(); setisloading(true); try { const result = await parse cloud run("loginuser", { email, password }); // log in using returned session token await parse user become(result sessiontoken); console log("user logged in with session ", result sessiontoken); setisloading(false); router push("/"); // proceed to app } catch (error) { console error("login failed ", error); } }; questa funzione invoca la funzione cloud loginuser , inviando le credenziali di accesso dell'utente al server dopo aver ricevuto un token di sessione valido in risposta, utilizza parse user become per autenticare il client e stabilire la sessione come appartenente all'utente connesso disconnettere gli utenti per disconnettere in modo sicuro un utente, chiamerai sia parse user logout() che la tua funzione personalizzata logoutuser nel cloud code questo assicura che il token di sessione venga cancellato sia sul client che invalidato sul server troverai il pulsante di disconnessione nel tuo componente header questo componente si troverà nella tua components cartella nella directory principale nel componente, definisci questa funzione const handlelogout = async () => { const sessiontoken = parse user current()? get("sessiontoken"); if (sessiontoken) { await parse user become(sessiontoken); // ensures proper context await parse cloud run("logoutuser"); // delete the session on server } await parse user logout(); // clear the local session }; questa funzione disconnetterà un utente e cancellerà la sessione sia sul client che sul server nella parte jsx del componente, collega la funzione al pulsante di disconnessione utilizzando l' onclick evento ad esempio \<dropdownmenuitem onclick={handlelogout}> logout \</dropdownmenuitem> onboarding venditore questa sezione mostra una funzione per consentire agli acquirenti di aggiornare il proprio account e registrarsi come venditori nella tua applicazione, naviga nella directory app/seller/register in questa directory, troverai il tuo page tsx file dove definirai la funzione che chiama la createseller funzione cloud questa funzione è responsabile della creazione di un profilo venditore per l'utente attuale nel page tsx file, modifica lo stato formdata per apparire così const \[formdata, setformdata] = usestate({ phone "", bio "", businessname "", }); sostituisci la logica nella handlesubmit funzione creata da v0 con la logica qui sotto const handlesubmit = async (e react formevent) => { e preventdefault(); try { const result = await parse cloud run("createseller", { businessname formdata businessname, bio formdata bio, phone formdata phone, }); console log("seller created ", result sellerid); } catch (error) { console error("error creating seller ", error); } }; chiama questa funzione quando invii il modulo per creare un profilo venditore per i tuoi utenti gestione del prodotto usa queste chiamate di funzione nel tuo frontend per gestire le operazioni sui prodotti come venditore creazione di un prodotto per chiamare la funzione di codice cloud che aggiunge un prodotto al database, individua la app/seller/products/new directory all'interno di questa directory si trova il tuo page tsx file, in questo file c'è un modulo questo modulo prende le informazioni per il prodotto, comprese le immagini modifica lo stato del prodotto affinché appaia così const \[product, setproduct] = usestate({ name "", price "", description "", stock "", status "active", }); crea anche uno stato per contenere le tue immagini const \[images, setimages] = usestate\<file\[]>(\[]); ora, scrivi una funzione per gestire l'aggiunta delle immagini al database questa funzione dovrebbe apparire così const handleimageupload = async (event) => { event preventdefault(); try { let name = "image jpg"; const file = new parse file(name, event target files\[0]); const photo = await file save(); setimages((prev) => \[ prev, photo]); console log("file saved ", file); alert(`image uploaded successfully`); } catch (error) { console error("error saving file ", error); } }; collega questa funzione all'input responsabile per il caricamento dei file utilizzando l' onchange evento successivamente, definisci la funzione handlesubmit questa funzione chiama il addproduct codice cloud passando le informazioni necessarie così const handlesubmit = async (e react formevent) => { e preventdefault(); try { interface addproductparams { name string; description string; price number; quantityavailable number; isactive boolean; } interface addproductresponse { id string; } parse cloud run\<addproductresponse, addproductparams>("addproduct", { name product name, description product description, price product price, quantityavailable product stock, isactive product status === "active", imagefiles images, }) then((response) => { console log("product created ", response id); }); } catch (error) { console error("error creating product ", error); } }; questa chiamata invia i dati del prodotto—comprese le immagini—al backend per creare un nuovo annuncio recupera tutti i prodotti questa chiamata recupera l'intero catalogo per le liste di prodotti pubblici o un feed della home page per creare la funzione che chiama la fetchallproducts funzione cloud, naviga nella app/products directory nella page tsx file, aggiungi questo codice interface product { id string; name string; description string; price number; image? string; } const \[products, setproducts] = usestate\<product\[]>(\[]); async function getallproducts() { try { const response = await parse cloud run("fetchallproducts"); console log("products fetched ", response); return response; } catch (error) { console error("error fetching products ", error); throw error; } } questo blocco di codice sopra definisce un'interfaccia per i prodotti e uno stato di products la getallproducts funzione chiama la funzione cloud fetchallproducts per ottenere tutti i prodotti nel database nota che devi chiamare la getallproducts funzione sopra all'interno di un useeffect() hook per recuperare e visualizzare i prodotti al caricamento della pagina così useeffect(() => { getallproducts() then((products) => { setproducts(products); }) catch((error) => { console error("error fetching products ", error); }); }, \[]); ottieni un singolo prodotto questa chiamata recupera i dettagli completi su un prodotto specifico naviga nella \[id] cartella nella tua app/products directory questa cartella contiene il page tsx file che conterrà la logica per recuperare i dettagli di un singolo prodotto nel page tsx file, scrivi questo codice interface product { id string; name string; description string; price number; images? string\[]; quantityavailable number; } const \[product, setproduct] = usestate\<product>({ id "", name "", description "", price 0, images \[], quantityavailable 0, }); async function getsingleproduct() { try { const response = await parse cloud run("getsingleproduct", {productid params id}); console log("product fetched ", response); return response; } catch (error) { console error("error fetching products ", error); throw error; } } useeffect(() => { getsingleproduct() then((product) => { setproduct(product); }) catch((error) => { console error("error fetching products ", error); }); }, \[]); questo blocco di codice definisce l'interfaccia per l'oggetto prodotto, imposta una variabile di stato product con valori predefiniti la getsingleproduct funzione chiama la tua getsingleproduct funzione di codice cloud utilizzando un productid dai parametri della rotta questo useeffect hook viene eseguito una sola volta quando il componente viene montato aggiorna un prodotto quando un venditore modifica un prodotto, chiama questa funzione con i campi aggiornati per aggiornare i prodotti, hai bisogno di un modulo con campi di input che raccolgono i nuovi dati, puoi trovare questo modulo nel page tsx file situato nella app/seller/products/\[id]/edit directory prima di aggiornare un prodotto, devi recuperare il prodotto e per farlo aggiungi questo codice al tuo page tsx file const \[product, setproduct] = usestate({ id "", name "", price "", description "", stock "", images \["", "", ""], status "active", }); useeffect(() => { async function fetchproduct() { try { const response = await parse cloud run("getsingleproduct", { productid params id, }); setproduct({ id response objectid, name response name || "", price string(response price ?? "0"), description response description || "", stock string(response quantityavailable ?? "0"), // fallback to placeholders if actual image data is not provided images \[ response image1 || `/placeholder svg?height=500\&width=500\&text=product`, response image2 || `/placeholder svg?height=500\&width=500\&text=productview+2`, response image3 || `/placeholder svg?height=500\&width=500\&text=productview+3`, ], status response isactive ? "active" "out of stock", }); } catch (error) { console error("error fetching product ", error); } } fetchproduct(); }, \[]); questo codice recupera i dettagli di un singolo prodotto dal tuo backend di back4app con la getsingleproduct funzione di codice cloud e memorizza i dettagli nello stato del componente product per visualizzarli come valore predefinito nel tuo modulo prima di modificarlo dopo aver recuperato i dettagli del prodotto, puoi modificare i dettagli utilizzando il modulo dopo aver compilato il modulo, l'invio del modulo chiamerà una handlesubmit funzione che conterrà la logica per aggiornare il tuo prodotto la tua handlesubmit funzione dovrebbe apparire così const handlesubmit = async (e react formevent) => { e preventdefault(); try { await parse cloud run("updateproduct", { productid product id, name product name, description product description, price parsefloat(product price), quantityavailable parseint(product stock, 10), isactive product status === "active", }); } catch (error) { console error("error updating product ", error); } }; questa funzione chiama la tua updateproduct funzione cloud code e invia un oggetto con i dati aggiornati del prodotto elimina un prodotto usa questa funzione per eliminare un prodotto dopo la conferma da parte del venditore per eliminare un prodotto, devi aggiungere una handledelete funzione che contiene la logica necessaria per eliminare il prodotto definirai la handledelete funzione nel page tsx file nella app/seller/products/\[id]/edit directory const handledelete = async () => { const confirmdelete = confirm( "are you sure you want to delete this product? this action cannot be undone " ); if (!confirmdelete) return; try { await parse cloud run("deleteproduct", { productid product id, }); } catch (error) { console error("error deleting product ", error); } }; la handledelete funzione prima conferma l'intento dell'utente prima di chiamare la deleteproduct funzione cloud code definita nel tuo backend collega la handledelete funzione al pulsante di eliminazione nella parte jsx del componente ad esempio \<button type="button" variant="destructive" onclick={handledelete} \> \<trash2 classname="h 4 w 4 mr 2" /> delete product \</button> ottieni i prodotti del venditore usa questo per recuperare tutti i prodotti di proprietà del venditore attualmente connesso definirai la funzione per gestire il recupero dei prodotti del venditore nel page tsx file nella app/seller/dashboard directory nel file, scrivi questo codice const \[products, setproducts] = usestate< { objectid string; name string; price number; quantityavailable number; sales number; isactive boolean; }\[] \>(\[]); useeffect(() => { async function fetchproducts() { try { const result = await parse cloud run("getsellerproducts"); setproducts(result); } catch (error) { console error("error fetching products ", error); } }; fetchproducts(); }, \[]); questo blocco di codice definisce lo stato products e utilizza il useeffect hook per chiamare la funzione fetchproducts una volta al caricamento la fetchproducts funzione chiama la funzione di codice cloud getsellerproducts e aggiorna lo stato products con il risultato della chiamata gestione del carrello queste chiamate consentono agli acquirenti di gestire il proprio carrello della spesa prima di effettuare un ordine aggiungi al carrello questa chiamata aggiunge un prodotto selezionato al carrello dell'utente o ne incrementa la quantità trova il file page tsx nella directory app/products e aggiungi le seguenti righe di codice async function handleaddtocart(productid string, quantity number = 1) { try { const response = await parse cloud run("addtocart", { productid, quantity, }); console log("add to cart success ", response); } catch (error) { console error("failed to add to cart ", error); } } la funzione handleaddtocart accetta productid e una quantità opzionale come argomenti e chiama il addtocart codice cloud sul tuo backend questa funzione dovrebbe essere eseguita quando i tuoi utenti cliccano sul pulsante "aggiungi al carrello" nella scheda del prodotto ad esempio \<button classname="w full" size="sm" onclick={() => handleaddtocart(product id)}> \<shoppingcart classname="h 4 w 4 mr 2" /> add to cart \</button> visualizza carrello usa questo per recuperare i contenuti del carrello e visualizzare un riepilogo del carrello in tempo reale per fare ciò, naviga al page tsx file nella app/cart directory all'interno di questo file, aggiungi il blocco di codice qui sotto interface cartitem { id string; // product's objectid name string; price number; quantity number; image string; } const \[cartitems, setcartitems] = usestate\<cartitem\[]>(\[]); useeffect(() => { async function fetchcart() { try { const response = await parse cloud run("getcart"); const parsed = response items map((item) => ({ id item productid, name item name, price item price, quantity item quantity, image item image, })); setcartitems(parsed); } catch (error) { console error("failed to fetch cart ", error); } } fetchcart(); }, \[]); il blocco di codice sopra definisce la struttura dei dati del carrello nel frontend con l'interfaccia cartitem , definisce lo stato cartitems che contiene gli articoli del carrello utilizza anche useeffect per attivare la funzione fetchcart una volta al caricamento della pagina la fetchcart funzione chiama la funzione di codice cloud getcart e recupera il carrello dal tuo backend utilizza il metodo map per convertire il formato backend in formato frontend prima di salvare i dati del carrello elaborati nello stato cartitems aggiorna l'elemento del carrello questa chiamata cambia la quantità di un prodotto specifico nel carrello all'interno del page tsx file nella app/cart directory, troverai una updatequantity funzione sostituisci quella funzione con quella qui sotto const updatequantity = async (productid string, newquantity number) => { if (newquantity < 1) return; try { await parse cloud run("updatecart", { productid, newquantity, }); console log("updated the cart"); } catch (error) { console error("failed to update cart item ", error); } }; questa funzione prende due parametri, productid e la quantità aggiornata che l'utente desidera impostare newquantity chiama la tua updatecart funzione cloud e invia sia il productid che il newquantity come parametri colleghi questa funzione ai pulsanti +/ utilizzando l'evento onclick così \<div classname="flex items center gap 2"> \<button variant="outline" size="icon" classname="h 8 w 8" onclick={() => updatequantity(item id, item quantity 1)} \> \<minus classname="h 3 w 3" /> \<span classname="sr only">decrease quantity\</span> \</button> \<span classname="w 8 text center">{item quantity}\</span> \<button variant="outline" size="icon" classname="h 8 w 8" onclick={() => updatequantity(item id, item quantity + 1)} \> \<plus classname="h 3 w 3" /> \<span classname="sr only">increase quantity\</span> \</button> \</div> rimuovi dal carrello rimuove un articolo completamente dal carrello per fare ciò, aggiungi il blocco di codice qui sotto al page tsx file nella app/cart directory all'interno di questo file const removeitem = async (productid string) => { try { await parse cloud run("removefromcart", { productid, }); setcartitems((items) => items filter((item) => item id !== productid)); } catch (error) { console error("failed to remove item ", error); } }; questa funzione, removeitem , rimuove un prodotto specifico dal carrello dell'utente chiamando la funzione cloud removefromcart sul backend la funzione aggiorna anche lo stato del carrello locale nel frontend per riflettere la modifica collega questa funzione al pulsante "rimuovi articolo", in questo modo \<button variant="ghost" size="icon" classname="h 8 w 8 text muted foreground" onclick={() => removeitem(item id)} \> \<trash2 classname="h 4 w 4" /> \<span classname="sr only">remove item\</span> \</button> gestione degli ordini queste funzioni gestiscono la creazione e il tracciamento degli ordini per acquirenti e venditori crea un ordine questo crea un ordine dai contenuti attuali del carrello dell'utente devi anche definire questa funzione nel page tsx file nella app/cart directory la funzione che contiene la logica per creare l'ordine dovrebbe apparire così const handleorder = async () => { try { const user = parse user current(); if (!user) { throw new error("you must be logged in to place an order "); } const result = await parse cloud run("createorder"); console log("order created successfully ", result); } catch (error any) { console error("failed to create order ", error); } }; questa funzione, handleorder , gestisce il processo di checkout effettuando un ordine tramite il tuo backend di back4app controlla se un utente è connesso, quindi chiama la createorder funzione cloud per convertire il carrello dell'utente attuale in un ordine ufficiale per chiamare questo al checkout, collega la funzione al pulsante "checkout" utilizzando l' onclick evento ad esempio \<button classname="w full" onclick={handleorder}>proceed to checkout\</button> visualizza ordini del venditore i venditori possono utilizzare questa chiamata per visualizzare ordini che includono i loro prodotti definisci questa funzione nel page tsx file nella directory app/seller/dashboard aggiungi le seguenti righe di codice al file page tsx const \[ordersdata, setordersdata] = usestate<{ id string; total number; buyer string; date date; status string; }\[] \>(\[]); async function fetchsellerorders() { try { const orders = await parse cloud run("getsellerorders"); console log("seller orders ", orders); setordersdata(orders); } catch (err) { console error("error fetching seller orders ", err); } }; questo codice recupera un elenco di ordini che includono i prodotti del venditore e li memorizza nello stato locale ordersdata per la visualizzazione in un dashboard venditore o in una vista di gestione degli ordini assicurati di chiamare la funzione in un useeffect hook in modo che la funzione venga eseguita una sola volta al caricamento della pagina aggiorna un ordine questo alterna lo stato di un ordine tra "in attesa" e "completato" definisci questa funzione nel page tsx file nella directory app/seller/dashboard la funzione dovrebbe apparire così const handleupdate = async (id string) => { const confirmupdate = confirm( "are you sure you want to update this order?" ); if (!confirmupdate) return; try { await parse cloud run("completeorder", { orderid id, }); console log("updated order"); } catch (error) { console error("error updating order ", error); } }; questa funzione, handleupdate , aggiorna lo stato di un ordine esistente chiamando la funzione cloud chiamata completeorder nel tuo backend di back4app collega questa funzione a un pulsante "modifica" nella parte jsx del componente così \<button variant="ghost" size="icon" onclick={() => {handleupdate(order id)}}> \<pencil classname="h 4 w 4" /> \<span classname="sr only">view\</span> \</button> distribuzione del frontend su contenitori back4app i contenitori back4app offrono un modo semplificato per impacchettare e distribuire la tua applicazione frontend invece di gestire servizi di hosting separati, puoi memorizzare tutte le dipendenze all'interno di un'immagine docker, garantendo prestazioni costanti e semplificando la manutenzione questo approccio basato su contenitori è particolarmente utile per le applicazioni next js, dove puoi ottimizzare le build per velocità e affidabilità per containerizzare la tua applicazione, crea un dockerfile per definire come la tua app viene costruita e servita di seguito è riportato un esempio di dockerfile per un'applicazione next js # stage 1 build the next js app from node 20 alpine as builder workdir /app copy package json package lock json / run npm install copy run npm run build \# stage 2 run the next js app from node 20 alpine workdir /app copy from=builder /app / expose 3000 cmd \["npm", "start"] dopo aver creato il tuo dockerfile, crea un dockerignore file e aggiungi questi comandi # node modules (reinstalled in docker) node modules \# next js build output next out \# logs npm debug log yarn debug log yarn error log pnpm debug log \# env files (optional — only if you handle secrets another way) env env local env development env production env test \# os / ide / editor junk ds store thumbs db vscode idea \# git git gitignore ora puoi costruire e testare la tua applicazione localmente per fare ciò, esegui il seguente comando nel tuo terminale docker build t ecommerce app docker run p 3000 3000 ecommerce app apri http //localhost 3000 per assicurarti che il tuo sito funzioni correttamente una volta verificato che tutto funziona come previsto in locale, è il momento di caricare il tuo codice su github e distribuirlo tramite back4app assicurati che il tuo codice sia stato impegnato e caricato in un repository github questo permetterà a back4app di accedere al tuo progetto per la distribuzione nel tuo account back4app, vai alla tua dashboard e fai clic sul dashboard menu a discesa nella parte superiore dello schermo dashboard menu dal menu a discesa, seleziona web deployment platform web deployment platform questo ti porterà alla pagina di distribuzione dell'applicazione web deploy web application page fai clic sul deploy a web app pulsante per avviare il processo di distribuzione link github repo poi, fai clic su import github repo e scegli il repository che contiene il tuo dockerfile assegna un nome al tuo progetto (ad esempio, ecommerce back4app) segui la configurazione guidata per costruire e distribuire la tua app una volta completato il deployment, back4app mostrerà una pagina di conferma come questa successful deployment l'area evidenziata nell'immagine sopra è l'url dove la tua applicazione è attiva puoi usarlo per visualizzare e testare la tua app direttamente in un browser web una volta distribuito, utilizza il dashboard di back4app per monitorare i log di build, tenere traccia della salute dei container e tornare a versioni precedenti se necessario il dashboard mostra aggiornamenti in tempo reale sullo stato dei container, rendendo più facile individuare errori e mantenere un ambiente stabile per i tuoi utenti con i container, ottieni una soluzione frontend flessibile e portatile che si integra perfettamente con il tuo backend di back4app, aprendo la strada a rilasci coerenti e senza problemi puoi visitare il sito web di e commerce costruito in questo tutorial qui https //ecommerceback4app mcphit37 b4a run/ conclusione congratulazioni—hai ora assemblato ogni strato di uno stack e commerce pronto per la produzione e collaudato impostazione del back end dalla creazione del tuo account back4app alla modellazione di utenti, prodotti e ordini sicurezza e api implementazione di un'autenticazione robusta e esposizione dei tuoi dati tramite endpoint rest e graphql logica aziendale e aggiornamenti in tempo reale automazione dei flussi di lavoro con cloud code e streaming di modifiche in tempo reale tramite livequery distribuzione del front end collegamento del javascript sdk e spedizione di un negozio next js nei container di back4app cosa c'è dopo? immergiti nella documentazione di back4app https //www back4app com/docs e nella guida della parse platform https //docs parseplatform org per riferimenti approfonditi, oppure unisciti al forum della comunità per raccogliere suggerimenti avanzati e app di esempio da parte di manutentori e colleghi sviluppatori questa base è solo l'inizio—espandila ulteriormente integrando webhook e lavori programmati, collegando gateway di pagamento o costruendo un'app mobile companion continua a iterare, rifattorizzare ed evolvere il tuo codice—e guarda il tuo negozio crescere insieme alle tue ambizioni