Quickstarters
How to Build an E-Commerce Backend?
77 นาที
ในบทเรียนเชิงปฏิบัตินี้ คุณจะสร้างแอปพลิเคชันอีคอมเมิร์ซแบบฟูลสแต็กที่มั่นคงจากพื้นฐานโดยใช้บริการแบ็คเอนด์เป็นบริการ ระหว่างทาง คุณจะเชี่ยวชาญ การตรวจสอบสิทธิ์ผู้ใช้ที่ปลอดภัย เพื่อให้แน่ใจว่ามีเพียงผู้ซื้อและผู้ดูแลระบบที่ได้รับอนุญาตเท่านั้นที่สามารถเข้าถึงได้ โมเดลข้อมูลที่ใช้งานง่าย ซึ่งออกแบบมาเพื่อสนับสนุนแคตตาล็อกผลิตภัณฑ์ โปรไฟล์ลูกค้า และประวัติการสั่งซื้อ api แบบ restful และเรียลไทม์ เพื่อให้ส่วนหน้าของคุณซิงค์กับสินค้าคงคลัง รถเข็น และสถานะการชำระเงินอยู่เสมอ ท่อการปรับใช้แบบอัตโนมัติ ช่วยให้คุณสามารถผลักดันการอัปเดตได้อย่างมั่นใจและย้อนกลับได้หากมีสิ่งใดผิดพลาด เมื่อสิ้นสุด คุณจะมีไม่เพียงแค่หน้าร้านที่พร้อมสำหรับการผลิต แต่ยังมีความรู้ด้านสถาปัตยกรรมในการขยาย ขยาย และรักษาความปลอดภัยแอปพลิเคชันเว็บใดๆ สำรวจแอปพลิเคชันอีคอมเมิร์ซที่เสร็จสมบูรณ์ในขณะทำงานที่ แอปอีคอมเมิร์ซเว็บ เริ่มกันเลย! ข้อคิดสำคัญ การตั้งค่าพื้นหลังอย่างรวดเร็ว เริ่มต้นและกำหนดค่ารูปแบบข้อมูลอีคอมเมิร์ซเต็มรูปแบบในไม่กี่นาทีด้วยแพลตฟอร์ม low code ของ back4app การไหลของผู้ใช้ที่ปลอดภัย ใช้ cloud code และโทเค็นเซสชันในการลงทะเบียน เข้าสู่ระบบ และออกจากระบบอย่างมีประสิทธิภาพ การพัฒนาแบบ api first เข้าถึงข้อมูลของคุณผ่าน rest/graphql endpoints ที่สร้างโดยอัตโนมัติและ parse sdk สำหรับลูกค้าใด ๆ ตรรกะธุรกิจใน cloud code รวมศูนย์การดำเนินงานหลัก—การจัดการผลิตภัณฑ์ crud, การจัดการรถเข็น และการชำระเงิน—ในขณะที่บังคับใช้สิทธิ์ การปรับใช้ frontend แบบ containerized แพ็คเกจและปรับใช้ร้านค้า next js ของคุณใน back4app web deployment เพื่อการโฮสต์ที่สอดคล้องและปรับขนาดได้ ข้อกำหนดเบื้องต้นและการตั้งค่าสภาพแวดล้อม ในการติดตามบทแนะนำนี้ ให้แน่ใจว่าคุณมีสิ่งต่อไปนี้ บัญชี back4app คุณสามารถลงทะเบียนได้ฟรีที่ เว็บไซต์ back4app https //www back4app com/signup ติดตั้ง node js ซึ่งช่วยให้คุณจัดการการพึ่งพาได้ด้วย npm หรือ yarn ความคุ้นเคยกับ javascript สำหรับการเขียนโค้ดคลาวด์ที่กำหนดเองและการใช้ sdk ของ back4app ความเข้าใจพื้นฐานเกี่ยวกับแนวคิดอีคอมเมิร์ซ เช่น การตรวจสอบสิทธิ์ผู้ใช้ การจัดการแคตตาล็อกผลิตภัณฑ์ และการประมวลผลคำสั่งซื้อ git สำหรับการควบคุมเวอร์ชัน เพื่อให้คุณสามารถติดตามการเปลี่ยนแปลง ย้อนกลับหากจำเป็น และทำงานร่วมกันได้อย่างราบรื่น การมีรายการข้างต้นจะช่วยให้คุณใช้ความสามารถของ back4app ได้สูงสุดและนำฟีเจอร์อีคอมเมิร์ซที่สำคัญมาใช้โดยไม่รู้สึกหนักใจ การสร้างและกำหนดค่าบัญชี back4app ของคุณ เริ่มต้นการตั้งค่าแบ็กเอนด์อีคอมเมิร์ซของคุณบน back4app โดยไปที่ back4app https //www back4app com และคลิก ลงทะเบียน กรอกที่อยู่อีเมลของคุณ เลือกพาสเวิร์ดที่แข็งแกร่ง และให้รายละเอียดที่จำเป็น เมื่อคุณยืนยันอีเมลของคุณ คุณจะสามารถเข้าถึงแดชบอร์ดของ back4app ได้ หน้าเว็บลงทะเบียน back4app ภายในแดชบอร์ด ให้เลือก สร้างแอปใหม่ หรือ สร้างแอปใหม่ และตั้งชื่อโปรเจกต์ของคุณ—ชื่อที่มีความหมายเพื่อให้คุณสามารถค้นหาได้ง่ายในภายหลัง ยืนยันตัวเลือกของคุณ จากนั้นรอให้กระบวนการสร้างแอปเสร็จสิ้น แดชบอร์ดโปรเจกต์จะแสดงคลาส การวิเคราะห์ และการตั้งค่า。 การสร้างแอป back4app ด้วยขั้นตอนเหล่านี้ คุณได้สร้างแพลตฟอร์มอีคอมเมิร์ซ ในส่วนถัดไป คุณจะออกแบบสคีมาข้อมูลของคุณและเตรียมพร้อมสำหรับการจัดการผลิตภัณฑ์ การจัดการคำสั่งซื้อ และการตรวจสอบผู้ใช้ การออกแบบสคีมาข้อมูลอีคอมเมิร์ซของคุณ เพื่อดำเนินการสร้างแบ็กเอนด์ที่สามารถขยายได้และดูแลรักษาได้สำหรับแพลตฟอร์มอีคอมเมิร์ซของคุณ คุณจะจัดระเบียบข้อมูลของคุณรอบเจ็ดตารางหลัก ผู้ใช้ , ผู้ซื้อ , ผู้ขาย , ผลิตภัณฑ์ , ตะกร้า , คำสั่งซื้อ , และ รายละเอียดคำสั่งซื้อ แต่ละตารางมีบทบาทที่มุ่งเน้นในการสนับสนุนฟังก์ชันการทำงานโดยรวมของระบบ และร่วมกันพวกเขาจะสร้างสคีมาที่เป็นมาตรฐานและมีประสิทธิภาพ เริ่มต้นด้วย user ตาราง ซึ่งทำหน้าที่เป็นพื้นฐานสำหรับอัตลักษณ์ของผู้ใช้ทั้งหมด ทุกคนในแพลตฟอร์มของคุณ—ไม่ว่าจะมีบทบาทใด—จะต้องยืนยันตัวตนโดยใช้ตารางนี้ รวมฟิลด์เช่น username , password , และ email เพื่อจัดการการเข้าสู่ระบบพื้นฐาน เพิ่ม emailverified เพื่อติดตามสถานะการตรวจสอบ และ authdata หากคุณวางแผนที่จะสนับสนุนการเข้าสู่ระบบของบุคคลที่สามหรือ oauth flows เพื่อแยกความแตกต่างระหว่างผู้ซื้อและผู้ขาย ให้กำหนดฟิลด์ usertype ฟิลด์นี้ช่วยให้คุณควบคุมการเข้าถึง จัดการมุมมอง และแยกฟังก์ชันตามบทบาทของผู้ใช้ในขณะที่ยังคงรักษาระบบการเข้าสู่ระบบที่สอดคล้องกัน แทนที่จะผสมผสานประเภทผู้ใช้ทั้งหมดในตารางเดียว ให้สร้าง buyer และ seller ตารางแยกต่างหากที่อ้างอิงถึง user ผ่านฟิลด์ userid ซึ่งช่วยให้คุณเก็บข้อมูลเฉพาะบทบาทโดยไม่ทำให้ตารางผู้ใช้หลักมีขนาดใหญ่เกินไป ตาราง buyer สามารถเก็บฟิลด์ที่เกี่ยวข้องกับการซื้อ เช่น paymentinfo และ shippingaddress , ซึ่งเป็นสิ่งจำเป็นสำหรับกระบวนการชำระเงินและการจัดส่ง ในทางตรงกันข้าม ตาราง seller จะติดตามคุณลักษณะที่เกี่ยวข้องกับผู้ค้า เช่น storename , bio , และ phonenumber ด้วยการแยกนี้ คุณสามารถจัดการและค้นหาผู้ซื้อและผู้ขายได้อย่างอิสระ ในขณะที่ยังคงเชื่อมโยงพวกเขากลับไปยังอัตลักษณ์ที่ใช้ร่วมกันใน user ตาราง product ของคุณคือที่ที่เก็บรายการสินค้าที่จะขาย สินค้าแต่ละชิ้นควรมีข้อมูลพื้นฐานที่อธิบาย เช่น ชื่อ รายละเอียดที่ละเอียด และรูปภาพหนึ่งหรือมากกว่า สำหรับการจัดการราคาและสินค้าคงคลัง คุณจะต้องรวมฟิลด์สำหรับราคา สถานะการมีอยู่ผ่าน isactive , และจำนวนสต็อกภายใต้ quantityavailable สำคัญมาก สินค้าแต่ละชิ้นต้องเชื่อมโยงกับผู้ขายที่ลงรายการไว้ เพื่อสร้างความสัมพันธ์นั้น ให้เพิ่ม sellerid เป็นคีย์ต่างประเทศที่อ้างอิงถึง seller ตาราง โครงสร้างนี้ช่วยให้แน่ใจว่าทุกชิ้นในแคตตาล็อกของคุณเชื่อมโยงกับผู้ค้า ที่ได้รับการตรวจสอบ และทำให้การกรองเฉพาะผู้ขายเป็นเรื่องง่าย เพื่อจัดการพฤติกรรมก่อนการซื้อ ให้แนะนำ cart ตาราง แต่ละตะกร้าจะเป็นของผู้ใช้ ดังนั้นให้รวมฟิลด์ userid ที่เชื่อมกลับไปยัง user เก็บอาร์เรย์ของ items ในตะกร้า โดยแต่ละรายการแสดงถึงสินค้าที่ผู้ใช้ตั้งใจจะซื้อ พร้อมกับข้อมูลเมตาที่คุณต้องการ เช่น จำนวนหรือทางเลือกที่เลือก การติดตาม totalprice ของตะกร้าช่วยให้คุณแสดงสรุปการชำระเงินได้อย่างรวดเร็วโดยไม่ต้องคำนวณค่าใหม่ในทุกคำขอ การตั้งค่านี้สนับสนุนฟังก์ชันการทำงานพื้นฐานของตะกร้าและทำให้การเก็บรักษาช่วงเวลาเป็นเรื่องง่าย หากคุณพบว่าโครงสร้างอาร์เรย์มีข้อจำกัด โดยเฉพาะหากคุณต้องการบันทึกข้อมูลระดับรายการที่ซับซ้อนมากขึ้น คุณสามารถปรับโครงสร้างรายการเป็นตารางแยกต่างหากในภายหลัง เมื่อผู้ซื้อทำการสั่งซื้อ คุณจะบันทึกการทำธุรกรรมใน order ตาราง แต่ละคำสั่งซื้อจะเชื่อมโยงกับ buyerid , อ้างอิงถึง buyer ตารางเพื่อให้แน่ใจว่าผู้ซื้อมีความถูกต้องและได้รับอนุญาต นอกจากลิงก์นี้แล้ว ให้เก็บ orderdate , สถานะ orderstatus , และมูลค่าทางการเงินรวมภายใต้ total ฟิลด์ นี่จะให้สรุปที่ชัดเจนเกี่ยวกับการซื้อและสนับสนุนการทำงานเช่นการติดตามคำสั่งซื้อและการจัดส่ง เนื่องจากแต่ละคำสั่งซื้ออาจมีสินค้าหลายรายการ คุณจะต้องมี orderdetails ตารางเพื่อจัดการรายการแต่ละรายการ ตารางนี้เชื่อมโยงแต่ละรายการกลับไปยังคำสั่งซื้อหลักผ่าน orderid , และไปยังสินค้าที่ซื้อโดยใช้ productid เพื่อบันทึกสถานะของการซื้ออย่างถูกต้อง ให้รวมถึง จำนวน ที่ซื้อและ ราคาต่อหน่วย ในขณะขาย การแยกรายละเอียดคำสั่งในลักษณะนี้ช่วยให้คุณสร้างรายงาน สร้างใบแจ้งหนี้ และจัดการการคืนสินค้าหรือการปรับเปลี่ยนได้อย่างแม่นยำ สคีมานี้ โดยมีการแยกความกังวลและความสมบูรณ์ของความสัมพันธ์อย่างชัดเจน เป็นพื้นฐานที่แข็งแกร่งสำหรับระบบอีคอมเมิร์ซของคุณ เมื่อโมเดลข้อมูลตอนนี้สอดคล้องกับการทำงานในโลกจริงของแพลตฟอร์มของคุณ คุณก็พร้อมที่จะเริ่มนำไปใช้ในแบ็กเอนด์ของคุณ เริ่มต้นด้วยการตั้งค่าตาราง ผู้ใช้ , ผู้ซื้อ , และ ผู้ขาย และสร้างจากที่นั่น การตั้งค่าชั้นเรียนในแดชบอร์ด ทำตามขั้นตอนด้านล่างเพื่อสร้างและเชื่อมโยงเอนทิตีของคุณใน back4app คุณจะกำหนดชั้นเรียนสำหรับ ผู้ใช้ , ผู้ซื้อ , ผู้ขาย , ตะกร้า , ผลิตภัณฑ์ , คำสั่ง , และ รายละเอียดคำสั่ง , จากนั้นสร้างพอยเตอร์เพื่อแสดงความสัมพันธ์เช่นการสืบทอด หนึ่งต่อหลาย และหลายต่อหลาย เข้าถึงเบราว์เซอร์ฐานข้อมูล เปิดแดชบอร์ดของแอปพลิเคชันของคุณและสร้างชั้นเรียนใหม่ชื่อ ผู้ใช้ คลิกที่ ฐานข้อมูล จากเมนูด้านซ้าย back4app dashboard การสร้างชั้นเรียน “ผู้ใช้” back4app สร้างชั้นเรียน ผู้ใช้ โดยอัตโนมัติ ชั้นเรียน ผู้ใช้ มาพร้อมกับคอลัมน์ต่อไปนี้ ชื่อผู้ใช้ รหัสผ่าน อีเมล เป็นต้น เพื่อเพิ่มคอลัมน์ ประเภทผู้ใช้ ให้เลือก เพิ่มคอลัมน์ใหม่ add new column ระบุชื่อคอลัมน์ ประเภทข้อมูล ค่าเริ่มต้น ฯลฯ add usertype column หมายเหตุ ใน parse ทุกคลาสจะมี objectid เป็นค่าเริ่มต้น ซึ่งทำหน้าที่เป็นกุญแจหลัก นั่นหมายความว่า objectid จะทำหน้าที่เป็น userid ในโมเดลเชิงสัมพันธ์ของคุณ การสร้างคลาส “buyer” ในการสร้างคลาสผู้ซื้อ ให้กลับไปที่ database browser และเลือก add class create new class เลือก custom และตั้งชื่อเป็น buyer add buyer class เพิ่มคอลัมน์ pointer ชื่อ user , ชี้ไปที่คลาส user create userid class นี่จำลอง “การสืบทอด” โดยการอ้างอิงถึง objectid ของผู้ใช้พื้นฐาน 3\ เพิ่มคอลัมน์ต่อไปนี้ ที่อยู่การจัดส่ง (string) ข้อมูลการชำระเงิน (string) เมื่อคุณสร้างวัตถุผู้ซื้อใหม่ คุณจะเชื่อมโยงกับบันทึกผู้ใช้ที่มีอยู่โดยการตั้งค่า buyer user เป็น objectid ของผู้ใช้นั้น การสร้างคลาส “ผู้ขาย” ทำซ้ำกระบวนการเดียวกันเพื่อสร้างคลาส ผู้ขาย เพิ่มคอลัมน์ pointer ชื่อ user อ้างอิงถึงคลาส user เพิ่มคอลัมน์เพิ่มเติมเหล่านี้ ชื่อร้าน (string) ชีวประวัติ (string) หมายเลขโทรศัพท์ (number) การสร้างคลาส “ผลิตภัณฑ์” เลือก สร้างคลาส อีกครั้ง โดยตั้งชื่อว่า ผลิตภัณฑ์ เพิ่มคอลัมน์ ชี้ไปยัง ที่เรียกว่า ผู้ขาย ชี้ไปยังคลาส ผู้ขาย (สิ่งนี้บังคับให้มีความสัมพันธ์แบบหนึ่งต่อหลายซึ่งผู้ขายหนึ่งคนสามารถมีผลิตภัณฑ์ได้หลายรายการ) เพิ่มคอลัมน์ต่อไปนี้ ชื่อ (string) คำอธิบาย (string) ราคา (number) จำนวนที่มีอยู่ (number) ใช้งานอยู่ (boolean) ภาพ (array) เก็บวัตถุที่แสดงถึงภาพผลิตภัณฑ์ การสร้างคลาส “ตะกร้า” คลิก สร้างคลาส , ตั้งชื่อคลาสว่า ตะกร้า เพิ่มคอลัมน์ชี้ไปยังที่เรียกว่า ผู้ใช้ ชี้ไปยังคลาส ผู้ใช้ (สิ่งนี้เชื่อมโยงแต่ละตะกร้ากับผู้ใช้เฉพาะ) จากนั้นเพิ่มคอลัมน์ต่อไปนี้เพื่อแสดงรายการในตะกร้า รายการ (array) เก็บวัตถุที่แสดงถึงแต่ละรายการในตะกร้า แต่ละรายการสามารถเป็นวัตถุเช่น { ผลิตภัณฑ์ ชี้ไปยังผลิตภัณฑ์, จำนวน หมายเลข } ราคาทั้งหมด (number) การสร้างคลาส “คำสั่งซื้อ” สร้างคลาสใหม่ชื่อ order เพิ่มคอลัมน์ pointer ที่เรียกว่า buyer ที่ชี้ไปยังคลาส buyer (แสดงว่าผู้ซื้อหนึ่งคนสามารถมีคำสั่งซื้อได้หลายรายการ) รวมถึงคอลัมน์เหล่านี้ orderdate (วันที่หรือสตริง ขึ้นอยู่กับความชอบของคุณ) orderstatus (สตริง) การสร้างคลาส “orderdetails” สุดท้าย สร้างคลาสชื่อ orderdetails เพิ่มคอลัมน์ pointer สองคอลัมน์ order → อ้างอิง order product → อ้างอิง product จากนั้น เพิ่มคอลัมน์ที่เหลือ quantity (จำนวน) unitprice (จำนวน) การตั้งค่านี้ช่วยให้มีความสัมพันธ์แบบหลายต่อหลายระหว่าง order และ product ผ่าน orderdetails , เนื่องจากแต่ละคำสั่งซื้อสามารถรวมผลิตภัณฑ์หลายรายการ และแต่ละผลิตภัณฑ์สามารถปรากฏในคำสั่งซื้อหลายรายการ การมองเห็นความสัมพันธ์ นี่คือแผนภาพความสัมพันธ์ของเอนทิตีที่เรียบง่าย (erd) ที่สะท้อนถึงคลาสและพอยเตอร์ของพวกเขา dbschema2 เมื่อคลาสเหล่านี้ถูกตั้งค่าแล้ว คุณสามารถจัดการการลงทะเบียนและการเข้าสู่ระบบผ่านคลาส user สร้างบันทึกผู้ซื้อหรือผู้ขายเฉพาะสำหรับประเภทผู้ใช้ที่แตกต่างกัน และจัดเก็บข้อมูลผลิตภัณฑ์หรือคำสั่งซื้อพร้อมการอ้างอิงคีย์ต่างประเทศที่ชัดเจน โดยการจัดโครงสร้างฐานข้อมูลของคุณในลักษณะนี้ คุณจะได้การออกแบบที่สะอาดและบำรุงรักษาง่ายสำหรับแอปพลิเคชันอีคอมเมิร์ซใดๆ เมื่อคุณมีสคีมาที่พร้อมแล้ว คุณก็พร้อมที่จะตั้งค่าการตรวจสอบสิทธิ์และการอนุญาตเพื่อจำกัดว่าใครสามารถแสดงรายการสินค้า สั่งซื้อ หรือดำเนินการงานด้านการบริหาร ขั้นตอนถัดไปจะแสดงให้คุณเห็นว่าคุณจะกำหนดค่าการลงทะเบียนและการเข้าสู่ระบบที่ปลอดภัยอย่างไร ซึ่งสร้างขึ้นจากบทบาทและคลาสที่คุณเพิ่งกำหนด การดำเนินการตรวจสอบสิทธิ์ด้วย back4app การตรวจสอบสิทธิ์ที่ปลอดภัยเป็นสิ่งสำคัญสำหรับแพลตฟอร์มอีคอมเมิร์ซใดๆ ช่วยให้คุณปกป้องบัญชีผู้ใช้ รายละเอียดการชำระเงิน และข้อมูลส่วนบุคคล back4app ทำให้สิ่งนี้ง่ายขึ้นด้วยหลายวิธี ตั้งแต่การใช้ชื่อผู้ใช้/รหัสผ่านแบบคลาสสิกไปจนถึงการเข้าสู่ระบบผ่านโซเชียลหรือการไหลแบบใช้โทเค็น ซึ่งทำให้คุณสามารถมอบประสบการณ์ที่ตรงไปตรงมาและปลอดภัยให้กับผู้ซื้อของคุณ ในการตั้งค่าการตรวจสอบสิทธิ์ในแอปพลิเคชันอีคอมเมิร์ซของคุณ คุณจะใช้โค้ดคลาวด์ โค้ดคลาวด์ขยายความสามารถของแบ็กเอนด์ของคุณโดยให้คุณเขียนตรรกะทางธุรกิจที่กำหนดเองโดยไม่ต้องโฮสต์เซิร์ฟเวอร์ของคุณเอง นี่หมายความว่าคุณสามารถตรวจสอบคำสั่งซื้อ คำนวณค่าธรรมเนียม หรือกระตุ้นการแจ้งเตือนในเหตุการณ์เฉพาะ—ทั้งหมดภายในโครงสร้างพื้นฐานของ back4app นี่เป็นวิธีที่เหมาะสมในการจัดการธุรกรรมที่ละเอียดอ่อนหรือกระบวนการข้อมูลที่ต้องการการควบคุมที่เข้มงวดและการดำเนินการที่รวดเร็ว เพื่อเปิดใช้งานโค้ดคลาวด์บน back4app ให้เปิดแดชบอร์ดของแอปของคุณและค้นหาส่วน cloud code find cloud code เมื่อคุณคลิก cloud code , คุณจะเห็น main js ซึ่งคุณสามารถเริ่มต้นการดำเนินการฟังก์ชันที่กำหนดเองได้ cloud code ในการดำเนินการไหลของการตรวจสอบสิทธิ์ใน back4app คุณจะต้องปรับใช้ฟังก์ชันบางอย่างในโค้ดคลาวด์ของคุณเพื่อสมัครสมาชิกผู้ใช้ เข้าสู่ระบบผู้ใช้ และออกจากระบบผู้ใช้ ลงทะเบียนผู้ใช้ใหม่ (ผู้ซื้อโดยค่าเริ่มต้น) ในการลงทะเบียนผู้ใช้ใหม่ ให้ใช้วิธีการสมัครสมาชิกของ parse ตั้งค่าฟิลด์มาตรฐานเช่น username , password , และ email , และรวมฟิลด์ที่กำหนดเองเพื่อระบุบทบาท คือ buyer หรือ seller ตามค่าเริ่มต้น ผู้ใช้ใหม่จะถูกกำหนดบทบาทเป็น buyer จนกว่าพวกเขาจะเลือกเปลี่ยนมัน เพื่อเริ่มต้น สร้างไฟล์ auth js ในไดเรกทอรีคลาวด์ของโค้ดคลาวด์ของคุณและเพิ่มบล็อกโค้ดด้านล่าง 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); } }); ฟังก์ชัน cloud นี้จัดการการลงทะเบียนผู้ใช้สำหรับผู้ซื้อ มันตรวจสอบข้อมูลที่ป้อน สร้างผู้ใช้ parse ใหม่ มอบหมายบทบาท ( buyer ) และเก็บข้อมูลเฉพาะของผู้ซื้อในคลาส buyer แยกต่างหาก เข้าสู่ระบบผู้ใช้ เพื่อยืนยันตัวตนผู้ใช้ ให้เรียกใช้ parse user login ที่มีอยู่ใน parse และส่งคืนโทเค็นเซสชันไปยังไคลเอนต์ เพิ่มโค้ดต่อไปนี้ลงใน auth js ของคุณเพื่อดำเนินการตามตรรกะนี้ในแบ็กเอนด์ของโค้ดคลาวด์ของคุณ 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"); } }); ฟังก์ชันนี้รับอีเมลและรหัสผ่านจากไคลเอนต์ พยายามยืนยันตัวตนผู้ใช้ และส่งคืนโทเค็นเซสชันหากสำเร็จ หากบัญชีถูกตั้งค่าว่าเป็นผู้ใช้ที่ถูกปิดใช้งาน จะบล็อกการเข้าถึงและโยนข้อผิดพลาดที่ชัดเจน ออกจากระบบ ในการดำเนินการฟังก์ชันออกจากระบบสำหรับแบ็กเอนด์ของคุณ ให้เพิ่มบล็อกโค้ดด้านล่างนี้ไปยัง auth js ไฟล์ 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' }; }); นี่จะสิ้นสุดเซสชันอย่างปลอดภัยในแบ็กเอนด์ ป้องกันการใช้โทเค็นต่อไป ด้วยฟังก์ชัน cloud code เหล่านี้ คุณจะมีระบบการตรวจสอบสิทธิ์ที่ปลอดภัยซึ่ง ลงทะเบียนผู้ใช้ด้วยตรรกะตามบทบาท ตรวจสอบและอนุญาตการเข้าถึงโดยใช้โทเค็นเซสชัน เชื่อมโยงบัญชีผู้ใช้กับบันทึกเฉพาะของผู้ซื้อ สนับสนุนการเข้าสู่ระบบและออกจากระบบอย่างสะอาด ใช้เครื่องมือการตรวจสอบเซสชันและอีเมลที่มีอยู่ใน back4app การสร้างตรรกะทางธุรกิจสำหรับแอปอีคอมเมิร์ซของคุณ ในการจัดการผู้ใช้ ผลิตภัณฑ์ รถเข็น และธุรกรรมในแพลตฟอร์มอีคอมเมิร์ซของคุณ คุณจะต้องกำหนดชุดฟังก์ชัน cloud code ใน back4app ฟังก์ชันเหล่านี้ช่วยให้คุณสร้าง อ่าน อัปเดต และลบ (crud) ทรัพยากร เช่น ผู้ขาย ผลิตภัณฑ์ และคำสั่ง ในขณะที่รักษาการควบคุมการเข้าถึงที่ปลอดภัยซึ่งเชื่อมโยงกับบทบาทของผู้ใช้ ด้านล่างนี้คือชุดฟังก์ชัน cloud ที่แสดงวิธีการทำงานกับเอนทิตีหลัก ผู้ขาย , ผลิตภัณฑ์ , รถเข็น , คำสั่ง , และ รายละเอียดคำสั่ง แต่ละฟังก์ชันจัดการการดำเนินการแบ็กเอนด์เฉพาะและรับประกันว่าการอนุญาตจะถูกบังคับใช้ผ่านการตรวจสอบผู้ใช้และการตรวจสอบบทบาท ผู้ขาย สร้างโปรไฟล์ผู้ขายสำหรับผู้ใช้ที่ต้องการเสนอผลิตภัณฑ์บนแพลตฟอร์ม การสร้างผู้ขาย ฟังก์ชันนี้จะอัปเดตบทบาทของผู้ใช้ปัจจุบันเป็นผู้ขายและสร้าง ผู้ขาย บันทึกพร้อมข้อมูลร้านค้า ในการดำเนินการนี้ในโค้ดคลาวด์ของคุณ ให้สร้าง seller js ไฟล์และเพิ่มบล็อกโค้ดด้านล่างลงไป 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); } }); สิ่งนี้ทำให้มั่นใจได้ว่าผู้ใช้ที่ได้รับการตรวจสอบแล้วเท่านั้นที่สามารถเป็นผู้ขายได้ และเชื่อมโยง ผู้ขาย บันทึกกับผู้ใช้ที่เกี่ยวข้องผ่านพอยเตอร์ ผลิตภัณฑ์ ผลิตภัณฑ์ถูกจัดทำโดยผู้ขายและสามารถเรียกดู สอบถาม และซื้อโดยผู้ซื้อ ฟังก์ชันเหล่านี้ช่วยให้ผู้ขายสร้าง ดึงข้อมูล อัปเดต และลบผลิตภัณฑ์ของตน และยังให้การเข้าถึงผลิตภัณฑ์แก่ผู้ซื้อ การสร้างผลิตภัณฑ์ ฟังก์ชันนี้เพิ่มผลิตภัณฑ์ใหม่สำหรับผู้ขายที่ล็อกอินและแนบภาพผลิตภัณฑ์ได้สูงสุดสามภาพ เพื่อใช้งานในโค้ดคลาวด์ของคุณให้สร้างไฟล์ product js และเพิ่มบล็อกโค้ดด้านล่างนี้ลงไป 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}`); } }); ฟังก์ชันนี้ตรวจสอบว่าผู้ใช้ได้เข้าสู่ระบบและมีบทบาทเป็นผู้ขาย ว่ามีวัตถุ seller ที่เกี่ยวข้องอยู่ และไม่มีการส่งภาพมากกว่าสามภาพ เมื่อได้รับการตรวจสอบแล้ว จะเก็บผลิตภัณฑ์และเชื่อมโยงกับผู้ขาย การค้นหาผลิตภัณฑ์ทั้งหมด ฟังก์ชันนี้ดึงข้อมูลผลิตภัณฑ์ทั้งหมดในระบบ ซึ่งสามารถใช้สำหรับการสร้างหน้าร้านสาธารณะ เพื่อดำเนินการนี้ในโค้ดคลาวด์ของคุณ ให้เพิ่มบล็อกโค้ดด้านล่างลงในไฟล์ของคุณ products js 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}`); } }); ฟังก์ชันนี้ดึงข้อมูลผลิตภัณฑ์ด้วยธง usemasterkey และจัดรูปแบบสำหรับการใช้งานในส่วนหน้า การค้นหาผลิตภัณฑ์เดียว ใช้ฟังก์ชันนี้เมื่อแสดงข้อมูลผลิตภัณฑ์ที่ละเอียดให้กับผู้ซื้อ เพื่อดำเนินการนี้ในโค้ดคลาวด์ของคุณ ให้เพิ่มบล็อกโค้ดด้านล่างไปยัง products js ไฟล์ 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}`); } }); ฟังก์ชันนี้ส่งคืนรายละเอียดผลิตภัณฑ์ทั้งหมดสำหรับรายการเดียว มันตรวจสอบว่ามีการส่งผ่าน productid ที่ถูกต้องและตรวจสอบให้แน่ใจว่าผู้ขอข้อมูลได้เข้าสู่ระบบ การค้นหาผลิตภัณฑ์ของผู้ขาย ฟังก์ชันนี้ช่วยให้ผู้ขายสามารถดึงผลิตภัณฑ์ทั้งหมดของตนเองได้ เพื่อดำเนินการนี้ในโค้ดคลาวด์ของคุณ ให้เพิ่มบล็อกโค้ดด้านล่างลงใน products js ไฟล์ 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}`); } }); ฟังก์ชันนี้ยืนยันว่าผู้ใช้เป็นผู้ขาย ค้นหาบันทึก seller ที่เกี่ยวข้อง และสอบถามคลาส product โดยใช้พอยเตอร์ไปยังผู้ขาย ผู้ขายใช้สิ่งนี้เพื่อดึงผลิตภัณฑ์ทั้งหมดของตนเอง การลบผลิตภัณฑ์ ฟังก์ชันนี้รับประกันว่าผู้ขายที่สร้างผลิตภัณฑ์เท่านั้นที่สามารถลบมันได้ เพื่อดำเนินการนี้ในโค้ดคลาวด์ของคุณ ให้เพิ่มบล็อกโค้ดด้านล่างลงในไฟล์ของคุณ products js 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}`); } }); ฟังก์ชันนี้ยืนยันความเป็นเจ้าของของผู้ใช้และจากนั้นลบผลิตภัณฑ์ออกจากฐานข้อมูล การอัปเดตผลิตภัณฑ์ อนุญาตให้ผู้ขายแก้ไขรายละเอียดของผลิตภัณฑ์โดยใช้ฟังก์ชันนี้ เพื่อดำเนินการนี้ในโค้ดคลาวด์ของคุณ ให้เพิ่มบล็อกโค้ดด้านล่างลงใน products js ไฟล์ 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}`); } }); มันทำให้แน่ใจว่าผู้ใช้เป็นผู้ขาย ยืนยันความเป็นเจ้าของผลิตภัณฑ์ และอัปเดตเฉพาะฟิลด์ที่มีการระบุในคำขอเท่านั้น ตะกร้า ฟังก์ชัน ตะกร้า ช่วยให้ผู้ซื้อจัดการรายการที่พวกเขาตั้งใจจะซื้อ ฟังก์ชันเหล่านี้รวมถึงการเพิ่มลงในตะกร้า การอัปเดตจำนวน การดูเนื้อหา และการลบรายการ การเพิ่มลงในตะกร้า ฟังก์ชันนี้จะเพิ่มผลิตภัณฑ์ลงในรถเข็นของผู้ซื้อหรืออัปเดตจำนวนหากมีอยู่แล้ว เพื่อดำเนินการนี้ ให้สร้างไฟล์ cart js และเพิ่มโค้ดบล็อกด้านล่างนี้ลงไป 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}`); } }); มันตรวจสอบให้แน่ใจว่าผู้ใช้ได้รับการตรวจสอบสิทธิ์, ตรวจสอบความถูกต้องของผลิตภัณฑ์, อัปเดตรายการสินค้า, และคำนวณราคาโดยรวมของรถเข็นใหม่ การสอบถามตะกร้า ดึงเนื้อหาของตะกร้าของผู้ใช้ปัจจุบัน รวมถึงรายละเอียดผลิตภัณฑ์และยอดรวมย่อย เพื่อดำเนินการนี้ ให้เพิ่มบล็อกโค้ดด้านล่างลงใน cart js ไฟล์ 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, }; }); ฟังก์ชันนี้ใช้ include("items product") เพื่อดึงข้อมูลผลิตภัณฑ์ที่ซ้อนกันในคำขอเดียว การแก้ไขตะกร้า อัปเดตจำนวนของรายการในตะกร้าหรือเอาออกทั้งหมดหากจำนวนใหม่เป็นศูนย์ เพื่อดำเนินการนี้ ให้เพิ่มบล็อกโค้ดด้านล่างลงใน cart js ไฟล์ 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}`); } }); มันจะตรวจสอบราคาผลิตภัณฑ์ทั้งหมดอีกครั้งระหว่างการอัปเดตเพื่อให้แน่ใจว่ามีความถูกต้องทั้งหมด การลบจากตะกร้า ฟังก์ชันนี้ลบผลิตภัณฑ์ออกจากรถเข็นของผู้ใช้ เพื่อดำเนินการนี้ ให้เพิ่มบล็อกโค้ดด้านล่างลงใน cart js ไฟล์ 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}`); } }); มันกรองรายการจากอาร์เรย์รถเข็นและคำนวณยอดรวมใหม่ก่อนที่จะบันทึก คำสั่ง ฟังก์ชันเหล่านี้จัดการกระบวนการสั่งซื้อ—ตั้งแต่การสร้างคำสั่งซื้อไปจนถึงการดึงประวัติคำสั่งซื้อของผู้ขาย การสร้างคำสั่งซื้อ ฟังก์ชันนี้จะแปลงรถเข็นของผู้ซื้อให้เป็นคำสั่งซื้ออย่างเป็นทางการ เพื่อดำเนินการนี้ ให้สร้างไฟล์ order js และเพิ่มบล็อกโค้ดด้านล่างนี้ลงไป 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}`); } }); มันตรวจสอบผู้ซื้อ, ตรวจสอบความพร้อมของสินค้า, ลดสินค้าคงคลัง, ประหยัดทั้ง คำสั่งซื้อ และ รายละเอียดคำสั่งซื้อ , และเคลียร์ตะกร้าหลังจากการสั่งซื้อที่สำเร็จ การรับคำสั่งซื้อจากผู้ขาย ฟังก์ชันนี้ดึงคำสั่งซื้อทั้งหมดที่รวมถึงผลิตภัณฑ์ที่ขายโดยผู้ขายปัจจุบัน เพื่อดำเนินการนี้ ให้เพิ่มบล็อกโค้ดด้านล่างลงในไฟล์ของคุณ order js 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}`); } }); มันระบุผลิตภัณฑ์ที่เจ้าของขาย, สอบถาม orderdetails สำหรับผลิตภัณฑ์เหล่านั้น, ดึงคำสั่งที่เกี่ยวข้อง, และส่งคืนโครงสร้างที่เรียบง่ายรวมถึงข้อมูลผู้ซื้อ การอัปเดตสถานะคำสั่ง ฟังก์ชันนี้สลับสถานะของคำสั่งระหว่าง “รอดำเนินการ” และ “เสร็จสิ้น ” เพื่อดำเนินการนี้, เพิ่มบล็อกโค้ดด้านล่างไปยัง order js ไฟล์ 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}`); } }); มันรับประกันว่าเฉพาะผู้ขายเท่านั้นที่สามารถดำเนินการนี้และคำสั่งนั้นมีอยู่ก่อนที่จะอัปเดตสถานะ ฟังก์ชันแบ็คเอนด์เหล่านี้ให้แอปอีคอมเมิร์ซของคุณมีความสามารถในการจัดการการดำเนินการหลักทั้งหมดอย่างปลอดภัย—รายการผลิตภัณฑ์, รถเข็นผู้ซื้อ, คำสั่ง, และสินค้าคงคลังของผู้ขาย—โดยตรงภายใน back4app โดยใช้ cloud code เพื่อให้แน่ใจว่าคุณสามารถเข้าถึงฟังก์ชันคลาวด์เหล่านี้จากภายนอกได้ คุณต้องลงทะเบียนไฟล์โค้ดคลาวด์ทั้งหมดใน main js ไฟล์ คุณสามารถทำได้โดยการเพิ่มบล็อกโค้ดด้านล่างลงใน main js ไฟล์ //main js require(" /auth js") require(" /cart js") require(" /order js") require(" /product js") require(" /seller js") การสร้างส่วนหน้า ในการสร้างหน้าร้านอีคอมเมิร์ซของคุณอย่างมีวิสัยทัศน์ คุณจะใช้ v0 dev เพื่อทำเช่นนี้ เริ่มต้นโดยการเยี่ยมชม v0 dev http //v0 dev สร้างบัญชีหากคุณยังไม่มี เมื่อบัญชีของคุณตั้งค่าเสร็จแล้ว คุณสามารถเริ่มสร้างส่วนหน้าของคุณได้ ในการสร้างส่วนหน้าของคุณ ให้ป้อนคำสั่งด้านล่าง create an e commerce web application with authentication features and a buyer and seller feature คำสั่งจะสร้างแอปอีคอมเมิร์ซ next js พร้อมฟีเจอร์ที่ร้องขอ create ecommerce app โดยใช้ฟีเจอร์การดูตัวอย่าง คุณสามารถนำทางผ่านแอปพลิเคชันเพื่อตรวจสอบว่าทุกอย่างทำงานตามที่คาดหวัง หากมีความยุ่งยากบางอย่างหรือคุณต้องการเพิ่มฟีเจอร์เพิ่มเติม คุณสามารถส่งคำสั่งอีกครั้งและ v0 จะปรับเปลี่ยนแอปพลิเคชัน ตัวอย่างเช่น ส่งคำสั่ง the seller can create, add, delete and update products คำสั่งนี้จะปรับเปลี่ยนแอปพลิเคชัน สร้างหน้าใหม่ที่ผู้ขายสามารถทำการดำเนินการ crud ได้ modify ecommerce app สุดท้าย ส่งคำสั่ง 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) คำสั่งนี้จะทำการแก้ไขขั้นสุดท้ายให้กับแอปพลิเคชัน เพื่อดูตัวอย่างแอปพลิเคชันที่ปรับเปลี่ยนแล้ว ให้คลิกที่ ดู ปุ่มในส่วนที่เน้นในภาพด้านบน เมื่อคุณมั่นใจว่าแอปพลิเคชันคือสิ่งที่คุณต้องการ ขั้นตอนถัดไปคือการนำโปรเจกต์ไปยังอุปกรณ์ท้องถิ่นของคุณ เพื่อทำเช่นนี้ ให้คลิกที่ปุ่มดาวน์โหลดที่ v0 สร้างขึ้นพร้อมกับการตอบสนองที่กระตุ้น ปุ่มดาวน์โหลด การคลิกที่ปุ่มจะเปิดเมนูแบบเลื่อนลงพร้อมลิงก์และ ปุ่มดาวน์โหลด zip เมนูแบบเลื่อนลง ถัดไป คลิกที่ ปุ่มดาวน์โหลด zip เมื่อคุณดาวน์โหลด zip เสร็จแล้ว ให้เปิดเทอร์มินัลของคุณและสร้างโฟลเดอร์ใหม่ชื่อ ecommerce app ในไดเรกทอรีที่คุณต้องการ mkdir ecommerce app ตอนนี้ให้แตกไฟล์เนื้อหาจากโฟลเดอร์ zip ลงในโฟลเดอร์ ecommerce app ไปที่ไดเรกทอรี ecommerce app บนเทอร์มินัลของคุณและติดตั้งการพึ่งพาที่จำเป็น เพื่อทำเช่นนี้ ให้รันคำสั่งต่อไปนี้ cd ecommerce app npm install หลังจากติดตั้งการพึ่งพาแล้ว ให้รันคำสั่ง npm run dev บนเทอร์มินัลของคุณเพื่อดูโปรเจกต์บนเซิร์ฟเวอร์ localhost ของคุณ การรวม frontend ของคุณกับ backend ของคุณ เพื่อเชื่อมต่อ frontend ของคุณกับฟังก์ชัน cloud code ใน backend back4app ของคุณ คุณจะใช้ parse javascript sdk sdk ช่วยให้คุณสามารถตรวจสอบผู้ใช้ เรียกใช้ฟังก์ชันแบ็คเอนด์ และโต้ตอบกับโมเดลข้อมูลของแอปของคุณได้อย่างปลอดภัยและมีประสิทธิภาพ ในการตั้งค่า sdk ให้รันคำสั่งต่อไปนี้ในไดเรกทอรีของโปรเจกต์ของคุณในเทอร์มินัล npm install parse จากนั้นให้สร้าง lib/parse js ไฟล์เพื่อกำหนดค่าการเชื่อมต่อ ในไฟล์นี้ให้ป้อนบล็อกโค้ดด้านล่าง 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; แทนที่ your app id และ your javascript key ด้วยข้อมูลประจำตัวที่พบในแดชบอร์ด back4app ของคุณภายใต้ app settings การกำหนดค่านี้จะช่วยให้ sdk รู้วิธีเชื่อมต่อกับโปรเจกต์เฉพาะของคุณ ตอนนี้ที่คุณได้เชื่อมต่อส่วนหน้าเข้ากับส่วนหลังแล้ว คุณสามารถเริ่มเขียนฟังก์ชันเพื่อเรียกใช้ฟังก์ชันโค้ดคลาวด์ที่คุณกำหนดไว้ในแอปพลิเคชัน back4app ของคุณ การตรวจสอบสิทธิ์บนไคลเอนต์ ส่วนนี้แสดงวิธีจัดการการลงทะเบียนผู้ใช้ การเข้าสู่ระบบ และการออกจากระบบในส่วนหน้าของคุณโดยใช้ parse sdk แต่ละฟังก์ชันจะตรงกับฟังก์ชัน cloud code หรือวิธี sdk ที่คุณได้ดำเนินการในแบ็คเอนด์ back4app ของคุณ ในแอปพลิเคชันของคุณ ไดเรกทอรี app/auth/register จะเก็บตรรกะสำหรับการลงทะเบียนผู้ใช้ ใน page tsx ให้กำหนด formdata สถานะ สถานะนี้จะเก็บข้อมูลประจำตัวที่จำเป็นสำหรับการลงทะเบียนผู้ใช้ สถานะ formdata ควรมีลักษณะดังนี้ const \[formdata, setformdata] = usestate({ name "", email "", password "", confirmpassword "", shippingaddress "", paymentinfo "", }); ด้วยข้อมูลประจำตัวที่ส่งไปยัง formdata , คุณสามารถเรียกใช้ signupuser ฟังก์ชันคลาวด์ที่คุณกำหนดในแอปพลิเคชัน back4app ของคุณ ตรวจสอบให้แน่ใจว่าได้ทำการนำเข้า parse จาก 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); } } ฟังก์ชันนี้จะทำงานเมื่อคุณส่งแบบฟอร์มลงทะเบียน มันเรียกใช้ signupuser ฟังก์ชันคลาวด์ที่กำหนดใน cloud code ฟังก์ชันนี้ส่งข้อมูลประจำตัวของผู้ใช้และข้อมูลเฉพาะของผู้ซื้อ (เช่น ข้อมูลการจัดส่งและการชำระเงิน) สุดท้าย มันจะบันทึกการตอบสนองหากการดำเนินการสำเร็จหรือพิมพ์ข้อผิดพลาดหากล้มเหลว การลงชื่อเข้าใช้ผู้ใช้ ในการเข้าสู่ระบบผู้ใช้ ให้ใช้ loginuser ฟังก์ชันโค้ดคลาวด์ในแบ็กเอนด์ของคุณ ไปที่ app/auth/login ไดเรกทอรีในแอปพลิเคชันของคุณ。 ภายใน page tsx ไฟล์ v0 จะสร้างสถานะที่มีข้อมูลรับรองของผู้ใช้ที่คุณต้องการเพื่อเข้าสู่ระบบผู้ใช้ สิ่งที่คุณต้องทำคือส่งข้อมูลรับรองเหล่านั้นไปยัง loginuser ฟังก์ชัน。 ตัวอย่างเช่น 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); } }; ฟังก์ชันนี้เรียกใช้ฟังก์ชันคลาวด์ loginuser , โดยส่งข้อมูลรับรองการเข้าสู่ระบบของผู้ใช้ไปยังเซิร์ฟเวอร์ หลังจากได้รับโทเค็นเซสชันที่ถูกต้องในคำตอบ มันจะใช้ parse user become เพื่อยืนยันตัวตนของไคลเอนต์และสร้างเซสชันให้เป็นของผู้ใช้ที่เข้าสู่ระบบแล้ว。 การออกจากระบบผู้ใช้ เพื่อออกจากระบบผู้ใช้อย่างปลอดภัย คุณจะเรียกใช้ทั้ง parse user logout() และฟังก์ชัน logoutuser ของ cloud code ที่คุณกำหนดเอง สิ่งนี้จะทำให้แน่ใจว่าโทเค็นเซสชันถูกลบทั้งในไคลเอนต์และถูกทำให้ไม่ถูกต้องในเซิร์ฟเวอร์ คุณจะพบปุ่มออกจากระบบในคอมโพเนนต์ส่วนหัวของคุณ คอมโพเนนต์นี้จะอยู่ใน components โฟลเดอร์ในไดเรกทอรีหลัก ในคอมโพเนนต์ ให้กำหนดฟังก์ชันนี้ 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 }; ฟังก์ชันนี้จะออกจากระบบผู้ใช้และลบเซสชันทั้งในไคลเอนต์และเซิร์ฟเวอร์ ในส่วน jsx ของคอมโพเนนต์ ให้ผูกฟังก์ชันกับปุ่มออกจากระบบโดยใช้ onclick อีเวนต์ ตัวอย่างเช่น \<dropdownmenuitem onclick={handlelogout}> logout \</dropdownmenuitem> การเริ่มต้นผู้ขาย ส่วนนี้แสดงฟังก์ชันเพื่อให้ผู้ซื้ออัปเกรดบัญชีของตนและลงทะเบียนเป็นผู้ขาย ในแอปพลิเคชันของคุณ ให้ไปที่ app/seller/register ไดเรกทอรี ในไดเรกทอรีนี้ คุณจะพบไฟล์ page tsx ของคุณซึ่งคุณจะกำหนดฟังก์ชันที่เรียกใช้ createseller ฟังก์ชันคลาวด์ ฟังก์ชันนี้มีหน้าที่สร้างโปรไฟล์ผู้ขายสำหรับผู้ใช้ปัจจุบัน ในไฟล์ page tsx ให้ปรับเปลี่ยนสถานะ formdata ให้ดูเหมือนดังนี้ const \[formdata, setformdata] = usestate({ phone "", bio "", businessname "", }); แทนที่ตรรกะในฟังก์ชัน handlesubmit ที่สร้างโดย v0 ด้วยตรรกะด้านล่าง 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); } }; เรียกใช้ฟังก์ชันนี้เมื่อส่งแบบฟอร์มเพื่อสร้างโปรไฟล์ผู้ขายสำหรับผู้ใช้ของคุณ การจัดการผลิตภัณฑ์ ใช้การเรียกฟังก์ชันเหล่านี้ในส่วนหน้าของคุณเพื่อจัดการการดำเนินการผลิตภัณฑ์ในฐานะผู้ขาย การสร้างผลิตภัณฑ์ เพื่อเรียกใช้ฟังก์ชันโค้ดคลาวด์ที่เพิ่มผลิตภัณฑ์ลงในฐานข้อมูล ให้ค้นหา app/seller/products/new ไดเรกทอรี ในไดเรกทอรีนี้คือ page tsx ไฟล์ ซึ่งในไฟล์นี้มีแบบฟอร์ม แบบฟอร์มนี้จะรับข้อมูลสำหรับผลิตภัณฑ์รวมถึงภาพ ปรับเปลี่ยน product สถานะให้ดูเหมือนดังนี้ const \[product, setproduct] = usestate({ name "", price "", description "", stock "", status "active", }); สร้างสถานะเพื่อเก็บภาพของคุณด้วย const \[images, setimages] = usestate\<file\[]>(\[]); ตอนนี้เขียนฟังก์ชันเพื่อจัดการการเพิ่มภาพลงในฐานข้อมูล ฟังก์ชันนี้ควรมีลักษณะดังนี้ 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); } }; ผูกฟังก์ชันนี้กับการป้อนข้อมูลที่รับผิดชอบในการอัปโหลดไฟล์โดยใช้ onchange เหตุการณ์ ถัดไป ให้กำหนดฟังก์ชัน handlesubmit ฟังก์ชันนี้จะเรียกใช้ addproduct โค้ดคลาวด์ในขณะที่ส่งข้อมูลที่จำเป็น เช่นนี้ 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); } }; การเรียกนี้จะส่งข้อมูลผลิตภัณฑ์—รวมถึงภาพ—ไปยังแบ็กเอนด์เพื่อสร้างรายการใหม่ ดึงข้อมูลผลิตภัณฑ์ทั้งหมด การเรียกนี้จะดึงข้อมูลทั้งหมดสำหรับรายการผลิตภัณฑ์สาธารณะหรือฟีดหน้าแรก เพื่อสร้างฟังก์ชันที่เรียกใช้ fetchallproducts ฟังก์ชันคลาวด์ ให้ไปที่ app/products ไดเรกทอรี ใน page tsx ไฟล์ ให้เพิ่มโค้ดนี้ 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; } } บล็อกโค้ดข้างต้นกำหนดอินเตอร์เฟซสำหรับผลิตภัณฑ์และ products สถานะ ฟังก์ชัน getallproducts เรียกใช้ฟังก์ชันคลาวด์ fetchallproducts เพื่อดึงผลิตภัณฑ์ทั้งหมดจากฐานข้อมูล โปรดทราบว่าคุณต้องเรียกใช้ฟังก์ชัน getallproducts ข้างต้นภายใน useeffect() ฮุคเพื่อดึงและแสดงผลิตภัณฑ์เมื่อโหลดหน้า เช่นนี้ useeffect(() => { getallproducts() then((products) => { setproducts(products); }) catch((error) => { console error("error fetching products ", error); }); }, \[]); รับผลิตภัณฑ์เดียว การเรียกนี้จะดึงรายละเอียดทั้งหมดเกี่ยวกับผลิตภัณฑ์เฉพาะ ไปที่ \[id] โฟลเดอร์ใน app/products ไดเรกทอรีของคุณ โฟลเดอร์นี้มี page tsx ไฟล์ที่มีตรรกะสำหรับการดึงรายละเอียดของผลิตภัณฑ์เดียว ใน page tsx ไฟล์ ให้เขียนโค้ดนี้ 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); }); }, \[]); บล็อกโค้ดนี้กำหนดอินเตอร์เฟซสำหรับวัตถุผลิตภัณฑ์ ตั้งค่าตัวแปรสถานะ product ด้วยค่าดีฟอลต์ ฟังก์ชัน getsingleproduct เรียกฟังก์ชันโค้ดคลาวด์ getsingleproduct ของคุณโดยใช้ productid จากพารามิเตอร์เส้นทาง ฟังก์ชัน useeffect นี้จะทำงานครั้งเดียวเมื่อคอมโพเนนต์ถูกติดตั้ง อัปเดตผลิตภัณฑ์ เมื่อผู้ขายแก้ไขผลิตภัณฑ์ ให้เรียกใช้ฟังก์ชันนี้พร้อมกับฟิลด์ที่อัปเดตแล้ว เพื่ออัปเดตผลิตภัณฑ์ คุณต้องมีฟอร์มที่มีฟิลด์ข้อมูลเพื่อรวบรวมข้อมูลใหม่ คุณสามารถค้นหาฟอร์มนี้ได้ใน page tsx ไฟล์ที่ตั้งอยู่ใน app/seller/products/\[id]/edit ไดเรกทอรี ก่อนที่จะอัปเดตผลิตภัณฑ์ คุณต้องดึงข้อมูลผลิตภัณฑ์ และเพื่อทำเช่นนี้ให้เพิ่มโค้ดนี้ลงใน page tsx ไฟล์ 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(); }, \[]); โค้ดนี้ดึงรายละเอียดของผลิตภัณฑ์เดียวจาก back4app backend ของคุณด้วยฟังก์ชันโค้ดคลาวด์ getsingleproduct และเก็บรายละเอียดในสถานะของคอมโพเนนต์ product เพื่อแสดงเป็นค่าดีฟอลต์ในฟอร์มของคุณก่อนที่คุณจะทำการแก้ไข หลังจากดึงรายละเอียดผลิตภัณฑ์แล้ว คุณสามารถเปลี่ยนรายละเอียดโดยใช้ฟอร์ม หลังจากกรอกฟอร์ม การส่งฟอร์มจะเรียกใช้ฟังก์ชัน handlesubmit ซึ่งจะถือว่ามีตรรกะสำหรับการอัปเดตผลิตภัณฑ์ของคุณ ฟังก์ชัน handlesubmit ของคุณควรมีลักษณะดังนี้ 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); } }; ฟังก์ชันนี้เรียกใช้ฟังก์ชัน updateproduct ของ cloud code และส่งวัตถุที่มีข้อมูลผลิตภัณฑ์ที่อัปเดตแล้ว ลบผลิตภัณฑ์ ใช้ฟังก์ชันนี้เพื่อลบผลิตภัณฑ์หลังจากได้รับการยืนยันจากผู้ขาย เพื่อที่จะลบผลิตภัณฑ์ คุณต้องเพิ่มฟังก์ชัน handledelete ที่มีตรรกะที่จำเป็นสำหรับการลบผลิตภัณฑ์ คุณจะกำหนดฟังก์ชัน handledelete ในไฟล์ page tsx ในไดเรกทอรี app/seller/products/\[id]/edit 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); } }; ฟังก์ชัน handledelete จะยืนยันเจตนาของผู้ใช้ก่อนที่จะเรียกใช้ฟังก์ชัน deleteproduct ของ cloud code ที่กำหนดในแบ็กเอนด์ของคุณ ผูกฟังก์ชัน handledelete เข้ากับปุ่มลบในส่วน jsx ของคอมโพเนนต์ ตัวอย่างเช่น \<button type="button" variant="destructive" onclick={handledelete} \> \<trash2 classname="h 4 w 4 mr 2" /> delete product \</button> ดึงผลิตภัณฑ์ของผู้ขาย ใช้สิ่งนี้เพื่อดึงผลิตภัณฑ์ทั้งหมดที่เป็นของผู้ขายที่เข้าสู่ระบบในขณะนี้ คุณจะกำหนดฟังก์ชันเพื่อจัดการการดึงผลิตภัณฑ์ของผู้ขายในไฟล์ page tsx ในไดเรกทอรี app/seller/dashboard ในไฟล์นี้ให้เขียนโค้ดนี้ 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(); }, \[]); บล็อกโค้ดนี้กำหนดสถานะ products และใช้ useeffect hook เพื่อเรียกใช้ฟังก์ชัน fetchproducts หนึ่งครั้งเมื่อโหลด ฟังก์ชัน fetchproducts เรียกใช้ฟังก์ชันโค้ดคลาวด์ getsellerproducts และอัปเดตสถานะ products ด้วยผลลัพธ์จากการเรียก การจัดการตะกร้า การเรียกเหล่านี้ช่วยให้ผู้ซื้อสามารถจัดการตะกร้าสินค้าก่อนที่จะทำการสั่งซื้อ เพิ่มลงในตะกร้า การเรียกนี้จะเพิ่มผลิตภัณฑ์ที่เลือกลงในตะกร้าของผู้ใช้หรือเพิ่มจำนวนของมัน ให้ค้นหาไฟล์ page tsx ในไดเรกทอรี app/products และเพิ่มบรรทัดโค้ดต่อไปนี้ 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); } } ฟังก์ชัน handleaddtocart รับ productid และจำนวนที่เลือกเป็นอาร์กิวเมนต์ และเรียกใช้ addtocart โค้ดคลาวด์ในแบ็กเอนด์ของคุณ ฟังก์ชันนี้ควรทำงานเมื่อผู้ใช้คลิกที่ปุ่ม "เพิ่มลงในตะกร้า" ในการ์ดผลิตภัณฑ์ของคุณ ตัวอย่างเช่น \<button classname="w full" size="sm" onclick={() => handleaddtocart(product id)}> \<shoppingcart classname="h 4 w 4 mr 2" /> add to cart \</button> ดูตะกร้า ใช้สิ่งนี้เพื่อดึงเนื้อหาของตะกร้าและแสดงสรุปตะกร้าแบบสด สำหรับการทำเช่นนี้ ให้ไปที่ page tsx ไฟล์ใน app/cart ไดเรกทอรีภายในไฟล์นี้ เพิ่มบล็อกโค้ดด้านล่าง 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(); }, \[]); บล็อกโค้ดด้านบนกำหนดรูปร่างของข้อมูลตะกร้าในส่วนหน้าโดยใช้ interface cartitem , กำหนด cartitems สถานะที่เก็บรายการในตะกร้า นอกจากนี้ยังใช้ useeffect เพื่อเรียกใช้ฟังก์ชัน fetchcart หนึ่งครั้งเมื่อโหลดหน้า ฟังก์ชัน fetchcart เรียกใช้ฟังก์ชันโค้ดคลาวด์ getcart และดึงตะกร้าจากแบ็กเอนด์ของคุณ มันใช้ map เมธอดเพื่อแปลงรูปแบบแบ็กเอนด์เป็นรูปแบบส่วนหน้าก่อนที่จะบันทึกข้อมูลตะกร้าที่ประมวลผลลงใน cartitems สถานะ อัปเดตสินค้าในตะกร้า การเรียกนี้เปลี่ยนจำนวนของผลิตภัณฑ์เฉพาะในตะกร้า ภายใน page tsx ไฟล์ใน app/cart ไดเรกทอรี คุณจะพบฟังก์ชัน updatequantity แทนที่ฟังก์ชันนั้นด้วยฟังก์ชันด้านล่าง 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); } }; ฟังก์ชันนี้รับพารามิเตอร์สองตัวคือ productid และจำนวนที่อัปเดตที่ผู้ใช้ต้องการตั้งค่า newquantity มันเรียกฟังก์ชันคลาวด์ updatecart ของคุณและส่งทั้ง productid และ newquantity เป็นพารามิเตอร์ คุณผูกฟังก์ชันนี้กับปุ่ม +/ โดยใช้ onclick อีเวนต์ เช่นนี้ \<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> ลบออกจากตะกร้า ลบรายการออกจากตะกร้าโดยสิ้นเชิง เพื่อทำเช่นนี้ ให้เพิ่มบล็อกโค้ดด้านล่างลงใน page tsx ไฟล์ใน app/cart ไดเรกทอรีภายในไฟล์นี้ 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); } }; ฟังก์ชันนี้, removeitem , ลบผลิตภัณฑ์เฉพาะจากตะกร้าของผู้ใช้โดยการเรียกใช้ฟังก์ชันคลาวด์ removefromcart บนแบ็คเอนด์ ฟังก์ชันนี้ยังอัปเดตสถานะตะกร้าท้องถิ่นในฟรอนต์เอนด์เพื่อสะท้อนการเปลี่ยนแปลง ผูกฟังก์ชันนี้กับปุ่ม "ลบรายการ" ดังนี้ \<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> การจัดการคำสั่งซื้อ ฟังก์ชันเหล่านี้จัดการการสร้างและติดตามคำสั่งซื้อสำหรับผู้ซื้อและผู้ขาย สร้างคำสั่งซื้อ นี่คือการสร้างคำสั่งซื้อจากเนื้อหาปัจจุบันของตะกร้าสินค้าของผู้ใช้ คุณยังต้องกำหนดฟังก์ชันนี้ใน page tsx ไฟล์ใน app/cart ไดเรกทอรี ฟังก์ชันที่ถือว่าเป็นตรรกะในการสร้างคำสั่งซื้อต้องมีลักษณะดังนี้ 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); } }; ฟังก์ชันนี้, handleorder , จัดการกระบวนการชำระเงินโดยการวางคำสั่งซื้อผ่าน back4app backend ของคุณ มันตรวจสอบว่าผู้ใช้ล็อกอินอยู่หรือไม่ จากนั้นเรียกใช้ createorder ฟังก์ชันคลาวด์เพื่อแปลงรถเข็นของผู้ใช้ปัจจุบันให้เป็นคำสั่งซื้ออย่างเป็นทางการ เพื่อเรียกใช้สิ่งนี้ที่หน้าชำระเงิน ให้ผูกฟังก์ชันกับปุ่ม "checkout" โดยใช้ onclick เหตุการณ์ ตัวอย่างเช่น \<button classname="w full" onclick={handleorder}>proceed to checkout\</button> ดูคำสั่งซื้อของผู้ขาย ผู้ขายสามารถใช้การเรียกนี้เพื่อดูคำสั่งซื้อที่รวมผลิตภัณฑ์ของตน กำหนดฟังก์ชันนี้ใน page tsx ไฟล์ใน app/seller/dashboard ไดเรกทอรี เพิ่มบรรทัดโค้ดต่อไปนี้ใน 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); } }; โค้ดนี้ดึงรายการคำสั่งซื้อที่รวมผลิตภัณฑ์ของผู้ขายและเก็บไว้ในสถานะท้องถิ่น ordersdata เพื่อแสดงในแดชบอร์ดของผู้ขายหรือมุมมองการจัดการคำสั่งซื้อ ตรวจสอบให้แน่ใจว่าได้เรียกใช้ฟังก์ชันใน useeffect hook เพื่อให้ฟังก์ชันทำงานเพียงครั้งเดียวเมื่อโหลดหน้า อัปเดตคำสั่งซื้อ สิ่งนี้สลับสถานะของคำสั่งซื้อระหว่าง "รอดำเนินการ" และ "เสร็จสิ้น" กำหนดฟังก์ชันนี้ใน page tsx ไฟล์ใน app/seller/dashboard ไดเรกทอรี ฟังก์ชันควรมีลักษณะดังนี้ 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); } }; ฟังก์ชันนี้, handleupdate , อัปเดตสถานะของคำสั่งที่มีอยู่โดยการเรียกใช้ฟังก์ชันคลาวด์ที่ชื่อว่า completeorder บน back4app backend ของคุณ ผูกฟังก์ชันนี้กับปุ่ม "แก้ไข" ในส่วน jsx ของคอมโพเนนต์ เช่นนี้ \<button variant="ghost" size="icon" onclick={() => {handleupdate(order id)}}> \<pencil classname="h 4 w 4" /> \<span classname="sr only">view\</span> \</button> การปรับใช้ frontend บน back4app containers back4app containers เสนอวิธีการที่มีประสิทธิภาพในการบรรจุและปรับใช้แอปพลิเคชัน frontend ของคุณ แทนที่จะต้องจัดการบริการโฮสติ้งแยกต่างหาก คุณสามารถเก็บทุกความต้องการภายในภาพ docker ซึ่งช่วยให้ประสิทธิภาพสม่ำเสมอและทำให้การบำรุงรักษาง่ายขึ้น วิธีการที่ใช้คอนเทนเนอร์นี้มีประโยชน์โดยเฉพาะสำหรับแอปพลิเคชัน next js ซึ่งคุณสามารถปรับแต่งการสร้างเพื่อความเร็วและความน่าเชื่อถือ ในการทำให้แอปพลิเคชันของคุณเป็นคอนเทนเนอร์ สร้าง dockerfile เพื่อกำหนดวิธีการสร้างและให้บริการแอปของคุณ ด้านล่างนี้คือตัวอย่าง dockerfile สำหรับแอปพลิเคชัน 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"] หลังจากสร้าง dockerfile ของคุณแล้ว ให้สร้าง dockerignore ไฟล์และเพิ่มคำสั่งเหล่านี้ # 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 ตอนนี้คุณสามารถสร้างและทดสอบแอปพลิเคชันของคุณในเครื่องได้แล้ว เพื่อทำเช่นนี้ ให้รันคำสั่งต่อไปนี้ในเทอร์มินัลของคุณ docker build t ecommerce app docker run p 3000 3000 ecommerce app เปิด http //localhost 3000 เพื่อให้แน่ใจว่าเว็บไซต์ของคุณทำงานได้อย่างถูกต้อง เมื่อคุณตรวจสอบแล้วว่าทุกอย่างทำงานตามที่คาดหวังในเครื่องของคุณ ก็ถึงเวลาที่จะผลักดันโค้ดของคุณไปยัง github และปรับใช้ผ่าน back4app ตรวจสอบให้แน่ใจว่าโค้ดของคุณถูกคอมมิตและผลักดันไปยังที่เก็บ github นี่จะช่วยให้ back4app เข้าถึงโปรเจกต์ของคุณเพื่อการปรับใช้ ในบัญชี back4app ของคุณ ให้ไปที่แดชบอร์ดของคุณและคลิกที่ แดชบอร์ด เมนูแบบเลื่อนที่ด้านบนของหน้าจอ dashboard menu จากเมนูแบบเลื่อน ให้เลือก แพลตฟอร์มการปรับใช้เว็บ web deployment platform นี่จะพาคุณไปยังหน้าการปรับใช้แอปพลิเคชันเว็บ deploy web application page คลิกที่ ปรับใช้แอปเว็บ เพื่อเริ่มกระบวนการปรับใช้ link github repo จากนั้น คลิกที่ นำเข้าที่เก็บ github และเลือกที่เก็บที่มี dockerfile ของคุณ กำหนดชื่อให้กับโปรเจกต์ของคุณ (เช่น ecommerce back4app) ทำตามการตั้งค่าที่แนะนำเพื่อสร้างและปรับใช้แอปของคุณ เมื่อการปรับใช้เสร็จสิ้น back4app จะแสดงหน้าการยืนยันเช่นนี้ successful deployment พื้นที่ที่เน้นในภาพด้านบนคือ url ที่แอปพลิเคชันของคุณออนไลน์ คุณสามารถใช้เพื่อดูและทดสอบแอปของคุณโดยตรงในเว็บเบราว์เซอร์ เมื่อปรับใช้แล้ว ให้ใช้แดชบอร์ด back4app เพื่อติดตามบันทึกการสร้าง ตรวจสอบสุขภาพของคอนเทนเนอร์ และย้อนกลับไปยังเวอร์ชันก่อนหน้าเมื่อจำเป็น แดชบอร์ดจะแสดงการอัปเดตแบบเรียลไทม์เกี่ยวกับสถานะของคอนเทนเนอร์ ทำให้การตรวจจับข้อผิดพลาดและการรักษาสภาพแวดล้อมที่เสถียรสำหรับผู้ใช้ของคุณง่ายขึ้น ด้วยคอนเทนเนอร์ คุณจะได้รับโซลูชันส่วนหน้าแบบยืดหยุ่นและพกพาได้ซึ่งทำงานร่วมกับ back4app backend ของคุณได้อย่างราบรื่น เปิดทางให้การปล่อยที่สม่ำเสมอและไม่มีปัญหา คุณสามารถเยี่ยมชมเว็บไซต์ e commerce ที่สร้างขึ้นในบทช่วยสอนนี้ ที่นี่ https //ecommerceback4app mcphit37 b4a run/ บทสรุป ขอแสดงความยินดี—คุณได้ประกอบทุกชั้นของสแต็กอีคอมเมิร์ซที่ผ่านการทดสอบในสนามและพร้อมใช้งาน การตั้งค่าด้านหลัง จากการจัดเตรียมบัญชี back4app ของคุณไปจนถึงการสร้างโมเดลผู้ใช้ ผลิตภัณฑ์ และคำสั่งซื้อ ความปลอดภัย & apis การใช้การตรวจสอบสิทธิ์ที่แข็งแกร่ง และการเปิดเผยข้อมูลของคุณผ่าน rest และ graphql endpoints ตรรกะทางธุรกิจ & การอัปเดตแบบเรียลไทม์ การทำงานอัตโนมัติของเวิร์กโฟลว์ด้วย cloud code และการสตรีมการเปลี่ยนแปลงแบบสดผ่าน livequery การปรับใช้ส่วนหน้า การเชื่อมต่อกับ javascript sdk และการจัดส่งร้านค้า next js ใน back4app containers ต่อไปจะทำอย่างไร? ดำดิ่งสู่ เอกสาร back4app https //www back4app com/docs และ คู่มือ parse platform https //docs parseplatform org เพื่อการอ้างอิงเชิงลึก หรือเข้าร่วมฟอรัมชุมชนเพื่อรับเคล็ดลับขั้นสูงและแอปตัวอย่างจากผู้ดูแลและนักพัฒนาคนอื่นๆ พื้นฐานนี้เป็นเพียงจุดเริ่มต้น—ขยายมันต่อไปโดยการรวมเว็บฮุกและงานที่กำหนดเวลา เชื่อมต่อเกตเวย์การชำระเงิน หรือสร้างแอปมือถือคู่ ทำการปรับปรุง แก้ไข และพัฒนารหัสของคุณต่อไป—และดูร้านค้าของคุณเติบโตไปพร้อมกับความทะเยอทะยานของคุณ